소재지 ₍₍◝(･'ω'･)◟⁾⁾ 🐟️?给现浇结构尽快开工阿卡对对对表公
 PNG      %k25u25%fgd5n!PK     bY\_Q  Q    open-uri.rbnu [        require 'uri'
require 'stringio'
require 'time'

module Kernel
  private
  alias open_uri_original_open open # :nodoc:

  # makes possible to open various resources including URIs.
  # If the first argument respond to `open' method,
  # the method is called with the rest arguments.
  #
  # If the first argument is a string which begins with xxx://,
  # it is parsed by URI.parse.  If the parsed object respond to `open' method,
  # the method is called with the rest arguments.
  #
  # Otherwise original open is called.
  #
  # Since open-uri.rb provides URI::HTTP#open, URI::HTTPS#open and
  # URI::FTP#open,
  # Kernel[#.]open can accepts such URIs and strings which begins with
  # http://, https:// and ftp://.
  # In these case, the opened file object is extended by OpenURI::Meta.
  def open(name, *rest, &block) # :doc:
    if name.respond_to?(:open)
      name.open(*rest, &block)
    elsif name.respond_to?(:to_str) &&
          %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ name &&
          (uri = URI.parse(name)).respond_to?(:open)
      uri.open(*rest, &block)
    else
      open_uri_original_open(name, *rest, &block)
    end
  end
  module_function :open
end

# OpenURI is an easy-to-use wrapper for net/http, net/https and net/ftp.
#
#== Example
#
# It is possible to open http/https/ftp URL as usual like opening a file:
#
#   open("http://www.ruby-lang.org/") {|f|
#     f.each_line {|line| p line}
#   }
#
# The opened file has several methods for meta information as follows since
# it is extended by OpenURI::Meta.
#
#   open("http://www.ruby-lang.org/en") {|f|
#     f.each_line {|line| p line}
#     p f.base_uri         # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
#     p f.content_type     # "text/html"
#     p f.charset          # "iso-8859-1"
#     p f.content_encoding # []
#     p f.last_modified    # Thu Dec 05 02:45:02 UTC 2002
#   }
#
# Additional header fields can be specified by an optional hash argument.
#
#   open("http://www.ruby-lang.org/en/",
#     "User-Agent" => "Ruby/#{RUBY_VERSION}",
#     "From" => "foo@bar.invalid",
#     "Referer" => "http://www.ruby-lang.org/") {|f|
#     # ...
#   }
#
# The environment variables such as http_proxy, https_proxy and ftp_proxy
# are in effect by default.  :proxy => nil disables proxy.
#
#   open("http://www.ruby-lang.org/en/raa.html", :proxy => nil) {|f|
#     # ...
#   }
#
# URI objects can be opened in a similar way.
#
#   uri = URI.parse("http://www.ruby-lang.org/en/")
#   uri.open {|f|
#     # ...
#   }
#
# URI objects can be read directly. The returned string is also extended by
# OpenURI::Meta.
#
#   str = uri.read
#   p str.base_uri
#
# Author:: Tanaka Akira <akr@m17n.org>

module OpenURI
  Options = {
    :proxy => true,
    :progress_proc => true,
    :content_length_proc => true,
    :http_basic_authentication => true,
  }

  def OpenURI.check_options(options) # :nodoc:
    options.each {|k, v|
      next unless Symbol === k
      unless Options.include? k
        raise ArgumentError, "unrecognized option: #{k}"
      end
    }
  end

  def OpenURI.scan_open_optional_arguments(*rest) # :nodoc:
    if !rest.empty? && (String === rest.first || Integer === rest.first)
      mode = rest.shift
      if !rest.empty? && Integer === rest.first
        perm = rest.shift
      end
    end
    return mode, perm, rest
  end

  def OpenURI.open_uri(name, *rest) # :nodoc:
    uri = URI::Generic === name ? name : URI.parse(name)
    mode, perm, rest = OpenURI.scan_open_optional_arguments(*rest)
    options = rest.shift if !rest.empty? && Hash === rest.first
    raise ArgumentError.new("extra arguments") if !rest.empty?
    options ||= {}
    OpenURI.check_options(options)

    unless mode == nil ||
           mode == 'r' || mode == 'rb' ||
           mode == File::RDONLY
      raise ArgumentError.new("invalid access mode #{mode} (#{uri.class} resource is read only.)")
    end

    io = open_loop(uri, options)
    if block_given?
      begin
        yield io
      ensure
        io.close
      end
    else
      io
    end
  end

  def OpenURI.open_loop(uri, options) # :nodoc:
    case opt_proxy = options.fetch(:proxy, true)
    when true
      find_proxy = lambda {|u| u.find_proxy}
    when nil, false
      find_proxy = lambda {|u| nil}
    when String
      opt_proxy = URI.parse(opt_proxy)
      find_proxy = lambda {|u| opt_proxy}
    when URI::Generic
      find_proxy = lambda {|u| opt_proxy}
    else
      raise ArgumentError.new("Invalid proxy option: #{opt_proxy}")
    end

    uri_set = {}
    buf = nil
    while true
      redirect = catch(:open_uri_redirect) {
        buf = Buffer.new
        uri.buffer_open(buf, find_proxy.call(uri), options)
        nil
      }
      if redirect
        if redirect.relative?
          # Although it violates RFC2616, Location: field may have relative
          # URI.  It is converted to absolute URI using uri as a base URI.
          redirect = uri + redirect
        end
        unless OpenURI.redirectable?(uri, redirect)
          raise "redirection forbidden: #{uri} -> #{redirect}"
        end
        if options.include? :http_basic_authentication
          # send authentication only for the URI directly specified.
          options = options.dup
          options.delete :http_basic_authentication
        end
        uri = redirect
        raise "HTTP redirection loop: #{uri}" if uri_set.include? uri.to_s
        uri_set[uri.to_s] = true
      else
        break
      end
    end
    io = buf.io
    io.base_uri = uri
    io
  end

  def OpenURI.redirectable?(uri1, uri2) # :nodoc:
    # This test is intended to forbid a redirection from http://... to
    # file:///etc/passwd.
    # However this is ad hoc.  It should be extensible/configurable.
    uri1.scheme.downcase == uri2.scheme.downcase ||
    (/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
  end

  def OpenURI.open_http(buf, target, proxy, options) # :nodoc:
    if proxy
      raise "Non-HTTP proxy URI: #{proxy}" if proxy.class != URI::HTTP
    end

    if target.userinfo && "1.9.0" <= RUBY_VERSION
      # don't raise for 1.8 because compatibility.
      raise ArgumentError, "userinfo not supported.  [RFC3986]"
    end

    require 'net/http'
    klass = Net::HTTP
    if URI::HTTP === target
      # HTTP or HTTPS
      if proxy
        klass = Net::HTTP::Proxy(proxy.host, proxy.port)
      end
      target_host = target.host
      target_port = target.port
      request_uri = target.request_uri
    else
      # FTP over HTTP proxy
      target_host = proxy.host
      target_port = proxy.port
      request_uri = target.to_s
    end

    http = klass.new(target_host, target_port)
    if target.class == URI::HTTPS
      require 'net/https'
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_PEER
      store = OpenSSL::X509::Store.new
      store.set_default_paths
      http.cert_store = store
    end

    header = {}
    options.each {|k, v| header[k] = v if String === k }

    resp = nil
    http.start {
      req = Net::HTTP::Get.new(request_uri, header)
      if options.include? :http_basic_authentication
        user, pass = options[:http_basic_authentication]
        req.basic_auth user, pass
      end
      http.request(req) {|response|
        resp = response
        if options[:content_length_proc] && Net::HTTPSuccess === resp
          if resp.key?('Content-Length')
            options[:content_length_proc].call(resp['Content-Length'].to_i)
          else
            options[:content_length_proc].call(nil)
          end
        end
        resp.read_body {|str|
          buf << str
          if options[:progress_proc] && Net::HTTPSuccess === resp
            options[:progress_proc].call(buf.size)
          end
        }
      }
    }
    io = buf.io
    io.rewind
    io.status = [resp.code, resp.message]
    resp.each {|name,value| buf.io.meta_add_field name, value }
    case resp
    when Net::HTTPSuccess
    when Net::HTTPMovedPermanently, # 301
         Net::HTTPFound, # 302
         Net::HTTPSeeOther, # 303
         Net::HTTPTemporaryRedirect # 307
      throw :open_uri_redirect, URI.parse(resp['location'])
    else
      raise OpenURI::HTTPError.new(io.status.join(' '), io)
    end
  end

  class HTTPError < StandardError
    def initialize(message, io)
      super(message)
      @io = io
    end
    attr_reader :io
  end

  class Buffer # :nodoc:
    def initialize
      @io = StringIO.new
      @size = 0
    end
    attr_reader :size

    StringMax = 10240
    def <<(str)
      @io << str
      @size += str.length
      if StringIO === @io && StringMax < @size
        require 'tempfile'
        io = Tempfile.new('open-uri')
        io.binmode
        Meta.init io, @io if @io.respond_to? :meta
        io << @io.string
        @io = io
      end
    end

    def io
      Meta.init @io unless @io.respond_to? :meta
      @io
    end
  end

  # Mixin for holding meta-information.
  module Meta
    def Meta.init(obj, src=nil) # :nodoc:
      obj.extend Meta
      obj.instance_eval {
        @base_uri = nil
        @meta = {}
      }
      if src
        obj.status = src.status
        obj.base_uri = src.base_uri
        src.meta.each {|name, value|
          obj.meta_add_field(name, value)
        }
      end
    end

    # returns an Array which consists status code and message.
    attr_accessor :status

    # returns a URI which is base of relative URIs in the data.
    # It may differ from the URI supplied by a user because redirection.
    attr_accessor :base_uri

    # returns a Hash which represents header fields.
    # The Hash keys are downcased for canonicalization.
    attr_reader :meta

    def meta_add_field(name, value) # :nodoc:
      @meta[name.downcase] = value
    end

    # returns a Time which represents Last-Modified field.
    def last_modified
      if v = @meta['last-modified']
        Time.httpdate(v)
      else
        nil
      end
    end

    RE_LWS = /[\r\n\t ]+/n
    RE_TOKEN = %r{[^\x00- ()<>@,;:\\"/\[\]?={}\x7f]+}n
    RE_QUOTED_STRING = %r{"(?:[\r\n\t !#-\[\]-~\x80-\xff]|\\[\x00-\x7f])*"}n
    RE_PARAMETERS = %r{(?:;#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?=#{RE_LWS}?(?:#{RE_TOKEN}|#{RE_QUOTED_STRING})#{RE_LWS}?)*}n

    def content_type_parse # :nodoc:
      v = @meta['content-type']
      # The last (?:;#{RE_LWS}?)? matches extra ";" which violates RFC2045.
      if v && %r{\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\z}no =~ v
        type = $1.downcase
        subtype = $2.downcase
        parameters = []
        $3.scan(/;#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?=#{RE_LWS}?(?:(#{RE_TOKEN})|(#{RE_QUOTED_STRING}))/no) {|att, val, qval|
          val = qval.gsub(/[\r\n\t !#-\[\]-~\x80-\xff]+|(\\[\x00-\x7f])/) { $1 ? $1[1,1] : $& } if qval
          parameters << [att.downcase, val]
        }
        ["#{type}/#{subtype}", *parameters]
      else
        nil
      end
    end

    # returns "type/subtype" which is MIME Content-Type.
    # It is downcased for canonicalization.
    # Content-Type parameters are stripped.
    def content_type
      type, *parameters = content_type_parse
      type || 'application/octet-stream'
    end

    # returns a charset parameter in Content-Type field.
    # It is downcased for canonicalization.
    #
    # If charset parameter is not given but a block is given,
    # the block is called and its result is returned.
    # It can be used to guess charset.
    #
    # If charset parameter and block is not given,
    # nil is returned except text type in HTTP.
    # In that case, "iso-8859-1" is returned as defined by RFC2616 3.7.1.
    def charset
      type, *parameters = content_type_parse
      if pair = parameters.assoc('charset')
        pair.last.downcase
      elsif block_given?
        yield
      elsif type && %r{\Atext/} =~ type &&
            @base_uri && /\Ahttp\z/i =~ @base_uri.scheme
        "iso-8859-1" # RFC2616 3.7.1
      else
        nil
      end
    end

    # returns a list of encodings in Content-Encoding field
    # as an Array of String.
    # The encodings are downcased for canonicalization.
    def content_encoding
      v = @meta['content-encoding']
      if v && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ v
        v.scan(RE_TOKEN).map {|content_coding| content_coding.downcase}
      else
        []
      end
    end
  end

  # Mixin for HTTP and FTP URIs.
  module OpenRead
    # OpenURI::OpenRead#open provides `open' for URI::HTTP and URI::FTP.
    #
    # OpenURI::OpenRead#open takes optional 3 arguments as:
    # OpenURI::OpenRead#open([mode [, perm]] [, options]) [{|io| ... }]
    #
    # `mode', `perm' is same as Kernel#open.
    #
    # However, `mode' must be read mode because OpenURI::OpenRead#open doesn't
    # support write mode (yet).
    # Also `perm' is just ignored because it is meaningful only for file
    # creation.
    #
    # `options' must be a hash.
    #
    # Each pairs which key is a string in the hash specify a extra header
    # field for HTTP.
    # I.e. it is ignored for FTP without HTTP proxy.
    #
    # The hash may include other options which key is a symbol:
    #
    # [:proxy]
    #  Synopsis:
    #    :proxy => "http://proxy.foo.com:8000/"
    #    :proxy => URI.parse("http://proxy.foo.com:8000/")
    #    :proxy => true
    #    :proxy => false
    #    :proxy => nil
    #   
    #  If :proxy option is specified, the value should be String, URI,
    #  boolean or nil.
    #  When String or URI is given, it is treated as proxy URI.
    #  When true is given or the option itself is not specified,
    #  environment variable `scheme_proxy' is examined.
    #  `scheme' is replaced by `http', `https' or `ftp'.
    #  When false or nil is given, the environment variables are ignored and
    #  connection will be made to a server directly.
    #
    # [:http_basic_authentication]
    #  Synopsis:
    #    :http_basic_authentication=>[user, password]
    #
    #  If :http_basic_authentication is specified,
    #  the value should be an array which contains 2 strings:
    #  username and password.
    #  It is used for HTTP Basic authentication defined by RFC 2617.
    #
    # [:content_length_proc]
    #  Synopsis:
    #    :content_length_proc => lambda {|content_length| ... }
    # 
    #  If :content_length_proc option is specified, the option value procedure
    #  is called before actual transfer is started.
    #  It takes one argument which is expected content length in bytes.
    # 
    #  If two or more transfer is done by HTTP redirection, the procedure
    #  is called only one for a last transfer.
    # 
    #  When expected content length is unknown, the procedure is called with
    #  nil.
    #  It is happen when HTTP response has no Content-Length header.
    #
    # [:progress_proc]
    #  Synopsis:
    #    :progress_proc => lambda {|size| ...}
    #
    #  If :progress_proc option is specified, the proc is called with one
    #  argument each time when `open' gets content fragment from network.
    #  The argument `size' `size' is a accumulated transfered size in bytes.
    #
    #  If two or more transfer is done by HTTP redirection, the procedure
    #  is called only one for a last transfer.
    #
    #  :progress_proc and :content_length_proc are intended to be used for
    #  progress bar.
    #  For example, it can be implemented as follows using Ruby/ProgressBar.
    #
    #    pbar = nil
    #    open("http://...",
    #      :content_length_proc => lambda {|t|
    #        if t && 0 < t
    #          pbar = ProgressBar.new("...", t)
    #          pbar.file_transfer_mode
    #        end
    #      },
    #      :progress_proc => lambda {|s|
    #        pbar.set s if pbar
    #      }) {|f| ... }
    #
    # OpenURI::OpenRead#open returns an IO like object if block is not given.
    # Otherwise it yields the IO object and return the value of the block.
    # The IO object is extended with OpenURI::Meta.
    def open(*rest, &block)
      OpenURI.open_uri(self, *rest, &block)
    end

    # OpenURI::OpenRead#read([options]) reads a content referenced by self and
    # returns the content as string.
    # The string is extended with OpenURI::Meta.
    # The argument `options' is same as OpenURI::OpenRead#open.
    def read(options={})
      self.open(options) {|f|
        str = f.read
        Meta.init str, f
        str
      }
    end
  end
end

module URI
  class Generic
    # returns a proxy URI.
    # The proxy URI is obtained from environment variables such as http_proxy,
    # ftp_proxy, no_proxy, etc.
    # If there is no proper proxy, nil is returned.
    #
    # Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.)
    # are examined too.
    #
    # But http_proxy and HTTP_PROXY is treated specially under CGI environment.
    # It's because HTTP_PROXY may be set by Proxy: header.
    # So HTTP_PROXY is not used.
    # http_proxy is not used too if the variable is case insensitive.
    # CGI_HTTP_PROXY can be used instead.
    def find_proxy
      name = self.scheme.downcase + '_proxy'
      proxy_uri = nil
      if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI?
        # HTTP_PROXY conflicts with *_proxy for proxy settings and
        # HTTP_* for header information in CGI.
        # So it should be careful to use it.
        pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/i !~ k }
        case pairs.length
        when 0 # no proxy setting anyway.
          proxy_uri = nil
        when 1
          k, v = pairs.shift
          if k == 'http_proxy' && ENV[k.upcase] == nil
            # http_proxy is safe to use because ENV is case sensitive.
            proxy_uri = ENV[name]
          else
            proxy_uri = nil
          end
        else # http_proxy is safe to use because ENV is case sensitive.
          proxy_uri = ENV.to_hash[name]
        end
        if !proxy_uri
          # Use CGI_HTTP_PROXY.  cf. libwww-perl.
          proxy_uri = ENV["CGI_#{name.upcase}"]
        end
      elsif name == 'http_proxy'
        unless proxy_uri = ENV[name]
          if proxy_uri = ENV[name.upcase]
            warn 'The environment variable HTTP_PROXY is discouraged.  Use http_proxy.'
          end
        end
      else
        proxy_uri = ENV[name] || ENV[name.upcase]
      end

      if proxy_uri && self.host
        require 'socket'
        begin
          addr = IPSocket.getaddress(self.host)
          proxy_uri = nil if /\A127\.|\A::1\z/ =~ addr
        rescue SocketError
        end
      end

      if proxy_uri
        proxy_uri = URI.parse(proxy_uri)
        name = 'no_proxy'
        if no_proxy = ENV[name] || ENV[name.upcase]
          no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
            if /(\A|\.)#{Regexp.quote host}\z/i =~ self.host &&
               (!port || self.port == port.to_i)
              proxy_uri = nil
              break
            end
          }
        end
        proxy_uri
      else
        nil
      end
    end
  end

  class HTTP
    def buffer_open(buf, proxy, options) # :nodoc:
      OpenURI.open_http(buf, self, proxy, options)
    end

    include OpenURI::OpenRead
  end

  class FTP
    def buffer_open(buf, proxy, options) # :nodoc:
      if proxy
        OpenURI.open_http(buf, self, proxy, options)
        return
      end
      require 'net/ftp'

      directories = self.path.split(%r{/}, -1)
      directories.shift if directories[0] == '' # strip a field before leading slash
      directories.each {|d|
        d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
      }
      unless filename = directories.pop
        raise ArgumentError, "no filename: #{self.inspect}"
      end
      directories.each {|d|
        if /[\r\n]/ =~ d
          raise ArgumentError, "invalid directory: #{d.inspect}"
        end
      }
      if /[\r\n]/ =~ filename
        raise ArgumentError, "invalid filename: #{filename.inspect}"
      end
      typecode = self.typecode
      if typecode && /\A[aid]\z/ !~ typecode
        raise ArgumentError, "invalid typecode: #{typecode.inspect}"
      end

      # The access sequence is defined by RFC 1738
      ftp = Net::FTP.open(self.host)
      # todo: extract user/passwd from .netrc.
      user = 'anonymous'
      passwd = nil
      user, passwd = self.userinfo.split(/:/) if self.userinfo
      ftp.login(user, passwd)
      directories.each {|cwd|
        ftp.voidcmd("CWD #{cwd}")
      }
      if typecode
        # xxx: typecode D is not handled.
        ftp.voidcmd("TYPE #{typecode.upcase}")
      end
      if options[:content_length_proc]
        options[:content_length_proc].call(ftp.size(filename))
      end
      ftp.retrbinary("RETR #{filename}", 4096) { |str|
        buf << str
        options[:progress_proc].call(buf.size) if options[:progress_proc]
      }
      ftp.close
      buf.io.rewind
    end

    include OpenURI::OpenRead
  end
end
PK     dY\/+rRF  F    benchmark.rbnu [        =begin
#
# benchmark.rb - a performance benchmarking library 
# 
# $Id: benchmark.rb 15425 2008-02-10 15:24:56Z naruse $
# 
# Created by Gotoken (gotoken@notwork.org). 
#
# Documentation by Gotoken (original RD), Lyle Johnson (RDoc conversion), and
# Gavin Sinclair (editing). 
#
=end

# == Overview
#
# The Benchmark module provides methods for benchmarking Ruby code, giving
# detailed reports on the time taken for each task.
#

# The Benchmark module provides methods to measure and report the time
# used to execute Ruby code.
#
# * Measure the time to construct the string given by the expression
#   <tt>"a"*1_000_000</tt>:
#
#       require 'benchmark'
#
#       puts Benchmark.measure { "a"*1_000_000 }
# 
#   On my machine (FreeBSD 3.2 on P5, 100MHz) this generates:
# 
#       1.166667   0.050000   1.216667 (  0.571355)
# 
#   This report shows the user CPU time, system CPU time, the sum of
#   the user and system CPU times, and the elapsed real time. The unit
#   of time is seconds.
# 
# * Do some experiments sequentially using the #bm method:
#
#       require 'benchmark'
#
#       n = 50000
#       Benchmark.bm do |x|
#         x.report { for i in 1..n; a = "1"; end }
#         x.report { n.times do   ; a = "1"; end }
#         x.report { 1.upto(n) do ; a = "1"; end }
#       end
# 
#   The result:
#
#              user     system      total        real
#          1.033333   0.016667   1.016667 (  0.492106)
#          1.483333   0.000000   1.483333 (  0.694605)
#          1.516667   0.000000   1.516667 (  0.711077)
#
# * Continuing the previous example, put a label in each report:
#
#       require 'benchmark'
#
#       n = 50000
#       Benchmark.bm(7) do |x|
#         x.report("for:")   { for i in 1..n; a = "1"; end }
#         x.report("times:") { n.times do   ; a = "1"; end }
#         x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
#       end
# 
# The result:
# 
#                     user     system      total        real
#        for:     1.050000   0.000000   1.050000 (  0.503462)
#        times:   1.533333   0.016667   1.550000 (  0.735473)
#        upto:    1.500000   0.016667   1.516667 (  0.711239)
# 
#
# * The times for some benchmarks depend on the order in which items
#   are run.  These differences are due to the cost of memory
#   allocation and garbage collection. To avoid these discrepancies,
#   the #bmbm method is provided.  For example, to compare ways to
#   sort an array of floats:
#
#       require 'benchmark'
#       
#       array = (1..1000000).map { rand }
#       
#       Benchmark.bmbm do |x|
#         x.report("sort!") { array.dup.sort! }
#         x.report("sort")  { array.dup.sort  }
#       end
# 
#   The result:
# 
#        Rehearsal -----------------------------------------
#        sort!  11.928000   0.010000  11.938000 ( 12.756000)
#        sort   13.048000   0.020000  13.068000 ( 13.857000)
#        ------------------------------- total: 25.006000sec
#        
#                    user     system      total        real
#        sort!  12.959000   0.010000  12.969000 ( 13.793000)
#        sort   12.007000   0.000000  12.007000 ( 12.791000)
#
#
# * Report statistics of sequential experiments with unique labels,
#   using the #benchmark method:
#
#       require 'benchmark'
#
#       n = 50000
#       Benchmark.benchmark(" "*7 + CAPTION, 7, FMTSTR, ">total:", ">avg:") do |x|
#         tf = x.report("for:")   { for i in 1..n; a = "1"; end }
#         tt = x.report("times:") { n.times do   ; a = "1"; end }
#         tu = x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
#         [tf+tt+tu, (tf+tt+tu)/3]
#       end
# 
#   The result:
# 
#                     user     system      total        real
#        for:     1.016667   0.016667   1.033333 (  0.485749)
#        times:   1.450000   0.016667   1.466667 (  0.681367)
#        upto:    1.533333   0.000000   1.533333 (  0.722166)
#        >total:  4.000000   0.033333   4.033333 (  1.889282)
#        >avg:    1.333333   0.011111   1.344444 (  0.629761)

module Benchmark

  BENCHMARK_VERSION = "2002-04-25" #:nodoc"

  def Benchmark::times() # :nodoc:
      Process::times()
  end


  # Invokes the block with a <tt>Benchmark::Report</tt> object, which
  # may be used to collect and report on the results of individual
  # benchmark tests. Reserves <i>label_width</i> leading spaces for
  # labels on each line. Prints _caption_ at the top of the
  # report, and uses _fmt_ to format each line.
  # If the block returns an array of
  # <tt>Benchmark::Tms</tt> objects, these will be used to format
  # additional lines of output. If _label_ parameters are
  # given, these are used to label these extra lines.
  #
  # _Note_: Other methods provide a simpler interface to this one, and are
  # suitable for nearly all benchmarking requirements.  See the examples in
  # Benchmark, and the #bm and #bmbm methods.
  #
  # Example: 
  #
  #     require 'benchmark'
  #     include Benchmark          # we need the CAPTION and FMTSTR constants 
  #
  #     n = 50000
  #     Benchmark.benchmark(" "*7 + CAPTION, 7, FMTSTR, ">total:", ">avg:") do |x|
  #       tf = x.report("for:")   { for i in 1..n; a = "1"; end }
  #       tt = x.report("times:") { n.times do   ; a = "1"; end }
  #       tu = x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
  #       [tf+tt+tu, (tf+tt+tu)/3]
  #     end
  # 
  # <i>Generates:</i>
  # 
  #                     user     system      total        real
  #        for:     1.016667   0.016667   1.033333 (  0.485749)
  #        times:   1.450000   0.016667   1.466667 (  0.681367)
  #        upto:    1.533333   0.000000   1.533333 (  0.722166)
  #        >total:  4.000000   0.033333   4.033333 (  1.889282)
  #        >avg:    1.333333   0.011111   1.344444 (  0.629761)
  # 

  def benchmark(caption = "", label_width = nil, fmtstr = nil, *labels) # :yield: report
    sync = STDOUT.sync
    STDOUT.sync = true
    label_width ||= 0
    fmtstr ||= FMTSTR
    raise ArgumentError, "no block" unless iterator?
    print caption
    results = yield(Report.new(label_width, fmtstr))
    Array === results and results.grep(Tms).each {|t|
      print((labels.shift || t.label || "").ljust(label_width), 
            t.format(fmtstr))
    }
    STDOUT.sync = sync
  end


  # A simple interface to the #benchmark method, #bm is generates sequential reports
  # with labels.  The parameters have the same meaning as for #benchmark.
  # 
  #     require 'benchmark'
  #
  #     n = 50000
  #     Benchmark.bm(7) do |x|
  #       x.report("for:")   { for i in 1..n; a = "1"; end }
  #       x.report("times:") { n.times do   ; a = "1"; end }
  #       x.report("upto:")  { 1.upto(n) do ; a = "1"; end }
  #     end
  # 
  # <i>Generates:</i>
  # 
  #                     user     system      total        real
  #        for:     1.050000   0.000000   1.050000 (  0.503462)
  #        times:   1.533333   0.016667   1.550000 (  0.735473)
  #        upto:    1.500000   0.016667   1.516667 (  0.711239)
  #

  def bm(label_width = 0, *labels, &blk) # :yield: report
    benchmark(" "*label_width + CAPTION, label_width, FMTSTR, *labels, &blk)
  end


  # Sometimes benchmark results are skewed because code executed
  # earlier encounters different garbage collection overheads than
  # that run later. #bmbm attempts to minimize this effect by running
  # the tests twice, the first time as a rehearsal in order to get the
  # runtime environment stable, the second time for
  # real. <tt>GC.start</tt> is executed before the start of each of
  # the real timings; the cost of this is not included in the
  # timings. In reality, though, there's only so much that #bmbm can
  # do, and the results are not guaranteed to be isolated from garbage
  # collection and other effects.
  #
  # Because #bmbm takes two passes through the tests, it can
  # calculate the required label width.
  #
  #       require 'benchmark'
  #       
  #       array = (1..1000000).map { rand }
  #       
  #       Benchmark.bmbm do |x|
  #         x.report("sort!") { array.dup.sort! }
  #         x.report("sort")  { array.dup.sort  }
  #       end
  # 
  # <i>Generates:</i>
  # 
  #        Rehearsal -----------------------------------------
  #        sort!  11.928000   0.010000  11.938000 ( 12.756000)
  #        sort   13.048000   0.020000  13.068000 ( 13.857000)
  #        ------------------------------- total: 25.006000sec
  #        
  #                    user     system      total        real
  #        sort!  12.959000   0.010000  12.969000 ( 13.793000)
  #        sort   12.007000   0.000000  12.007000 ( 12.791000)
  #
  # #bmbm yields a Benchmark::Job object and returns an array of
  # Benchmark::Tms objects.
  #
  def bmbm(width = 0, &blk) # :yield: job
    job = Job.new(width)
    yield(job)
    width = job.width
    sync = STDOUT.sync
    STDOUT.sync = true

    # rehearsal
    print "Rehearsal "
    puts '-'*(width+CAPTION.length - "Rehearsal ".length)
    list = []
    job.list.each{|label,item|
      print(label.ljust(width))
      res = Benchmark::measure(&item)
      print res.format()
      list.push res
    }
    sum = Tms.new; list.each{|i| sum += i}
    ets = sum.format("total: %tsec")
    printf("%s %s\n\n",
           "-"*(width+CAPTION.length-ets.length-1), ets)
    
    # take
    print ' '*width, CAPTION
    list = []
    ary = []
    job.list.each{|label,item|
      GC::start
      print label.ljust(width)
      res = Benchmark::measure(&item)
      print res.format()
      ary.push res
      list.push [label, res]
    }

    STDOUT.sync = sync
    ary
  end

  # 
  # Returns the time used to execute the given block as a
  # Benchmark::Tms object.
  #
  def measure(label = "") # :yield:
    t0, r0 = Benchmark.times, Time.now
    yield
    t1, r1 = Benchmark.times, Time.now
    Benchmark::Tms.new(t1.utime  - t0.utime, 
                       t1.stime  - t0.stime, 
                       t1.cutime - t0.cutime, 
                       t1.cstime - t0.cstime, 
                       r1.to_f - r0.to_f,
                       label)
  end

  #
  # Returns the elapsed real time used to execute the given block.
  #
  def realtime(&blk) # :yield:
    r0 = Time.now
    yield
    r1 = Time.now
    r1.to_f - r0.to_f
  end



  #
  # A Job is a sequence of labelled blocks to be processed by the
  # Benchmark.bmbm method.  It is of little direct interest to the user.
  #
  class Job # :nodoc:
    #
    # Returns an initialized Job instance.
    # Usually, one doesn't call this method directly, as new
    # Job objects are created by the #bmbm method.
    # _width_ is a initial value for the label offset used in formatting;
    # the #bmbm method passes its _width_ argument to this constructor. 
    # 
    def initialize(width)
      @width = width
      @list = []
    end

    #
    # Registers the given label and block pair in the job list.
    #
    def item(label = "", &blk) # :yield:
      raise ArgumentError, "no block" unless block_given?
      label += ' '
      w = label.length
      @width = w if @width < w
      @list.push [label, blk]
      self
    end

    alias report item
    
    # An array of 2-element arrays, consisting of label and block pairs.
    attr_reader :list
    
    # Length of the widest label in the #list, plus one.  
    attr_reader :width
  end

  module_function :benchmark, :measure, :realtime, :bm, :bmbm



  #
  # This class is used by the Benchmark.benchmark and Benchmark.bm methods.
  # It is of little direct interest to the user.
  #
  class Report # :nodoc:
    #
    # Returns an initialized Report instance.
    # Usually, one doesn't call this method directly, as new
    # Report objects are created by the #benchmark and #bm methods. 
    # _width_ and _fmtstr_ are the label offset and 
    # format string used by Tms#format. 
    # 
    def initialize(width = 0, fmtstr = nil)
      @width, @fmtstr = width, fmtstr
    end

    #
    # Prints the _label_ and measured time for the block,
    # formatted by _fmt_. See Tms#format for the
    # formatting rules.
    #
    def item(label = "", *fmt, &blk) # :yield:
      print label.ljust(@width)
      res = Benchmark::measure(&blk)
      print res.format(@fmtstr, *fmt)
      res
    end

    alias report item
  end



  #
  # A data object, representing the times associated with a benchmark
  # measurement.
  #
  class Tms
    CAPTION = "      user     system      total        real\n"
    FMTSTR = "%10.6u %10.6y %10.6t %10.6r\n"

    # User CPU time
    attr_reader :utime
    
    # System CPU time
    attr_reader :stime
   
    # User CPU time of children
    attr_reader :cutime
    
    # System CPU time of children
    attr_reader :cstime
    
    # Elapsed real time
    attr_reader :real
    
    # Total time, that is _utime_ + _stime_ + _cutime_ + _cstime_ 
    attr_reader :total
    
    # Label
    attr_reader :label

    #
    # Returns an initialized Tms object which has
    # _u_ as the user CPU time, _s_ as the system CPU time, 
    # _cu_ as the children's user CPU time, _cs_ as the children's
    # system CPU time, _real_ as the elapsed real time and _l_
    # as the label. 
    # 
    def initialize(u = 0.0, s = 0.0, cu = 0.0, cs = 0.0, real = 0.0, l = nil)
      @utime, @stime, @cutime, @cstime, @real, @label = u, s, cu, cs, real, l
      @total = @utime + @stime + @cutime + @cstime
    end

    # 
    # Returns a new Tms object whose times are the sum of the times for this
    # Tms object, plus the time required to execute the code block (_blk_).
    # 
    def add(&blk) # :yield:
      self + Benchmark::measure(&blk) 
    end

    # 
    # An in-place version of #add.
    # 
    def add!
      t = Benchmark::measure(&blk) 
      @utime  = utime + t.utime
      @stime  = stime + t.stime
      @cutime = cutime + t.cutime
      @cstime = cstime + t.cstime
      @real   = real + t.real
      self
    end

    # 
    # Returns a new Tms object obtained by memberwise summation
    # of the individual times for this Tms object with those of the other
    # Tms object.
    # This method and #/() are useful for taking statistics. 
    # 
    def +(other); memberwise(:+, other) end
    
    #
    # Returns a new Tms object obtained by memberwise subtraction
    # of the individual times for the other Tms object from those of this
    # Tms object.
    #
    def -(other); memberwise(:-, other) end
    
    #
    # Returns a new Tms object obtained by memberwise multiplication
    # of the individual times for this Tms object by _x_.
    #
    def *(x); memberwise(:*, x) end

    # 
    # Returns a new Tms object obtained by memberwise division
    # of the individual times for this Tms object by _x_.
    # This method and #+() are useful for taking statistics. 
    # 
    def /(x); memberwise(:/, x) end

    #
    # Returns the contents of this Tms object as
    # a formatted string, according to a format string
    # like that passed to Kernel.format. In addition, #format
    # accepts the following extensions:
    #
    # <tt>%u</tt>::     Replaced by the user CPU time, as reported by Tms#utime.
    # <tt>%y</tt>::     Replaced by the system CPU time, as reported by #stime (Mnemonic: y of "s*y*stem")
    # <tt>%U</tt>::     Replaced by the children's user CPU time, as reported by Tms#cutime 
    # <tt>%Y</tt>::     Replaced by the children's system CPU time, as reported by Tms#cstime
    # <tt>%t</tt>::     Replaced by the total CPU time, as reported by Tms#total
    # <tt>%r</tt>::     Replaced by the elapsed real time, as reported by Tms#real
    # <tt>%n</tt>::     Replaced by the label string, as reported by Tms#label (Mnemonic: n of "*n*ame")
    # 
    # If _fmtstr_ is not given, FMTSTR is used as default value, detailing the
    # user, system and real elapsed time.
    # 
    def format(arg0 = nil, *args)
      fmtstr = (arg0 || FMTSTR).dup
      fmtstr.gsub!(/(%[-+\.\d]*)n/){"#{$1}s" % label}
      fmtstr.gsub!(/(%[-+\.\d]*)u/){"#{$1}f" % utime}
      fmtstr.gsub!(/(%[-+\.\d]*)y/){"#{$1}f" % stime}
      fmtstr.gsub!(/(%[-+\.\d]*)U/){"#{$1}f" % cutime}
      fmtstr.gsub!(/(%[-+\.\d]*)Y/){"#{$1}f" % cstime}
      fmtstr.gsub!(/(%[-+\.\d]*)t/){"#{$1}f" % total}
      fmtstr.gsub!(/(%[-+\.\d]*)r/){"(#{$1}f)" % real}
      arg0 ? Kernel::format(fmtstr, *args) : fmtstr
    end

    # 
    # Same as #format.
    # 
    def to_s
      format
    end

    # 
    # Returns a new 6-element array, consisting of the
    # label, user CPU time, system CPU time, children's
    # user CPU time, children's system CPU time and elapsed
    # real time.
    # 
    def to_a
      [@label, @utime, @stime, @cutime, @cstime, @real]
    end

    protected
    def memberwise(op, x)
      case x
      when Benchmark::Tms
        Benchmark::Tms.new(utime.__send__(op, x.utime),
                           stime.__send__(op, x.stime),
                           cutime.__send__(op, x.cutime),
                           cstime.__send__(op, x.cstime),
                           real.__send__(op, x.real)
                           )
      else
        Benchmark::Tms.new(utime.__send__(op, x),
                           stime.__send__(op, x),
                           cutime.__send__(op, x),
                           cstime.__send__(op, x),
                           real.__send__(op, x)
                           )
      end
    end
  end

  # The default caption string (heading above the output times).
  CAPTION = Benchmark::Tms::CAPTION

  # The default format string used to display times.  See also Benchmark::Tms#format. 
  FMTSTR = Benchmark::Tms::FMTSTR
end

if __FILE__ == $0
  include Benchmark

  n = ARGV[0].to_i.nonzero? || 50000
  puts %Q([#{n} times iterations of `a = "1"'])
  benchmark("       " + CAPTION, 7, FMTSTR) do |x|
    x.report("for:")   {for i in 1..n; a = "1"; end} # Benchmark::measure
    x.report("times:") {n.times do   ; a = "1"; end}
    x.report("upto:")  {1.upto(n) do ; a = "1"; end}
  end

  benchmark do
    [
      measure{for i in 1..n; a = "1"; end},  # Benchmark::measure
      measure{n.times do   ; a = "1"; end},
      measure{1.upto(n) do ; a = "1"; end}
    ]
  end
end
PK     dY\}ޢf   f     generator.rbnu [        #!/usr/bin/env ruby
#--
# $Idaemons: /home/cvs/rb/generator.rb,v 1.8 2001/10/03 08:54:32 knu Exp $
# $RoughId: generator.rb,v 1.10 2003/10/14 19:36:58 knu Exp $
# $Id: generator.rb 15954 2008-04-10 10:52:50Z knu $
#++
#
# = generator.rb: convert an internal iterator to an external one
#
# Copyright (c) 2001,2003 Akinori MUSHA <knu@iDaemons.org>
#
# All rights reserved.  You can redistribute and/or modify it under
# the same terms as Ruby.
#
# == Overview
#
# This library provides the Generator class, which converts an
# internal iterator (i.e. an Enumerable object) to an external
# iterator.  In that form, you can roll many iterators independently.
#
# The SyncEnumerator class, which is implemented using Generator,
# makes it easy to roll many Enumerable objects synchronously.
#
# See the respective classes for examples of usage.


#
# Generator converts an internal iterator (i.e. an Enumerable object)
# to an external iterator.
#
# Note that it is not very fast since it is implemented using
# continuations, which are currently slow.
#
# == Example
#
#   require 'generator'
#
#   # Generator from an Enumerable object
#   g = Generator.new(['A', 'B', 'C', 'Z'])
#
#   while g.next?
#     puts g.next
#   end
#
#   # Generator from a block
#   g = Generator.new { |g|
#     for i in 'A'..'C'
#       g.yield i
#     end
#
#     g.yield 'Z'
#   }
#
#   # The same result as above
#   while g.next?
#     puts g.next
#   end
#   
class Generator
  include Enumerable

  # Creates a new generator either from an Enumerable object or from a
  # block.
  #
  # In the former, block is ignored even if given.
  #
  # In the latter, the given block is called with the generator
  # itself, and expected to call the +yield+ method for each element.
  def initialize(enum = nil, &block)
    if enum
      @block = proc { |g|
	enum.each { |x| g.yield x }
      }
    else
      @block = block
    end

    @index = 0
    @queue = []
    @cont_next = @cont_yield = @cont_endp = nil

    if @cont_next = callcc { |c| c }
      @block.call(self)

      @cont_endp.call(nil) if @cont_endp
    end

    self
  end

  # Yields an element to the generator.
  def yield(value)
    if @cont_yield = callcc { |c| c }
      @queue << value
      @cont_next.call(nil)
    end

    self
  end

  # Returns true if the generator has reached the end.
  def end?()
    if @cont_endp = callcc { |c| c }
      @cont_yield.nil? && @queue.empty?
    else
      @queue.empty?
    end
  end

  # Returns true if the generator has not reached the end yet.
  def next?()
    !end?
  end

  # Returns the current index (position) counting from zero.
  def index()
    @index
  end

  # Returns the current index (position) counting from zero.
  def pos()
    @index
  end

  # Returns the element at the current position and moves forward.
  def next()
    if end?
      raise EOFError, "no more elements available"
    end

    if @cont_next = callcc { |c| c }
      @cont_yield.call(nil) if @cont_yield
    end

    @index += 1

    @queue.shift
  end

  # Returns the element at the current position.
  def current()
    if @queue.empty?
      raise EOFError, "no more elements available"
    end

    @queue.first
  end

  # Rewinds the generator.
  def rewind()
    initialize(nil, &@block) if @index.nonzero?

    self
  end

  # Rewinds the generator and enumerates the elements.
  def each
    rewind

    until end?
      yield self.next
    end

    self
  end
end

class Enumerable::Enumerator
  def __generator
    @generator ||= Generator.new(self)
  end
  private :__generator

  # call-seq:
  #   e.next   => object
  #
  # Returns the next object in the enumerator, and move the internal
  # position forward.  When the position reached at the end, internal
  # position is rewinded then StopIteration is raised.
  #
  # Note that enumeration sequence by next method does not affect other
  # non-external enumeration methods, unless underlying iteration
  # methods itself has side-effect, e.g. IO#each_line.
  #
  # Caution: This feature internally uses Generator, which uses callcc
  # to stop and resume enumeration to fetch each value.  Use with care
  # and be aware of the performance loss.
  def next
    g = __generator
    return g.next unless g.end?

    g.rewind
    raise StopIteration, 'iteration reached at end' 
  end

  # call-seq:
  #   e.rewind   => e
  #
  # Rewinds the enumeration sequence by the next method.
  def rewind
    __generator.rewind
    self
  end
end

#
# SyncEnumerator creates an Enumerable object from multiple Enumerable
# objects and enumerates them synchronously.
#
# == Example
#
#   require 'generator'
#
#   s = SyncEnumerator.new([1,2,3], ['a', 'b', 'c'])
#
#   # Yields [1, 'a'], [2, 'b'], and [3,'c']
#   s.each { |row| puts row.join(', ') }
#
class SyncEnumerator
  include Enumerable

  # Creates a new SyncEnumerator which enumerates rows of given
  # Enumerable objects.
  def initialize(*enums)
    @gens = enums.map { |e| Generator.new(e) }
  end

  # Returns the number of enumerated Enumerable objects, i.e. the size
  # of each row.
  def size
    @gens.size
  end

  # Returns the number of enumerated Enumerable objects, i.e. the size
  # of each row.
  def length
    @gens.length
  end

  # Returns true if the given nth Enumerable object has reached the
  # end.  If no argument is given, returns true if any of the
  # Enumerable objects has reached the end.
  def end?(i = nil)
    if i.nil?
      @gens.detect { |g| g.end? } ? true : false
    else
      @gens[i].end?
    end
  end

  # Enumerates rows of the Enumerable objects.
  def each
    @gens.each { |g| g.rewind }

    loop do
      count = 0

      ret = @gens.map { |g|
	if g.end?
	  count += 1
	  nil
	else
	  g.next
	end
      }

      if count == @gens.size
	break
      end

      yield ret
    end

    self
  end
end

if $0 == __FILE__
  eval DATA.read, nil, $0, __LINE__+4
end

__END__

require 'test/unit'

class TC_Generator < Test::Unit::TestCase
  def test_block1
    g = Generator.new { |g|
      # no yield's
    }

    assert_equal(0, g.pos)
    assert_raises(EOFError) { g.current }
  end

  def test_block2
    g = Generator.new { |g|
      for i in 'A'..'C'
        g.yield i
      end

      g.yield 'Z'
    }

    assert_equal(0, g.pos)
    assert_equal('A', g.current)

    assert_equal(true, g.next?)
    assert_equal(0, g.pos)
    assert_equal('A', g.current)
    assert_equal(0, g.pos)
    assert_equal('A', g.next)

    assert_equal(1, g.pos)
    assert_equal(true, g.next?)
    assert_equal(1, g.pos)
    assert_equal('B', g.current)
    assert_equal(1, g.pos)
    assert_equal('B', g.next)

    assert_equal(g, g.rewind)

    assert_equal(0, g.pos)
    assert_equal('A', g.current)

    assert_equal(true, g.next?)
    assert_equal(0, g.pos)
    assert_equal('A', g.current)
    assert_equal(0, g.pos)
    assert_equal('A', g.next)

    assert_equal(1, g.pos)
    assert_equal(true, g.next?)
    assert_equal(1, g.pos)
    assert_equal('B', g.current)
    assert_equal(1, g.pos)
    assert_equal('B', g.next)

    assert_equal(2, g.pos)
    assert_equal(true, g.next?)
    assert_equal(2, g.pos)
    assert_equal('C', g.current)
    assert_equal(2, g.pos)
    assert_equal('C', g.next)

    assert_equal(3, g.pos)
    assert_equal(true, g.next?)
    assert_equal(3, g.pos)
    assert_equal('Z', g.current)
    assert_equal(3, g.pos)
    assert_equal('Z', g.next)

    assert_equal(4, g.pos)
    assert_equal(false, g.next?)
    assert_raises(EOFError) { g.next }
  end

  def test_each
    a = [5, 6, 7, 8, 9]

    g = Generator.new(a)

    i = 0

    g.each { |x|
      assert_equal(a[i], x)

      i += 1

      break if i == 3
    }

    assert_equal(3, i)

    i = 0

    g.each { |x|
      assert_equal(a[i], x)

      i += 1
    }

    assert_equal(5, i)
  end
end

class TC_SyncEnumerator < Test::Unit::TestCase
  def test_each
    r = ['a'..'f', 1..10, 10..20]
    ra = r.map { |x| x.to_a }

    a = (0...(ra.map {|x| x.size}.max)).map { |i| ra.map { |x| x[i] } }

    s = SyncEnumerator.new(*r)

    i = 0

    s.each { |x|
      assert_equal(a[i], x)

      i += 1

      break if i == 3
    }

    assert_equal(3, i)

    i = 0

    s.each { |x|
      assert_equal(a[i], x)

      i += 1
    }

    assert_equal(a.size, i)
  end
end
PK     eY\v%&  &  	  e2mmap.rbnu [        #
#   e2mmap.rb - for ruby 1.1
#   	$Release Version: 2.0$
#   	$Revision: 1.10 $
#   	$Date: 1999/02/17 12:33:17 $
#   	by Keiju ISHITSUKA
#
# --
#   Usage:
#
# U1)
#   class Foo
#     extend Exception2MessageMapper
#     def_e2message ExistingExceptionClass, "message..."
#     def_exception :NewExceptionClass, "message..."[, superclass]
#     ...
#   end
#
# U2)
#   module Error
#     extend Exception2MessageMapper
#     def_e2meggage ExistingExceptionClass, "message..."
#     def_exception :NewExceptionClass, "message..."[, superclass]
#     ...
#   end
#   class Foo
#     include Error
#     ...
#   end
#
#   foo = Foo.new
#   foo.Fail ....
#
# U3)
#   module Error
#     extend Exception2MessageMapper
#     def_e2message ExistingExceptionClass, "message..."
#     def_exception :NewExceptionClass, "message..."[, superclass]
#     ...
#   end
#   class Foo
#     extend Exception2MessageMapper
#     include Error
#     ...
#   end
#
#   Foo.Fail NewExceptionClass, arg...
#   Foo.Fail ExistingExceptionClass, arg...
#
#
fail "Use Ruby 1.1" if VERSION < "1.1"

module Exception2MessageMapper
  @RCS_ID='-$Id: e2mmap.rb,v 1.10 1999/02/17 12:33:17 keiju Exp keiju $-'

  E2MM = Exception2MessageMapper

  def E2MM.extend_object(cl)
    super
    cl.bind(self) unless cl == E2MM
  end
  
  # backward compatibility
  def E2MM.extend_to(b)
    c = eval("self", b)
    c.extend(self)
  end

  def bind(cl)
    self.module_eval %[
      def Raise(err = nil, *rest)
	Exception2MessageMapper.Raise(self.class, err, *rest)
      end
      alias Fail Raise

      def self.included(mod)
	mod.extend Exception2MessageMapper
      end
    ]
  end

  # Fail(err, *rest)
  #	err:	exception
  #	rest:	message arguments
  #
  def Raise(err = nil, *rest)
    E2MM.Raise(self, err, *rest)
  end
  alias Fail Raise

  # backward compatibility
  alias fail! fail
  def fail(err = nil, *rest)
    begin 
      E2MM.Fail(self, err, *rest)
    rescue E2MM::ErrNotRegisteredException
      super
    end
  end
  class << self
    public :fail
  end

  
  # def_e2message(c, m)
  #	    c:  exception
  #	    m:  message_form
  #	define exception c with message m.
  #
  def def_e2message(c, m)
    E2MM.def_e2message(self, c, m)
  end
  
  # def_exception(n, m, s)
  #	    n:  exception_name
  #	    m:  message_form
  #	    s:	superclass(default: StandardError)
  #	define exception named ``c'' with message m.
  #
  def def_exception(n, m, s = StandardError)
    E2MM.def_exception(self, n, m, s)
  end

  #
  # Private definitions.
  #
  # {[class, exp] => message, ...}
  @MessageMap = {}

  # E2MM.def_exception(k, e, m)
  #	    k:  class to define exception under.
  #	    e:  exception
  #	    m:  message_form
  #	define exception c with message m.
  #
  def E2MM.def_e2message(k, c, m)
    E2MM.instance_eval{@MessageMap[[k, c]] = m}
    c
  end
  
  # E2MM.def_exception(k, n, m, s)
  #	    k:  class to define exception under.
  #	    n:  exception_name
  #	    m:  message_form
  #	    s:	superclass(default: StandardError)
  #	define exception named ``c'' with message m.
  #
  def E2MM.def_exception(k, n, m, s = StandardError)
    n = n.id2name if n.kind_of?(Fixnum)
    e = Class.new(s)
    E2MM.instance_eval{@MessageMap[[k, e]] = m}
    k.const_set(n, e)
  end

  # Fail(klass, err, *rest)
  #	klass:  class to define exception under.
  #	err:	exception
  #	rest:	message arguments
  #
  def E2MM.Raise(klass = E2MM, err = nil, *rest)
    if form = e2mm_message(klass, err)
      $! = err.new(sprintf(form, *rest))
      $@ = caller(1) if $@.nil?
      #p $@
      #p __FILE__
      $@.shift if $@[0] =~ /^#{Regexp.quote(__FILE__)}:/
      raise
    else
      E2MM.Fail E2MM, ErrNotRegisteredException, err.inspect
    end
  end
  class <<E2MM
    alias Fail Raise
  end

  def E2MM.e2mm_message(klass, exp)
    for c in klass.ancestors
      if mes = @MessageMap[[c,exp]]
	#p mes
	m = klass.instance_eval('"' + mes + '"')
	return m
      end
    end
    nil
  end
  class <<self
    alias message e2mm_message
  end

  E2MM.def_exception(E2MM, 
		     :ErrNotRegisteredException, 
		     "not registerd exception(%s)")
end


PK     eY\^f%+  +  
  webrick.rbnu [        #
# WEBrick -- WEB server toolkit.
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: webrick.rb,v 1.12 2002/10/01 17:16:31 gotoyuzo Exp $

require 'webrick/compat.rb'

require 'webrick/version.rb'
require 'webrick/config.rb'
require 'webrick/log.rb'
require 'webrick/server.rb'
require 'webrick/utils.rb'
require 'webrick/accesslog'

require 'webrick/htmlutils.rb'
require 'webrick/httputils.rb'
require 'webrick/cookie.rb'
require 'webrick/httpversion.rb'
require 'webrick/httpstatus.rb'
require 'webrick/httprequest.rb'
require 'webrick/httpresponse.rb'
require 'webrick/httpserver.rb'
require 'webrick/httpservlet.rb'
require 'webrick/httpauth.rb'
PK     eY\f*=l  l  	  matrix.rbnu [        #!/usr/local/bin/ruby
#--
#   matrix.rb - 
#       $Release Version: 1.0$
#       $Revision: 1.11 $
#       $Date: 1999/10/06 11:01:53 $
#       Original Version from Smalltalk-80 version
#          on July 23, 1985 at 8:37:17 am
#       by Keiju ISHITSUKA
#++
#
# = matrix.rb
#
# An implementation of Matrix and Vector classes.
#
# Author:: Keiju ISHITSUKA
# Documentation:: Gavin Sinclair (sourced from <i>Ruby in a Nutshell</i> (Matsumoto, O'Reilly)) 
#
# See classes Matrix and Vector for documentation. 
#


require "e2mmap.rb"

module ExceptionForMatrix # :nodoc:
  extend Exception2MessageMapper
  def_e2message(TypeError, "wrong argument type %s (expected %s)")
  def_e2message(ArgumentError, "Wrong # of arguments(%d for %d)")
  
  def_exception("ErrDimensionMismatch", "\#{self.name} dimension mismatch")
  def_exception("ErrNotRegular", "Not Regular Matrix")
  def_exception("ErrOperationNotDefined", "This operation(%s) can\\'t defined")
end

#
# The +Matrix+ class represents a mathematical matrix, and provides methods for creating
# special-case matrices (zero, identity, diagonal, singular, vector), operating on them
# arithmetically and algebraically, and determining their mathematical properties (trace, rank,
# inverse, determinant).
#
# Note that although matrices should theoretically be rectangular, this is not
# enforced by the class.
#
# Also note that the determinant of integer matrices may be incorrectly calculated unless you
# also <tt>require 'mathn'</tt>.  This may be fixed in the future.
#
# == Method Catalogue
#
# To create a matrix:
# * <tt> Matrix[*rows]                  </tt>
# * <tt> Matrix.[](*rows)               </tt>
# * <tt> Matrix.rows(rows, copy = true) </tt>
# * <tt> Matrix.columns(columns)        </tt>
# * <tt> Matrix.diagonal(*values)       </tt>
# * <tt> Matrix.scalar(n, value)        </tt>
# * <tt> Matrix.scalar(n, value)        </tt>
# * <tt> Matrix.identity(n)             </tt>
# * <tt> Matrix.unit(n)                 </tt>
# * <tt> Matrix.I(n)                    </tt>
# * <tt> Matrix.zero(n)                 </tt>
# * <tt> Matrix.row_vector(row)         </tt>
# * <tt> Matrix.column_vector(column)   </tt>
#
# To access Matrix elements/columns/rows/submatrices/properties: 
# * <tt>  [](i, j)                      </tt>
# * <tt> #row_size                      </tt>
# * <tt> #column_size                   </tt>
# * <tt> #row(i)                        </tt>
# * <tt> #column(j)                     </tt>
# * <tt> #collect                       </tt>
# * <tt> #map                           </tt>
# * <tt> #minor(*param)                 </tt>
#
# Properties of a matrix:
# * <tt> #regular?                      </tt>
# * <tt> #singular?                     </tt>
# * <tt> #square?                       </tt>
#
# Matrix arithmetic:
# * <tt>  *(m)                          </tt>
# * <tt>  +(m)                          </tt>
# * <tt>  -(m)                          </tt>
# * <tt> #/(m)                          </tt>
# * <tt> #inverse                       </tt>
# * <tt> #inv                           </tt>
# * <tt>  **                            </tt>
#
# Matrix functions:
# * <tt> #determinant                   </tt>
# * <tt> #det                           </tt>
# * <tt> #rank                          </tt>
# * <tt> #trace                         </tt>
# * <tt> #tr                            </tt>
# * <tt> #transpose                     </tt>
# * <tt> #t                             </tt>
#
# Conversion to other data types:
# * <tt> #coerce(other)                 </tt>
# * <tt> #row_vectors                   </tt>
# * <tt> #column_vectors                </tt>
# * <tt> #to_a                          </tt>
#
# String representations:
# * <tt> #to_s                          </tt>
# * <tt> #inspect                       </tt>
#
class Matrix
  @RCS_ID='-$Id: matrix.rb,v 1.11 1999/10/06 11:01:53 keiju Exp keiju $-'
  
#  extend Exception2MessageMapper
  include ExceptionForMatrix
  
  # instance creations
  private_class_method :new
  
  #
  # Creates a matrix where each argument is a row.
  #   Matrix[ [25, 93], [-1, 66] ]
  #      =>  25 93
  #          -1 66
  #
  def Matrix.[](*rows)
    new(:init_rows, rows, false)
  end
  
  #
  # Creates a matrix where +rows+ is an array of arrays, each of which is a row
  # to the matrix.  If the optional argument +copy+ is false, use the given
  # arrays as the internal structure of the matrix without copying.
  #   Matrix.rows([[25, 93], [-1, 66]])
  #      =>  25 93
  #          -1 66
  def Matrix.rows(rows, copy = true)
    new(:init_rows, rows, copy)
  end
  
  #
  # Creates a matrix using +columns+ as an array of column vectors.
  #   Matrix.columns([[25, 93], [-1, 66]])
  #      =>  25 -1
  #          93 66
  #
  #
  def Matrix.columns(columns)
    rows = (0 .. columns[0].size - 1).collect {
      |i|
      (0 .. columns.size - 1).collect {
        |j|
        columns[j][i]
      }
    }
    Matrix.rows(rows, false)
  end
  
  #
  # Creates a matrix where the diagonal elements are composed of +values+.
  #   Matrix.diagonal(9, 5, -3)
  #     =>  9  0  0
  #         0  5  0
  #         0  0 -3
  #
  def Matrix.diagonal(*values)
    size = values.size
    rows = (0 .. size  - 1).collect {
      |j|
      row = Array.new(size).fill(0, 0, size)
      row[j] = values[j]
      row
    }
    rows(rows, false)
  end
  
  #
  # Creates an +n+ by +n+ diagonal matrix where each diagonal element is
  # +value+.
  #   Matrix.scalar(2, 5)
  #     => 5 0
  #        0 5
  #
  def Matrix.scalar(n, value)
    Matrix.diagonal(*Array.new(n).fill(value, 0, n))
  end

  #
  # Creates an +n+ by +n+ identity matrix.
  #   Matrix.identity(2)
  #     => 1 0
  #        0 1
  #
  def Matrix.identity(n)
    Matrix.scalar(n, 1)
  end
  class << Matrix 
    alias unit identity
    alias I identity
  end
  
  #
  # Creates an +n+ by +n+ zero matrix.
  #   Matrix.zero(2)
  #     => 0 0
  #        0 0
  #
  def Matrix.zero(n)
    Matrix.scalar(n, 0)
  end
  
  #
  # Creates a single-row matrix where the values of that row are as given in
  # +row+.
  #   Matrix.row_vector([4,5,6])
  #     => 4 5 6
  #
  def Matrix.row_vector(row)
    case row
    when Vector
      Matrix.rows([row.to_a], false)
    when Array
      Matrix.rows([row.dup], false)
    else
      Matrix.rows([[row]], false)
    end
  end
  
  #
  # Creates a single-column matrix where the values of that column are as given
  # in +column+.
  #   Matrix.column_vector([4,5,6])
  #     => 4
  #        5
  #        6
  #
  def Matrix.column_vector(column)
    case column
    when Vector
      Matrix.columns([column.to_a])
    when Array
      Matrix.columns([column])
    else
      Matrix.columns([[column]])
    end
  end

  #
  # This method is used by the other methods that create matrices, and is of no
  # use to general users.
  #
  def initialize(init_method, *argv)
    self.send(init_method, *argv)
  end
  
  def init_rows(rows, copy)
    if copy
      @rows = rows.collect{|row| row.dup}
    else
      @rows = rows
    end
    self
  end
  private :init_rows
  
  #
  # Returns element (+i+,+j+) of the matrix.  That is: row +i+, column +j+.
  #
  def [](i, j)
    @rows[i][j]
  end

  #
  # Returns the number of rows.
  #
  def row_size
    @rows.size
  end
  
  #
  # Returns the number of columns.  Note that it is possible to construct a
  # matrix with uneven columns (e.g. Matrix[ [1,2,3], [4,5] ]), but this is
  # mathematically unsound.  This method uses the first row to determine the
  # result.
  #
  def column_size
    @rows[0].size
  end

  #
  # Returns row vector number +i+ of the matrix as a Vector (starting at 0 like
  # an array).  When a block is given, the elements of that vector are iterated.
  #
  def row(i) # :yield: e
    if block_given?
      for e in @rows[i]
        yield e
      end
    else
      Vector.elements(@rows[i])
    end
  end

  #
  # Returns column vector number +j+ of the matrix as a Vector (starting at 0
  # like an array).  When a block is given, the elements of that vector are
  # iterated.
  #
  def column(j) # :yield: e
    if block_given?
      0.upto(row_size - 1) do
        |i|
        yield @rows[i][j]
      end
    else
      col = (0 .. row_size - 1).collect {
        |i|
        @rows[i][j]
      }
      Vector.elements(col, false)
    end
  end
  
  #
  # Returns a matrix that is the result of iteration of the given block over all
  # elements of the matrix.
  #   Matrix[ [1,2], [3,4] ].collect { |i| i**2 }
  #     => 1  4
  #        9 16
  #
  def collect # :yield: e
    rows = @rows.collect{|row| row.collect{|e| yield e}}
    Matrix.rows(rows, false)
  end
  alias map collect
  
  #
  # Returns a section of the matrix.  The parameters are either:
  # *  start_row, nrows, start_col, ncols; OR
  # *  col_range, row_range
  #
  #   Matrix.diagonal(9, 5, -3).minor(0..1, 0..2)
  #     => 9 0 0
  #        0 5 0
  #
  def minor(*param)
    case param.size
    when 2
      from_row = param[0].first
      size_row = param[0].end - from_row
      size_row += 1 unless param[0].exclude_end?
      from_col = param[1].first
      size_col = param[1].end - from_col
      size_col += 1 unless param[1].exclude_end?
    when 4
      from_row = param[0]
      size_row = param[1]
      from_col = param[2]
      size_col = param[3]
    else
      Matrix.Raise ArgumentError, param.inspect
    end
    
    rows = @rows[from_row, size_row].collect{
      |row|
      row[from_col, size_col]
    }
    Matrix.rows(rows, false)
  end
 
  #--
  # TESTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  #++

  #
  # Returns +true+ if this is a regular matrix.
  #
  def regular?
    square? and rank == column_size
  end
  
  #
  # Returns +true+ is this is a singular (i.e. non-regular) matrix.
  #
  def singular?
    not regular?
  end

  #
  # Returns +true+ is this is a square matrix.  See note in column_size about this
  # being unreliable, though.
  #
  def square?
    column_size == row_size
  end
  
  #--
  # OBJECT METHODS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  #++

  #
  # Returns +true+ if and only if the two matrices contain equal elements.
  #
  def ==(other)
    return false unless Matrix === other
    
    other.compare_by_row_vectors(@rows)
  end
  alias eql? ==
  
  #
  # Not really intended for general consumption.
  #
  def compare_by_row_vectors(rows)
    return false unless @rows.size == rows.size
    
    0.upto(@rows.size - 1) do
      |i|
      return false unless @rows[i] == rows[i]
    end
    true
  end
  
  #
  # Returns a clone of the matrix, so that the contents of each do not reference
  # identical objects.
  #
  def clone
    Matrix.rows(@rows)
  end
  
  #
  # Returns a hash-code for the matrix.
  #
  def hash
    value = 0
    for row in @rows
      for e in row
        value ^= e.hash
      end
    end
    return value
  end
  
  #--
  # ARITHMETIC -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  #++
  
  #
  # Matrix multiplication.
  #   Matrix[[2,4], [6,8]] * Matrix.identity(2)
  #     => 2 4
  #        6 8
  #
  def *(m) # m is matrix or vector or number
    case(m)
    when Numeric
      rows = @rows.collect {
        |row|
        row.collect {
          |e|
          e * m
        }
      }
      return Matrix.rows(rows, false)
    when Vector
      m = Matrix.column_vector(m)
      r = self * m
      return r.column(0)
    when Matrix
      Matrix.Raise ErrDimensionMismatch if column_size != m.row_size
    
      rows = (0 .. row_size - 1).collect {
        |i|
        (0 .. m.column_size - 1).collect {
          |j|
          vij = 0
          0.upto(column_size - 1) do
            |k|
            vij += self[i, k] * m[k, j]
          end
          vij
        }
      }
      return Matrix.rows(rows, false)
    else
      x, y = m.coerce(self)
      return x * y
    end
  end
  
  #
  # Matrix addition.
  #   Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]]
  #     =>  6  0
  #        -4 12
  #
  def +(m)
    case m
    when Numeric
      Matrix.Raise ErrOperationNotDefined, "+"
    when Vector
      m = Matrix.column_vector(m)
    when Matrix
    else
      x, y = m.coerce(self)
      return x + y
    end
    
    Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
    
    rows = (0 .. row_size - 1).collect {
      |i|
      (0 .. column_size - 1).collect {
        |j|
        self[i, j] + m[i, j]
      }
    }
    Matrix.rows(rows, false)
  end

  #
  # Matrix subtraction.
  #   Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]]
  #     => -8  2
  #         8  1
  #
  def -(m)
    case m
    when Numeric
      Matrix.Raise ErrOperationNotDefined, "-"
    when Vector
      m = Matrix.column_vector(m)
    when Matrix
    else
      x, y = m.coerce(self)
      return x - y
    end
    
    Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
    
    rows = (0 .. row_size - 1).collect {
      |i|
      (0 .. column_size - 1).collect {
        |j|
        self[i, j] - m[i, j]
      }
    }
    Matrix.rows(rows, false)
  end
  
  #
  # Matrix division (multiplication by the inverse).
  #   Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]]
  #     => -7  1
  #        -3 -6
  #
  def /(other)
    case other
    when Numeric
      rows = @rows.collect {
        |row|
        row.collect {
          |e|
          e / other
        }
      }
      return Matrix.rows(rows, false)
    when Matrix
      return self * other.inverse
    else
      x, y = other.coerce(self)
      rerurn x / y
    end
  end

  #
  # Returns the inverse of the matrix.
  #   Matrix[[1, 2], [2, 1]].inverse
  #     => -1  1
  #         0 -1
  #
  def inverse
    Matrix.Raise ErrDimensionMismatch unless square?
    Matrix.I(row_size).inverse_from(self)
  end
  alias inv inverse

  #
  # Not for public consumption?
  #
  def inverse_from(src)
    size = row_size - 1
    a = src.to_a
    
    for k in 0..size
      i = k
      akk = a[k][k].abs
      for j in (k+1)..size
        v = a[j][k].abs
        if v > akk
          i = j
          akk = v
        end
      end
      Matrix.Raise ErrNotRegular if akk == 0
      if i != k
        a[i], a[k] = a[k], a[i]
        @rows[i], @rows[k] = @rows[k], @rows[i]
      end
      akk = a[k][k]
      
      for i in 0 .. size
        next if i == k
        q = a[i][k] / akk
        a[i][k] = 0
        
        (k + 1).upto(size) do   
          |j|
          a[i][j] -= a[k][j] * q
        end
        0.upto(size) do
          |j|
          @rows[i][j] -= @rows[k][j] * q
        end
      end
      
      (k + 1).upto(size) do
        |j|
        a[k][j] /= akk
      end
      0.upto(size) do
        |j|
        @rows[k][j] /= akk
      end
    end
    self
  end
  #alias reciprocal inverse
  
  #
  # Matrix exponentiation.  Defined for integer powers only.  Equivalent to
  # multiplying the matrix by itself N times.
  #   Matrix[[7,6], [3,9]] ** 2
  #     => 67 96
  #        48 99
  #
  def ** (other)
    if other.kind_of?(Integer)
      x = self
      if other <= 0
        x = self.inverse
        return Matrix.identity(self.column_size) if other == 0
        other = -other
      end
      z = x
      n = other  - 1
      while n != 0
        while (div, mod = n.divmod(2)
               mod == 0)
          x = x * x
          n = div
        end
        z *= x
        n -= 1
      end
      z
    elsif other.kind_of?(Float) || defined?(Rational) && other.kind_of?(Rational)
      Matrix.Raise ErrOperationNotDefined, "**"
    else
      Matrix.Raise ErrOperationNotDefined, "**"
    end
  end
  
  #--
  # MATRIX FUNCTIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  #++
  
  #
  # Returns the determinant of the matrix.  If the matrix is not square, the
  # result is 0.
  #   Matrix[[7,6], [3,9]].determinant
  #     => 63
  #
  def determinant
    return 0 unless square?
    
    size = row_size - 1
    a = to_a
    
    det = 1
    k = 0
    begin 
      if (akk = a[k][k]) == 0
        i = k
        begin
          return 0 if (i += 1) > size
        end while a[i][k] == 0
        a[i], a[k] = a[k], a[i]
        akk = a[k][k]
        det *= -1
      end
      (k + 1).upto(size) do
        |i|
        q = a[i][k] / akk
        (k + 1).upto(size) do
          |j|
          a[i][j] -= a[k][j] * q
        end
      end
      det *= akk
    end while (k += 1) <= size
    det
  end
  alias det determinant
        
  #
  # Returns the rank of the matrix.  Beware that using Float values, with their
  # usual lack of precision, can affect the value returned by this method.  Use
  # Rational values instead if this is important to you.
  #   Matrix[[7,6], [3,9]].rank
  #     => 2
  #
  def rank
    if column_size > row_size
      a = transpose.to_a
      a_column_size = row_size
      a_row_size = column_size
    else
      a = to_a
      a_column_size = column_size
      a_row_size = row_size
    end
    rank = 0
    k = 0
    begin
      if (akk = a[k][k]) == 0
        i = k
        exists = true
        begin
          if (i += 1) > a_column_size - 1
            exists = false
            break
          end
        end while a[i][k] == 0
        if exists
          a[i], a[k] = a[k], a[i]
          akk = a[k][k]
        else
          i = k
          exists = true
          begin
            if (i += 1) > a_row_size - 1
              exists = false
              break
            end
          end while a[k][i] == 0
          if exists
            k.upto(a_column_size - 1) do
              |j|
              a[j][k], a[j][i] = a[j][i], a[j][k]
            end
            akk = a[k][k]
          else
            next
          end
        end
      end
      (k + 1).upto(a_row_size - 1) do
        |i|
        q = a[i][k] / akk
        (k + 1).upto(a_column_size - 1) do
          |j|
          a[i][j] -= a[k][j] * q
        end
      end
      rank += 1
    end while (k += 1) <= a_column_size - 1
    return rank
  end

  #
  # Returns the trace (sum of diagonal elements) of the matrix.
  #   Matrix[[7,6], [3,9]].trace
  #     => 16
  #
  def trace
    tr = 0
    0.upto(column_size - 1) do
      |i|
      tr += @rows[i][i]
    end
    tr
  end
  alias tr trace
  
  #
  # Returns the transpose of the matrix.
  #   Matrix[[1,2], [3,4], [5,6]]
  #     => 1 2
  #        3 4
  #        5 6
  #   Matrix[[1,2], [3,4], [5,6]].transpose
  #     => 1 3 5
  #        2 4 6
  #
  def transpose
    Matrix.columns(@rows)
  end
  alias t transpose
  
  #--
  # CONVERTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  #++
  
  #
  # FIXME: describe #coerce.
  #
  def coerce(other)
    case other
    when Numeric
      return Scalar.new(other), self
    else
      raise TypeError, "#{self.class} can't be coerced into #{other.class}"
    end
  end

  #
  # Returns an array of the row vectors of the matrix.  See Vector.
  #
  def row_vectors
    rows = (0 .. row_size - 1).collect {
      |i|
      row(i)
    }
    rows
  end
  
  #
  # Returns an array of the column vectors of the matrix.  See Vector.
  #
  def column_vectors
    columns = (0 .. column_size - 1).collect {
      |i|
      column(i)
    }
    columns
  end
  
  #
  # Returns an array of arrays that describe the rows of the matrix.
  #
  def to_a
    @rows.collect{|row| row.collect{|e| e}}
  end
  
  #--
  # PRINTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  #++
  
  #
  # Overrides Object#to_s
  #
  def to_s
    "Matrix[" + @rows.collect{
      |row|
      "[" + row.collect{|e| e.to_s}.join(", ") + "]"
    }.join(", ")+"]"
  end
  
  #
  # Overrides Object#inspect
  #
  def inspect
    "Matrix"+@rows.inspect
  end
  
  # Private CLASS
  
  class Scalar < Numeric # :nodoc:
    include ExceptionForMatrix
    
    def initialize(value)
      @value = value
    end
    
    # ARITHMETIC
    def +(other)
      case other
      when Numeric
        Scalar.new(@value + other)
      when Vector, Matrix
        Scalar.Raise WrongArgType, other.class, "Numeric or Scalar"
      when Scalar
        Scalar.new(@value + other.value)
      else
        x, y = other.coerce(self)
        x + y
      end
    end
    
    def -(other)
      case other
      when Numeric
        Scalar.new(@value - other)
      when Vector, Matrix
        Scalar.Raise WrongArgType, other.class, "Numeric or Scalar"
      when Scalar
        Scalar.new(@value - other.value)
      else
        x, y = other.coerce(self)
        x - y
      end
    end
    
    def *(other)
      case other
      when Numeric
        Scalar.new(@value * other)
      when Vector, Matrix
        other.collect{|e| @value * e}
      else
        x, y = other.coerce(self)
        x * y
      end
    end
    
    def / (other)
      case other
      when Numeric
        Scalar.new(@value / other)
      when Vector
        Scalar.Raise WrongArgType, other.class, "Numeric or Scalar or Matrix"
      when Matrix
        self * _M.inverse
      else
        x, y = other.coerce(self)
        x / y
      end
    end
    
    def ** (other)
      case other
      when Numeric
        Scalar.new(@value ** other)
      when Vector
        Scalar.Raise WrongArgType, other.class, "Numeric or Scalar or Matrix"
      when Matrix
        other.powered_by(self)
      else
        x, y = other.coerce(self)
        x ** y
      end
    end
  end
end


#
# The +Vector+ class represents a mathematical vector, which is useful in its own right, and
# also constitutes a row or column of a Matrix.
#
# == Method Catalogue
#
# To create a Vector:
# * <tt>  Vector.[](*array)                   </tt>
# * <tt>  Vector.elements(array, copy = true) </tt>
#
# To access elements:
# * <tt>  [](i)                               </tt>
#
# To enumerate the elements:
# * <tt> #each2(v)                            </tt>
# * <tt> #collect2(v)                         </tt>
#
# Vector arithmetic:
# * <tt>  *(x) "is matrix or number"          </tt>
# * <tt>  +(v)                                </tt>
# * <tt>  -(v)                                </tt>
#
# Vector functions:
# * <tt> #inner_product(v)                    </tt>
# * <tt> #collect                             </tt>
# * <tt> #map                                 </tt>
# * <tt> #map2(v)                             </tt>
# * <tt> #r                                   </tt>
# * <tt> #size                                </tt>
#
# Conversion to other data types:
# * <tt> #covector                            </tt>
# * <tt> #to_a                                </tt>
# * <tt> #coerce(other)                       </tt>
#
# String representations:
# * <tt> #to_s                                </tt>
# * <tt> #inspect                             </tt>
#
class Vector
  include ExceptionForMatrix
  
  #INSTANCE CREATION
  
  private_class_method :new

  #
  # Creates a Vector from a list of elements.
  #   Vector[7, 4, ...]
  #
  def Vector.[](*array)
    new(:init_elements, array, copy = false)
  end
  
  #
  # Creates a vector from an Array.  The optional second argument specifies
  # whether the array itself or a copy is used internally.
  #
  def Vector.elements(array, copy = true)
    new(:init_elements, array, copy)
  end
  
  #
  # For internal use.
  #
  def initialize(method, array, copy)
    self.send(method, array, copy)
  end
  
  #
  # For internal use.
  #
  def init_elements(array, copy)
    if copy
      @elements = array.dup
    else
      @elements = array
    end
  end
  
  # ACCESSING
         
  #
  # Returns element number +i+ (starting at zero) of the vector.
  #
  def [](i)
    @elements[i]
  end
  
  #
  # Returns the number of elements in the vector.
  #
  def size
    @elements.size
  end
  
  #--
  # ENUMERATIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  #++

  #
  # Iterate over the elements of this vector and +v+ in conjunction.
  #
  def each2(v) # :yield: e1, e2
    Vector.Raise ErrDimensionMismatch if size != v.size
    0.upto(size - 1) do
      |i|
      yield @elements[i], v[i]
    end
  end
  
  #
  # Collects (as in Enumerable#collect) over the elements of this vector and +v+
  # in conjunction.
  #
  def collect2(v) # :yield: e1, e2
    Vector.Raise ErrDimensionMismatch if size != v.size
    (0 .. size - 1).collect do
      |i|
      yield @elements[i], v[i]
    end
  end

  #--
  # COMPARING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  #++

  #
  # Returns +true+ iff the two vectors have the same elements in the same order.
  #
  def ==(other)
    return false unless Vector === other
    
    other.compare_by(@elements)
  end
  alias eql? ==
  
  #
  # For internal use.
  #
  def compare_by(elements)
    @elements == elements
  end
  
  #
  # Return a copy of the vector.
  #
  def clone
    Vector.elements(@elements)
  end
  
  #
  # Return a hash-code for the vector.
  #
  def hash
    @elements.hash
  end
  
  #--
  # ARITHMETIC -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  #++
  
  #
  # Multiplies the vector by +x+, where +x+ is a number or another vector.
  #
  def *(x)
    case x
    when Numeric
      els = @elements.collect{|e| e * x}
      Vector.elements(els, false)
    when Matrix
      Matrix.column_vector(self) * x
    else
      s, x = x.coerce(self)
      s * x
    end
  end

  #
  # Vector addition.
  #
  def +(v)
    case v
    when Vector
      Vector.Raise ErrDimensionMismatch if size != v.size
      els = collect2(v) {
        |v1, v2|
        v1 + v2
      }
      Vector.elements(els, false)
    when Matrix
      Matrix.column_vector(self) + v
    else
      s, x = v.coerce(self)
      s + x
    end
  end

  #
  # Vector subtraction.
  #
  def -(v)
    case v
    when Vector
      Vector.Raise ErrDimensionMismatch if size != v.size
      els = collect2(v) {
        |v1, v2|
        v1 - v2
      }
      Vector.elements(els, false)
    when Matrix
      Matrix.column_vector(self) - v
    else
      s, x = v.coerce(self)
      s - x
    end
  end
  
  #--
  # VECTOR FUNCTIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  #++
  
  #
  # Returns the inner product of this vector with the other.
  #   Vector[4,7].inner_product Vector[10,1]  => 47
  #
  def inner_product(v)
    Vector.Raise ErrDimensionMismatch if size != v.size
    
    p = 0
    each2(v) {
      |v1, v2|
      p += v1 * v2
    }
    p
  end
  
  #
  # Like Array#collect.
  #
  def collect # :yield: e
    els = @elements.collect {
      |v|
      yield v
    }
    Vector.elements(els, false)
  end
  alias map collect
  
  #
  # Like Vector#collect2, but returns a Vector instead of an Array.
  #
  def map2(v) # :yield: e1, e2
    els = collect2(v) {
      |v1, v2|
      yield v1, v2
    }
    Vector.elements(els, false)
  end
  
  #
  # Returns the modulus (Pythagorean distance) of the vector.
  #   Vector[5,8,2].r => 9.643650761
  #
  def r
    v = 0
    for e in @elements
      v += e*e
    end
    return Math.sqrt(v)
  end
  
  #--
  # CONVERTING
  #++

  #
  # Creates a single-row matrix from this vector.
  #
  def covector
    Matrix.row_vector(self)
  end
  
  #
  # Returns the elements of the vector in an array.
  #
  def to_a
    @elements.dup
  end
  
  #
  # FIXME: describe Vector#coerce.
  #
  def coerce(other)
    case other
    when Numeric
      return Scalar.new(other), self
    else
      raise TypeError, "#{self.class} can't be coerced into #{other.class}"
    end
  end
  
  #--
  # PRINTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  #++
  
  #
  # Overrides Object#to_s
  #
  def to_s
    "Vector[" + @elements.join(", ") + "]"
  end
  
  #
  # Overrides Object#inspect
  #
  def inspect
    str = "Vector"+@elements.inspect
  end
end


# Documentation comments:
#  - Matrix#coerce and Vector#coerce need to be documented
PK     fY\buM'  '    webrick/httprequest.rbnu [        #
# httprequest.rb -- HTTPRequest Class
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: httprequest.rb,v 1.64 2003/07/13 17:18:22 gotoyuzo Exp $

require 'timeout'
require 'uri'

require 'webrick/httpversion'
require 'webrick/httpstatus'
require 'webrick/httputils'
require 'webrick/cookie'

module WEBrick

  class HTTPRequest
    BODY_CONTAINABLE_METHODS = [ "POST", "PUT" ]
    BUFSIZE = 1024*4

    # Request line
    attr_reader :request_line
    attr_reader :request_method, :unparsed_uri, :http_version

    # Request-URI
    attr_reader :request_uri, :host, :port, :path
    attr_accessor :script_name, :path_info, :query_string

    # Header and entity body
    attr_reader :raw_header, :header, :cookies
    attr_reader :accept, :accept_charset
    attr_reader :accept_encoding, :accept_language

    # Misc
    attr_accessor :user
    attr_reader :addr, :peeraddr
    attr_reader :attributes
    attr_reader :keep_alive
    attr_reader :request_time

    def initialize(config)
      @config = config
      @logger = config[:Logger]

      @request_line = @request_method =
        @unparsed_uri = @http_version = nil

      @request_uri = @host = @port = @path = nil
      @script_name = @path_info = nil
      @query_string = nil
      @query = nil
      @form_data = nil

      @raw_header = Array.new
      @header = nil
      @cookies = []
      @accept = []
      @accept_charset = []
      @accept_encoding = []
      @accept_language = []
      @body = ""

      @addr = @peeraddr = nil
      @attributes = {}
      @user = nil
      @keep_alive = false
      @request_time = nil

      @remaining_size = nil
      @socket = nil
    end

    def parse(socket=nil)
      @socket = socket
      begin
        @peeraddr = socket.respond_to?(:peeraddr) ? socket.peeraddr : []
        @addr = socket.respond_to?(:addr) ? socket.addr : []
      rescue Errno::ENOTCONN
        raise HTTPStatus::EOFError
      end

      read_request_line(socket)
      if @http_version.major > 0
        read_header(socket)
        @header['cookie'].each{|cookie|
          @cookies += Cookie::parse(cookie)
        }
        @accept = HTTPUtils.parse_qvalues(self['accept'])
        @accept_charset = HTTPUtils.parse_qvalues(self['accept-charset'])
        @accept_encoding = HTTPUtils.parse_qvalues(self['accept-encoding'])
        @accept_language = HTTPUtils.parse_qvalues(self['accept-language'])
      end
      return if @request_method == "CONNECT"
      return if @unparsed_uri == "*"

      begin
        @request_uri = parse_uri(@unparsed_uri)
        @path = HTTPUtils::unescape(@request_uri.path)
        @path = HTTPUtils::normalize_path(@path)
        @host = @request_uri.host
        @port = @request_uri.port
        @query_string = @request_uri.query
        @script_name = ""
        @path_info = @path.dup
      rescue
        raise HTTPStatus::BadRequest, "bad URI `#{@unparsed_uri}'."
      end

      if /close/io =~ self["connection"]
        @keep_alive = false
      elsif /keep-alive/io =~ self["connection"]
        @keep_alive = true
      elsif @http_version < "1.1"
        @keep_alive = false
      else
        @keep_alive = true
      end
    end

    def body(&block)
      block ||= Proc.new{|chunk| @body << chunk }
      read_body(@socket, block)
      @body.empty? ? nil : @body
    end

    def query
      unless @query
        parse_query()
      end
      @query
    end

    def content_length
      return Integer(self['content-length'])
    end

    def content_type
      return self['content-type']
    end

    def [](header_name)
      if @header
        value = @header[header_name.downcase]
        value.empty? ? nil : value.join(", ")
      end
    end

    def each
      @header.each{|k, v|
        value = @header[k]
        yield(k, value.empty? ? nil : value.join(", "))
      }
    end

    def keep_alive?
      @keep_alive
    end

    def to_s
      ret = @request_line.dup
      @raw_header.each{|line| ret << line }
      ret << CRLF
      ret << body if body
      ret
    end

    def fixup()
      begin
        body{|chunk| }   # read remaining body
      rescue HTTPStatus::Error => ex
        @logger.error("HTTPRequest#fixup: #{ex.class} occured.")
        @keep_alive = false
      rescue => ex
        @logger.error(ex)
        @keep_alive = false
      end
    end

    def meta_vars
      # This method provides the metavariables defined by the revision 3
      # of ``The WWW Common Gateway Interface Version 1.1''.
      # (http://Web.Golux.Com/coar/cgi/)

      meta = Hash.new

      cl = self["Content-Length"]
      ct = self["Content-Type"]
      meta["CONTENT_LENGTH"]    = cl if cl.to_i > 0
      meta["CONTENT_TYPE"]      = ct.dup if ct
      meta["GATEWAY_INTERFACE"] = "CGI/1.1"
      meta["PATH_INFO"]         = @path_info ? @path_info.dup : ""
     #meta["PATH_TRANSLATED"]   = nil      # no plan to be provided
      meta["QUERY_STRING"]      = @query_string ? @query_string.dup : ""
      meta["REMOTE_ADDR"]       = @peeraddr[3]
      meta["REMOTE_HOST"]       = @peeraddr[2]
     #meta["REMOTE_IDENT"]      = nil      # no plan to be provided
      meta["REMOTE_USER"]       = @user
      meta["REQUEST_METHOD"]    = @request_method.dup
      meta["REQUEST_URI"]       = @request_uri.to_s
      meta["SCRIPT_NAME"]       = @script_name.dup
      meta["SERVER_NAME"]       = @host
      meta["SERVER_PORT"]       = @port.to_s
      meta["SERVER_PROTOCOL"]   = "HTTP/" + @config[:HTTPVersion].to_s
      meta["SERVER_SOFTWARE"]   = @config[:ServerSoftware].dup

      self.each{|key, val|
        next if /^content-type$/i =~ key
        next if /^content-length$/i =~ key
        name = "HTTP_" + key
        name.gsub!(/-/o, "_")
        name.upcase!
        meta[name] = val
      }

      meta
    end

    private

    def read_request_line(socket)
      @request_line = read_line(socket) if socket
      @request_time = Time.now
      raise HTTPStatus::EOFError unless @request_line
      if /^(\S+)\s+(\S+?)(?:\s+HTTP\/(\d+\.\d+))?\r?\n/mo =~ @request_line
        @request_method = $1
        @unparsed_uri   = $2
        @http_version   = HTTPVersion.new($3 ? $3 : "0.9")
      else
        rl = @request_line.sub(/\x0d?\x0a\z/o, '')
        raise HTTPStatus::BadRequest, "bad Request-Line `#{rl}'."
      end
    end

    def read_header(socket)
      if socket
        while line = read_line(socket)
          break if /\A(#{CRLF}|#{LF})\z/om =~ line
          @raw_header << line
        end
      end
      @header = HTTPUtils::parse_header(@raw_header.join)
    end

    def parse_uri(str, scheme="http")
      if @config[:Escape8bitURI]
        str = HTTPUtils::escape8bit(str)
      end
      str.sub!(%r{\A/+}o, '/')
      uri = URI::parse(str)
      return uri if uri.absolute?
      if self["host"]
        pattern = /\A(#{URI::REGEXP::PATTERN::HOST})(?::(\d+))?\z/n
        host, port = *self['host'].scan(pattern)[0]
      elsif @addr.size > 0
        host, port = @addr[2], @addr[1]
      else
        host, port = @config[:ServerName], @config[:Port]
      end
      uri.scheme = scheme
      uri.host = host
      uri.port = port ? port.to_i : nil
      return URI::parse(uri.to_s)
    end

    def read_body(socket, block)
      return unless socket
      if tc = self['transfer-encoding']
        case tc
        when /chunked/io then read_chunked(socket, block)
        else raise HTTPStatus::NotImplemented, "Transfer-Encoding: #{tc}."
        end
      elsif self['content-length'] || @remaining_size
        @remaining_size ||= self['content-length'].to_i
        while @remaining_size > 0 
          sz = BUFSIZE < @remaining_size ? BUFSIZE : @remaining_size
          break unless buf = read_data(socket, sz)
          @remaining_size -= buf.size
          block.call(buf)
        end
        if @remaining_size > 0 && @socket.eof?
          raise HTTPStatus::BadRequest, "invalid body size."
        end
      elsif BODY_CONTAINABLE_METHODS.member?(@request_method)
        raise HTTPStatus::LengthRequired
      end
      return @body
    end

    def read_chunk_size(socket)
      line = read_line(socket)
      if /^([0-9a-fA-F]+)(?:;(\S+))?/ =~ line
        chunk_size = $1.hex
        chunk_ext = $2
        [ chunk_size, chunk_ext ]
      else
        raise HTTPStatus::BadRequest, "bad chunk `#{line}'."
      end
    end

    def read_chunked(socket, block)
      chunk_size, = read_chunk_size(socket)
      while chunk_size > 0
        data = ""
        while data.size < chunk_size
          tmp = read_data(socket, chunk_size-data.size) # read chunk-data
          break unless tmp
          data << tmp
        end
        if data.nil? || data.size != chunk_size
          raise BadRequest, "bad chunk data size."
        end
        read_line(socket)                    # skip CRLF
        block.call(data)
        chunk_size, = read_chunk_size(socket)
      end
      read_header(socket)                    # trailer + CRLF
      @header.delete("transfer-encoding")
      @remaining_size = 0
    end

    def _read_data(io, method, arg)
      begin
        timeout(@config[:RequestTimeout]){
          return io.__send__(method, arg)
        }
      rescue Errno::ECONNRESET
        return nil
      rescue TimeoutError
        raise HTTPStatus::RequestTimeout
      end
    end

    def read_line(io)
      _read_data(io, :gets, LF)
    end

    def read_data(io, size)
      _read_data(io, :read, size)
    end

    def parse_query()
      begin
        if @request_method == "GET" || @request_method == "HEAD"
          @query = HTTPUtils::parse_query(@query_string)
        elsif self['content-type'] =~ /^application\/x-www-form-urlencoded/
          @query = HTTPUtils::parse_query(body)
        elsif self['content-type'] =~ /^multipart\/form-data; boundary=(.+)/
          boundary = HTTPUtils::dequote($1)
          @query = HTTPUtils::parse_form_data(body, boundary)
        else
          @query = Hash.new
        end
      rescue => ex
        raise HTTPStatus::BadRequest, ex.message
      end
    end
  end
end
PK     hY\{L
  
    webrick/httpstatus.rbnu [        #
# httpstatus.rb -- HTTPStatus Class
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: httpstatus.rb,v 1.11 2003/03/24 20:18:55 gotoyuzo Exp $

module WEBrick

  module HTTPStatus

    class Status      < StandardError
      def initialize(*args)
        args[0] = AccessLog.escape(args[0]) unless args.empty?
        super(*args)
      end
      class << self
        attr_reader :code, :reason_phrase
      end
      def code() self::class::code end
      def reason_phrase() self::class::reason_phrase end
      alias to_i code
    end
    class Info        < Status; end
    class Success     < Status; end
    class Redirect    < Status; end
    class Error       < Status; end
    class ClientError < Error; end
    class ServerError < Error; end
    
    class EOFError < StandardError; end

    StatusMessage = {
      100, 'Continue',
      101, 'Switching Protocols',
      200, 'OK',
      201, 'Created',
      202, 'Accepted',
      203, 'Non-Authoritative Information',
      204, 'No Content',
      205, 'Reset Content',
      206, 'Partial Content',
      300, 'Multiple Choices',
      301, 'Moved Permanently',
      302, 'Found',
      303, 'See Other',
      304, 'Not Modified',
      305, 'Use Proxy',
      307, 'Temporary Redirect',
      400, 'Bad Request',
      401, 'Unauthorized',
      402, 'Payment Required',
      403, 'Forbidden',
      404, 'Not Found',
      405, 'Method Not Allowed',
      406, 'Not Acceptable',
      407, 'Proxy Authentication Required',
      408, 'Request Timeout',
      409, 'Conflict',
      410, 'Gone',
      411, 'Length Required',
      412, 'Precondition Failed',
      413, 'Request Entity Too Large',
      414, 'Request-URI Too Large',
      415, 'Unsupported Media Type',
      416, 'Request Range Not Satisfiable',
      417, 'Expectation Failed',
      500, 'Internal Server Error',
      501, 'Not Implemented',
      502, 'Bad Gateway',
      503, 'Service Unavailable',
      504, 'Gateway Timeout',
      505, 'HTTP Version Not Supported'
    }

    CodeToError = {}

    StatusMessage.each{|code, message|
      message.freeze
      var_name = message.gsub(/[ \-]/,'_').upcase
      err_name = message.gsub(/[ \-]/,'')

      case code
      when 100...200; parent = Info
      when 200...300; parent = Success
      when 300...400; parent = Redirect
      when 400...500; parent = ClientError
      when 500...600; parent = ServerError
      end

      const_set("RC_#{var_name}", code)
      err_class = Class.new(parent)
      err_class.instance_variable_set(:@code, code)
      err_class.instance_variable_set(:@reason_phrase, message)
      const_set(err_name, err_class)
      CodeToError[code] = err_class
    }

    def reason_phrase(code)
      StatusMessage[code.to_i]
    end
    def info?(code)
      code.to_i >= 100 and code.to_i < 200
    end
    def success?(code)
      code.to_i >= 200 and code.to_i < 300
    end
    def redirect?(code)
      code.to_i >= 300 and code.to_i < 400
    end
    def error?(code)
      code.to_i >= 400 and code.to_i < 600
    end
    def client_error?(code)
      code.to_i >= 400 and code.to_i < 500
    end
    def server_error?(code)
      code.to_i >= 500 and code.to_i < 600
    end

    def self.[](code)
      CodeToError[code]
    end

    module_function :reason_phrase
    module_function :info?, :success?, :redirect?, :error?
    module_function :client_error?, :server_error?
  end
end
PK     iY\ͩ      webrick/cgi.rbnu [        #
# cgi.rb -- Yet another CGI library
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
# reserved.
#
# $Id: cgi.rb 11708 2007-02-12 23:01:19Z shyouhei $

require "webrick/httprequest"
require "webrick/httpresponse"
require "webrick/config"
require "stringio"

module WEBrick
  class CGI
    CGIError = Class.new(StandardError)

    attr_reader :config, :logger

    def initialize(*args)
      if defined?(MOD_RUBY)
        unless ENV.has_key?("GATEWAY_INTERFACE")
          Apache.request.setup_cgi_env
        end
      end
      if %r{HTTP/(\d+\.\d+)} =~ ENV["SERVER_PROTOCOL"]
        httpv = $1
      end
      @config = WEBrick::Config::HTTP.dup.update(
        :ServerSoftware => ENV["SERVER_SOFTWARE"] || "null",
        :HTTPVersion    => HTTPVersion.new(httpv || "1.0"),
        :RunOnCGI       => true,   # to detect if it runs on CGI.
        :NPH            => false   # set true to run as NPH script.
      )
      if config = args.shift
        @config.update(config)
      end
      @config[:Logger] ||= WEBrick::BasicLog.new($stderr)
      @logger = @config[:Logger]
      @options = args
    end

    def [](key)
      @config[key]
    end

    def start(env=ENV, stdin=$stdin, stdout=$stdout)
      sock = WEBrick::CGI::Socket.new(@config, env, stdin, stdout)
      req = HTTPRequest.new(@config)
      res = HTTPResponse.new(@config)
      unless @config[:NPH] or defined?(MOD_RUBY)
        def res.setup_header
          unless @header["status"]
            phrase = HTTPStatus::reason_phrase(@status)
            @header["status"] = "#{@status} #{phrase}"
          end
          super
        end
        def res.status_line
          ""
        end
      end

      begin
        req.parse(sock)
        req.script_name = (env["SCRIPT_NAME"] || File.expand_path($0)).dup
        req.path_info = (env["PATH_INFO"] || "").dup
        req.query_string = env["QUERY_STRING"]
        req.user = env["REMOTE_USER"]
        res.request_method = req.request_method
        res.request_uri = req.request_uri
        res.request_http_version = req.http_version
        res.keep_alive = req.keep_alive?
        self.service(req, res)
      rescue HTTPStatus::Error => ex
        res.set_error(ex)
      rescue HTTPStatus::Status => ex
        res.status = ex.code
      rescue Exception => ex 
        @logger.error(ex)
        res.set_error(ex, true)
      ensure
        req.fixup
        if defined?(MOD_RUBY)
          res.setup_header
          Apache.request.status_line = "#{res.status} #{res.reason_phrase}"
          Apache.request.status = res.status
          table = Apache.request.headers_out
          res.header.each{|key, val|
            case key
            when /^content-encoding$/i
              Apache::request.content_encoding = val
            when /^content-type$/i
              Apache::request.content_type = val
            else
              table[key] = val.to_s
            end
          }
          res.cookies.each{|cookie|
            table.add("Set-Cookie", cookie.to_s)
          }
          Apache.request.send_http_header
          res.send_body(sock)
        else
          res.send_response(sock)
        end
      end
    end

    def service(req, res)
      method_name = "do_" + req.request_method.gsub(/-/, "_")
      if respond_to?(method_name)
        __send__(method_name, req, res)
      else
        raise HTTPStatus::MethodNotAllowed,
              "unsupported method `#{req.request_method}'."
      end
    end

    class Socket
      include Enumerable

      private
  
      def initialize(config, env, stdin, stdout)
        @config = config
        @env = env
        @header_part = StringIO.new
        @body_part = stdin
        @out_port = stdout
        @out_port.binmode
  
        @server_addr = @env["SERVER_ADDR"] || "0.0.0.0"
        @server_name = @env["SERVER_NAME"]
        @server_port = @env["SERVER_PORT"]
        @remote_addr = @env["REMOTE_ADDR"]
        @remote_host = @env["REMOTE_HOST"] || @remote_addr
        @remote_port = @env["REMOTE_PORT"] || 0

        begin
          @header_part << request_line << CRLF
          setup_header
          @header_part << CRLF
          @header_part.rewind
        rescue Exception => ex
          raise CGIError, "invalid CGI environment"
        end
      end

      def request_line
        meth = @env["REQUEST_METHOD"] || "GET"
        unless url = @env["REQUEST_URI"]
          url = (@env["SCRIPT_NAME"] || File.expand_path($0)).dup
          url << @env["PATH_INFO"].to_s
          url = WEBrick::HTTPUtils.escape_path(url)
          if query_string = @env["QUERY_STRING"]
            unless query_string.empty?
              url << "?" << query_string
            end
          end
        end
        # we cannot get real HTTP version of client ;)
        httpv = @config[:HTTPVersion]
        return "#{meth} #{url} HTTP/#{httpv}"
      end
  
      def setup_header
        add_header("CONTENT_TYPE", "Content-Type")
        add_header("CONTENT_LENGTH", "Content-length")
        @env.each_key{|name|
          if /^HTTP_(.*)/ =~ name
            add_header(name, $1.gsub(/_/, "-"))
          end
        }
      end
  
      def add_header(envname, hdrname)
        if value = @env[envname]
          unless value.empty?
            @header_part << hdrname << ": " << value << CRLF
          end
        end
      end

      def input
        @header_part.eof? ? @body_part : @header_part
      end
  
      public
  
      def peeraddr
        [nil, @remote_port, @remote_host, @remote_addr]
      end
  
      def addr
        [nil, @server_port, @server_name, @server_addr]
      end
  
      def gets(eol=LF)
        input.gets(eol)
      end
  
      def read(size=nil)
        input.read(size)
      end

      def each
        input.each{|line| yield(line) }
      end
  
      def <<(data)
        @out_port << data
      end

      def cert
        return nil unless defined?(OpenSSL)
        if pem = @env["SSL_SERVER_CERT"]
          OpenSSL::X509::Certificate.new(pem) unless pem.empty?
        end
      end

      def peer_cert
        return nil unless defined?(OpenSSL)
        if pem = @env["SSL_CLIENT_CERT"]
          OpenSSL::X509::Certificate.new(pem) unless pem.empty?
        end
      end

      def peer_cert_chain
        return nil unless defined?(OpenSSL)
        if @env["SSL_CLIENT_CERT_CHAIN_0"]
          keys = @env.keys
          certs = keys.sort.collect{|k|
            if /^SSL_CLIENT_CERT_CHAIN_\d+$/ =~ k
              if pem = @env[k]
                OpenSSL::X509::Certificate.new(pem) unless pem.empty?
              end
            end
          }
          certs.compact
        end
      end

      def cipher
        return nil unless defined?(OpenSSL)
        if cipher = @env["SSL_CIPHER"]
          ret = [ cipher ]
          ret << @env["SSL_PROTOCOL"]
          ret << @env["SSL_CIPHER_USEKEYSIZE"]
          ret << @env["SSL_CIPHER_ALGKEYSIZE"]
          ret
        end
      end
    end
  end 
end  
PK     jY\/ݔv  v    webrick/httpversion.rbnu [        #
# HTTPVersion.rb -- presentation of HTTP version
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: httpversion.rb,v 1.5 2002/09/21 12:23:37 gotoyuzo Exp $

module WEBrick
  class HTTPVersion
    include Comparable

    attr_accessor :major, :minor

    def self.convert(version)
      version.is_a?(self) ? version : new(version)
    end

    def initialize(version)
      case version
      when HTTPVersion
        @major, @minor = version.major, version.minor
      when String
        if /^(\d+)\.(\d+)$/ =~ version
          @major, @minor = $1.to_i, $2.to_i
        end
      end
      if @major.nil? || @minor.nil?
        raise ArgumentError,
          format("cannot convert %s into %s", version.class, self.class)
      end
    end

    def <=>(other)
      unless other.is_a?(self.class)
        other = self.class.new(other)
      end
      if (ret = @major <=> other.major) == 0
        return @minor <=> other.minor
      end
      return ret
    end

    def to_s
      format("%d.%d", @major, @minor)
    end
  end
end
PK     jY\!G      webrick/httpserver.rbnu [        #
# httpserver.rb -- HTTPServer Class
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: httpserver.rb,v 1.63 2002/10/01 17:16:32 gotoyuzo Exp $

require 'webrick/server'
require 'webrick/httputils'
require 'webrick/httpstatus'
require 'webrick/httprequest'
require 'webrick/httpresponse'
require 'webrick/httpservlet'
require 'webrick/accesslog'

module WEBrick
  class HTTPServerError < ServerError; end

  class HTTPServer < ::WEBrick::GenericServer
    def initialize(config={}, default=Config::HTTP)
      super
      @http_version = HTTPVersion::convert(@config[:HTTPVersion])

      @mount_tab = MountTable.new
      if @config[:DocumentRoot]
        mount("/", HTTPServlet::FileHandler, @config[:DocumentRoot],
              @config[:DocumentRootOptions])
      end

      unless @config[:AccessLog]
        @config[:AccessLog] = [
          [ $stderr, AccessLog::COMMON_LOG_FORMAT ],
          [ $stderr, AccessLog::REFERER_LOG_FORMAT ]
        ]
      end
 
      @virtual_hosts = Array.new
    end

    def run(sock)
      while true 
        res = HTTPResponse.new(@config)
        req = HTTPRequest.new(@config)
        server = self
        begin
          timeout = @config[:RequestTimeout]
          while timeout > 0
            break if IO.select([sock], nil, nil, 0.5)
            timeout = 0 if @status != :Running
            timeout -= 0.5
          end
          raise HTTPStatus::EOFError if timeout <= 0 || sock.eof?
          req.parse(sock)
          res.request_method = req.request_method
          res.request_uri = req.request_uri
          res.request_http_version = req.http_version
          res.keep_alive = req.keep_alive?
          server = lookup_server(req) || self
          if callback = server[:RequestCallback] || server[:RequestHandler]
            callback.call(req, res)
          end
          server.service(req, res)
        rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
          res.set_error(ex)
        rescue HTTPStatus::Error => ex
          @logger.error(ex.message)
          res.set_error(ex)
        rescue HTTPStatus::Status => ex
          res.status = ex.code
        rescue StandardError => ex
          @logger.error(ex)
          res.set_error(ex, true)
        ensure
          if req.request_line
            req.fixup()
            res.send_response(sock)
            server.access_log(@config, req, res)
          end
        end
        break if @http_version < "1.1"
        break unless req.keep_alive?
        break unless res.keep_alive?
      end
    end

    def service(req, res)
      if req.unparsed_uri == "*"
        if req.request_method == "OPTIONS"
          do_OPTIONS(req, res)
          raise HTTPStatus::OK
        end
        raise HTTPStatus::NotFound, "`#{req.unparsed_uri}' not found."
      end

      servlet, options, script_name, path_info = search_servlet(req.path)
      raise HTTPStatus::NotFound, "`#{req.path}' not found." unless servlet
      req.script_name = script_name
      req.path_info = path_info
      si = servlet.get_instance(self, *options)
      @logger.debug(format("%s is invoked.", si.class.name))
      si.service(req, res)
    end

    def do_OPTIONS(req, res)
      res["allow"] = "GET,HEAD,POST,OPTIONS"
    end

    def mount(dir, servlet, *options)
      @logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir))
      @mount_tab[dir] = [ servlet, options ]
    end

    def mount_proc(dir, proc=nil, &block)
      proc ||= block
      raise HTTPServerError, "must pass a proc or block" unless proc
      mount(dir, HTTPServlet::ProcHandler.new(proc))
    end

    def unmount(dir)
      @logger.debug(sprintf("unmount %s.", dir))
      @mount_tab.delete(dir)
    end
    alias umount unmount

    def search_servlet(path)
      script_name, path_info = @mount_tab.scan(path)
      servlet, options = @mount_tab[script_name]
      if servlet
        [ servlet, options, script_name, path_info ]
      end
    end

    def virtual_host(server)
      @virtual_hosts << server
      @virtual_hosts = @virtual_hosts.sort_by{|s|
        num = 0
        num -= 4 if s[:BindAddress]
        num -= 2 if s[:Port]
        num -= 1 if s[:ServerName]
        num
      }
    end

    def lookup_server(req)
      @virtual_hosts.find{|s|
        (s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) &&
        (s[:Port].nil?        || req.port == s[:Port])           &&
        ((s[:ServerName].nil?  || req.host == s[:ServerName]) ||
         (!s[:ServerAlias].nil? && s[:ServerAlias].find{|h| h === req.host}))
      }
    end

    def access_log(config, req, res)
      param = AccessLog::setup_params(config, req, res)
      @config[:AccessLog].each{|logger, fmt|
        logger << AccessLog::format(fmt+"\n", param)
      }
    end

    class MountTable
      def initialize
        @tab = Hash.new
        compile
      end

      def [](dir)
        dir = normalize(dir)
        @tab[dir]
      end

      def []=(dir, val)
        dir = normalize(dir)
        @tab[dir] = val
        compile
        val
      end

      def delete(dir)
        dir = normalize(dir)
        res = @tab.delete(dir)
        compile
        res
      end

      def scan(path)
        @scanner =~ path
        [ $&, $' ]
      end

      private

      def compile
        k = @tab.keys
        k.sort!
        k.reverse!
        k.collect!{|path| Regexp.escape(path) }
        @scanner = Regexp.new("^(" + k.join("|") +")(?=/|$)")
      end

      def normalize(dir)
        ret = dir ? dir.dup : ""
        ret.sub!(%r|/+$|, "")
        ret
      end
    end
  end
end
PK     kY\W'  '    webrick/httputils.rbnu [        #
# httputils.rb -- HTTPUtils Module
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: httputils.rb,v 1.34 2003/06/05 21:34:08 gotoyuzo Exp $

require 'socket'
require 'tempfile'

module WEBrick
  CR   = "\x0d"
  LF   = "\x0a"
  CRLF = "\x0d\x0a"

  module HTTPUtils

    def normalize_path(path)
      raise "abnormal path `#{path}'" if path[0] != ?/
      ret = path.dup

      ret.gsub!(%r{/+}o, '/')                    # //      => /
      while ret.sub!(%r'/\.(?:/|\Z)', '/'); end  # /.      => /
      while ret.sub!(%r'/(?!\.\./)[^/]+/\.\.(?:/|\Z)', '/'); end # /foo/.. => /foo

      raise "abnormal path `#{path}'" if %r{/\.\.(/|\Z)} =~ ret
      ret
    end
    module_function :normalize_path

    #####

    DefaultMimeTypes = {
      "ai"    => "application/postscript",
      "asc"   => "text/plain",
      "avi"   => "video/x-msvideo",
      "bin"   => "application/octet-stream",
      "bmp"   => "image/bmp",
      "class" => "application/octet-stream",
      "cer"   => "application/pkix-cert",
      "crl"   => "application/pkix-crl",
      "crt"   => "application/x-x509-ca-cert",
     #"crl"   => "application/x-pkcs7-crl",
      "css"   => "text/css",
      "dms"   => "application/octet-stream",
      "doc"   => "application/msword",
      "dvi"   => "application/x-dvi",
      "eps"   => "application/postscript",
      "etx"   => "text/x-setext",
      "exe"   => "application/octet-stream",
      "gif"   => "image/gif",
      "htm"   => "text/html",
      "html"  => "text/html",
      "jpe"   => "image/jpeg",
      "jpeg"  => "image/jpeg",
      "jpg"   => "image/jpeg",
      "lha"   => "application/octet-stream",
      "lzh"   => "application/octet-stream",
      "mov"   => "video/quicktime",
      "mpe"   => "video/mpeg",
      "mpeg"  => "video/mpeg",
      "mpg"   => "video/mpeg",
      "pbm"   => "image/x-portable-bitmap",
      "pdf"   => "application/pdf",
      "pgm"   => "image/x-portable-graymap",
      "png"   => "image/png",
      "pnm"   => "image/x-portable-anymap",
      "ppm"   => "image/x-portable-pixmap",
      "ppt"   => "application/vnd.ms-powerpoint",
      "ps"    => "application/postscript",
      "qt"    => "video/quicktime",
      "ras"   => "image/x-cmu-raster",
      "rb"    => "text/plain",
      "rd"    => "text/plain",
      "rtf"   => "application/rtf",
      "sgm"   => "text/sgml",
      "sgml"  => "text/sgml",
      "tif"   => "image/tiff",
      "tiff"  => "image/tiff",
      "txt"   => "text/plain",
      "xbm"   => "image/x-xbitmap",
      "xls"   => "application/vnd.ms-excel",
      "xml"   => "text/xml",
      "xpm"   => "image/x-xpixmap",
      "xwd"   => "image/x-xwindowdump",
      "zip"   => "application/zip",
    }

    # Load Apache compatible mime.types file.
    def load_mime_types(file)
      open(file){ |io|
        hash = Hash.new
        io.each{ |line|
          next if /^#/ =~ line
          line.chomp!
          mimetype, ext0 = line.split(/\s+/, 2)
          next unless ext0   
          next if ext0.empty?
          ext0.split(/\s+/).each{ |ext| hash[ext] = mimetype }
        }
        hash
      }
    end
    module_function :load_mime_types

    def mime_type(filename, mime_tab)
      suffix1 = (/\.(\w+)$/ =~ filename && $1.downcase)
      suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ filename && $1.downcase)
      mime_tab[suffix1] || mime_tab[suffix2] || "application/octet-stream"
    end
    module_function :mime_type

    #####

    def parse_header(raw)
      header = Hash.new([].freeze)
      field = nil
      raw.each{|line|
        case line
        when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):\s*(.*?)\s*\z/om
          field, value = $1, $2
          field.downcase!
          header[field] = [] unless header.has_key?(field)
          header[field] << value
        when /^\s+(.*?)\s*\z/om
          value = $1
          unless field
            raise HTTPStatus::BadRequest, "bad header '#{line}'."
          end
          header[field][-1] << " " << value
        else
          raise HTTPStatus::BadRequest, "bad header '#{line}'."
        end
      }
      header.each{|key, values|
        values.each{|value|
          value.strip!
          value.gsub!(/\s+/, " ")
        }
      }
      header
    end
    module_function :parse_header

    def split_header_value(str)
      str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]+)+)
                    (?:,\s*|\Z)'xn).flatten
    end
    module_function :split_header_value

    def parse_range_header(ranges_specifier)
      if /^bytes=(.*)/ =~ ranges_specifier
        byte_range_set = split_header_value($1)
        byte_range_set.collect{|range_spec|
          case range_spec
          when /^(\d+)-(\d+)/ then $1.to_i .. $2.to_i
          when /^(\d+)-/      then $1.to_i .. -1
          when /^-(\d+)/      then -($1.to_i) .. -1
          else return nil
          end
        }
      end
    end
    module_function :parse_range_header

    def parse_qvalues(value)
      tmp = []
      if value
        parts = value.split(/,\s*/)
        parts.each {|part|
          if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
            val = m[1]
            q = (m[2] or 1).to_f
            tmp.push([val, q])
          end
        }
        tmp = tmp.sort_by{|val, q| -q}
        tmp.collect!{|val, q| val}
      end
      return tmp
    end
    module_function :parse_qvalues

    #####

    def dequote(str)
      ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
      ret.gsub!(/\\(.)/, "\\1")
      ret
    end
    module_function :dequote

    def quote(str)
      '"' << str.gsub(/[\\\"]/o, "\\\1") << '"'
    end
    module_function :quote

    #####

    class FormData < String
      EmptyRawHeader = [].freeze
      EmptyHeader = {}.freeze

      attr_accessor :name, :filename, :next_data
      protected :next_data

      def initialize(*args)
        @name = @filename = @next_data = nil
        if args.empty?
          @raw_header = []
          @header = nil
          super("")
        else
          @raw_header = EmptyRawHeader
          @header = EmptyHeader 
          super(args.shift)
          unless args.empty?
            @next_data = self.class.new(*args)
          end
        end
      end

      def [](*key)
        begin
          @header[key[0].downcase].join(", ")
        rescue StandardError, NameError
          super
        end
      end

      def <<(str)
        if @header
          super
        elsif str == CRLF
          @header = HTTPUtils::parse_header(@raw_header)
          if cd = self['content-disposition']
            if /\s+name="(.*?)"/ =~ cd then @name = $1 end
            if /\s+filename="(.*?)"/ =~ cd then @filename = $1 end
          end
        else
          @raw_header << str
        end
        self
      end

      def append_data(data)
        tmp = self
        while tmp
          unless tmp.next_data 
            tmp.next_data = data
            break
          end
          tmp = tmp.next_data
        end
        self
      end

      def each_data
        tmp = self
        while tmp
          next_data = tmp.next_data
          yield(tmp)
          tmp = next_data
        end
      end

      def list
        ret = []
        each_data{|data|
          ret << data.to_s
        }
        ret
      end

      alias :to_ary :list

      def to_s
        String.new(self)
      end
    end

    def parse_query(str)
      query = Hash.new
      if str
        str.split(/[&;]/).each{|x|
          next if x.empty? 
          key, val = x.split(/=/,2)
          key = unescape_form(key)
          val = unescape_form(val.to_s)
          val = FormData.new(val)
          val.name = key
          if query.has_key?(key)
            query[key].append_data(val)
            next
          end
          query[key] = val
        }
      end
      query
    end
    module_function :parse_query

    def parse_form_data(io, boundary)
      boundary_regexp = /\A--#{boundary}(--)?#{CRLF}\z/
      form_data = Hash.new
      return form_data unless io
      data = nil
      io.each{|line|
        if boundary_regexp =~ line
          if data
            data.chop!
            key = data.name
            if form_data.has_key?(key)
              form_data[key].append_data(data)
            else
              form_data[key] = data 
            end
          end
          data = FormData.new
          next
        else
          if data
            data << line
          end
        end
      }
      return form_data
    end
    module_function :parse_form_data

    #####

    reserved = ';/?:@&=+$,'
    num      = '0123456789'
    lowalpha = 'abcdefghijklmnopqrstuvwxyz'
    upalpha  = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    mark     = '-_.!~*\'()'
    unreserved = num + lowalpha + upalpha + mark
    control  = (0x0..0x1f).collect{|c| c.chr }.join + "\x7f"
    space    = " "
    delims   = '<>#%"'
    unwise   = '{}|\\^[]`'
    nonascii = (0x80..0xff).collect{|c| c.chr }.join

    module_function

    def _make_regex(str) /([#{Regexp.escape(str)}])/n end
    def _make_regex!(str) /([^#{Regexp.escape(str)}])/n end
    def _escape(str, regex) str.gsub(regex){ "%%%02X" % $1[0] } end
    def _unescape(str, regex) str.gsub(regex){ $1.hex.chr } end

    UNESCAPED = _make_regex(control+space+delims+unwise+nonascii)
    UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii)
    NONASCII  = _make_regex(nonascii)
    ESCAPED   = /%([0-9a-fA-F]{2})/
    UNESCAPED_PCHAR = _make_regex!(unreserved+":@&=+$,")

    def escape(str)
      _escape(str, UNESCAPED)
    end

    def unescape(str)
      _unescape(str, ESCAPED)
    end

    def escape_form(str)
      ret = _escape(str, UNESCAPED_FORM)
      ret.gsub!(/ /, "+")
      ret
    end

    def unescape_form(str)
      _unescape(str.gsub(/\+/, " "), ESCAPED)
    end

    def escape_path(str)
      result = ""
      str.scan(%r{/([^/]*)}).each{|i|
        result << "/" << _escape(i[0], UNESCAPED_PCHAR)
      }
      return result
    end

    def escape8bit(str)
      _escape(str, NONASCII)
    end
  end
end
PK     lY\`>H  H    webrick/htmlutils.rbnu [        #
# htmlutils.rb -- HTMLUtils Module
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: htmlutils.rb,v 1.7 2002/09/21 12:23:35 gotoyuzo Exp $

module WEBrick
  module HTMLUtils

    def escape(string)
      str = string ? string.dup : ""
      str.gsub!(/&/n, '&amp;')
      str.gsub!(/\"/n, '&quot;')
      str.gsub!(/>/n, '&gt;')
      str.gsub!(/</n, '&lt;')
      str
    end
    module_function :escape

  end
end
PK     lY\بj#  #    webrick/log.rbnu [        #
# log.rb -- Log Class
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: log.rb,v 1.26 2002/10/06 17:06:10 gotoyuzo Exp $

module WEBrick
  class BasicLog
    # log-level constant
    FATAL, ERROR, WARN, INFO, DEBUG = 1, 2, 3, 4, 5

    attr_accessor :level

    def initialize(log_file=nil, level=nil)
      @level = level || INFO
      case log_file
      when String
        @log = open(log_file, "a+")
        @log.sync = true
        @opened = true
      when NilClass
        @log = $stderr
      else
        @log = log_file  # requires "<<". (see BasicLog#log)
      end
    end

    def close
      @log.close if @opened
      @log = nil
    end

    def log(level, data)
      if @log && level <= @level
        data += "\n" if /\n\Z/ !~ data
        @log << data
      end
    end

    def <<(obj)
      log(INFO, obj.to_s)
    end

    def fatal(msg) log(FATAL, "FATAL " << format(msg)); end
    def error(msg) log(ERROR, "ERROR " << format(msg)); end
    def warn(msg)  log(WARN,  "WARN  " << format(msg)); end
    def info(msg)  log(INFO,  "INFO  " << format(msg)); end
    def debug(msg) log(DEBUG, "DEBUG " << format(msg)); end

    def fatal?; @level >= FATAL; end
    def error?; @level >= ERROR; end
    def warn?;  @level >= WARN; end
    def info?;  @level >= INFO; end
    def debug?; @level >= DEBUG; end

    private

    def format(arg)
      str = if arg.is_a?(Exception)
        "#{arg.class}: #{arg.message}\n\t" <<
        arg.backtrace.join("\n\t") << "\n"
      elsif arg.respond_to?(:to_str)
        arg.to_str
      else
        arg.inspect
      end
    end
  end

  class Log < BasicLog
    attr_accessor :time_format 

    def initialize(log_file=nil, level=nil)
      super(log_file, level)
      @time_format = "[%Y-%m-%d %H:%M:%S]"
    end

    def log(level, data)
      tmp = Time.now.strftime(@time_format)
      tmp << " " << data
      super(level, tmp)
    end
  end
end
PK     mY\
_      webrick/https.rbnu [        #
# https.rb -- SSL/TLS enhancement for HTTPServer
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2001 GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: https.rb,v 1.15 2003/07/22 19:20:42 gotoyuzo Exp $

require 'webrick/ssl'

module WEBrick
  module Config
    HTTP.update(SSL)
  end

  class HTTPRequest
    attr_reader :cipher, :server_cert, :client_cert

    alias orig_parse parse

    def parse(socket=nil)
      @cipher = @server_cert = @client_cert = nil
      if socket.respond_to?(:cert)
        @server_cert = socket.cert || @config[:SSLCertificate]
        @client_cert = socket.peer_cert
        @client_cert_chain = socket.peer_cert_chain
        @cipher      = socket.cipher
      end
      orig_parse(socket)
    end

    alias orig_parse_uri parse_uri

    def parse_uri(str, scheme="https")
      if @server_cert
        return orig_parse_uri(str, scheme)
      end
      return orig_parse_uri(str)
    end

    alias orig_meta_vars meta_vars

    def meta_vars
      meta = orig_meta_vars
      if @server_cert
        meta["HTTPS"] = "on"
        meta["SSL_SERVER_CERT"] = @server_cert.to_pem
        meta["SSL_CLIENT_CERT"] = @client_cert ? @client_cert.to_pem : ""
        if @client_cert_chain
          @client_cert_chain.each_with_index{|cert, i|
            meta["SSL_CLIENT_CERT_CHAIN_#{i}"] = cert.to_pem
          }
        end
        meta["SSL_CIPHER"] = @cipher[0]
        meta["SSL_PROTOCOL"] = @cipher[1]
        meta["SSL_CIPHER_USEKEYSIZE"] = @cipher[2].to_s
        meta["SSL_CIPHER_ALGKEYSIZE"] = @cipher[3].to_s
      end
      meta
    end
  end
end
PK     mY\2      webrick/httpresponse.rbnu [        #
# httpresponse.rb -- HTTPResponse Class
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: httpresponse.rb,v 1.45 2003/07/11 11:02:25 gotoyuzo Exp $

require 'time'
require 'webrick/httpversion'
require 'webrick/htmlutils'
require 'webrick/httputils'
require 'webrick/httpstatus'

module WEBrick
  class HTTPResponse
    BUFSIZE = 1024*4

    attr_reader :http_version, :status, :header
    attr_reader :cookies
    attr_accessor :reason_phrase
    attr_accessor :body

    attr_accessor :request_method, :request_uri, :request_http_version
    attr_accessor :filename
    attr_accessor :keep_alive
    attr_reader :config, :sent_size

    def initialize(config)
      @config = config
      @logger = config[:Logger]
      @header = Hash.new
      @status = HTTPStatus::RC_OK
      @reason_phrase = nil
      @http_version = HTTPVersion::convert(@config[:HTTPVersion])
      @body = ''
      @keep_alive = true
      @cookies = []
      @request_method = nil
      @request_uri = nil
      @request_http_version = @http_version  # temporary
      @chunked = false
      @filename = nil
      @sent_size = 0
    end

    def status_line
      "HTTP/#@http_version #@status #@reason_phrase #{CRLF}"
    end

    def status=(status)
      @status = status
      @reason_phrase = HTTPStatus::reason_phrase(status)
    end

    def [](field)
      @header[field.downcase]
    end

    def []=(field, value)
      @header[field.downcase] = value.to_s
    end

    def content_length
      if len = self['content-length']
        return Integer(len)
      end
    end

    def content_length=(len)
      self['content-length'] = len.to_s
    end

    def content_type
      self['content-type']
    end

    def content_type=(type)
      self['content-type'] = type
    end

    def each
      @header.each{|k, v|  yield(k, v) }
    end

    def chunked?
      @chunked
    end

    def chunked=(val)
      @chunked = val ? true : false
    end

    def keep_alive?
      @keep_alive
    end

    def send_response(socket)
      begin
        setup_header()
        send_header(socket)
        send_body(socket)
      rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN => ex
        @logger.debug(ex)
        @keep_alive = false
      rescue Exception => ex
        @logger.error(ex)
        @keep_alive = false
      end
    end

    def setup_header()
      @reason_phrase    ||= HTTPStatus::reason_phrase(@status)
      @header['server'] ||= @config[:ServerSoftware]
      @header['date']   ||= Time.now.httpdate

      # HTTP/0.9 features
      if @request_http_version < "1.0"
        @http_version = HTTPVersion.new("0.9")
        @keep_alive = false
      end

      # HTTP/1.0 features
      if @request_http_version < "1.1"
        if chunked?
          @chunked = false
          ver = @request_http_version.to_s
          msg = "chunked is set for an HTTP/#{ver} request. (ignored)"
          @logger.warn(msg)
        end
      end

      # Determine the message length (RFC2616 -- 4.4 Message Length)
      if @status == 304 || @status == 204 || HTTPStatus::info?(@status)
        @header.delete('content-length')
        @body = ""
      elsif chunked?
        @header["transfer-encoding"] = "chunked"
        @header.delete('content-length')
      elsif %r{^multipart/byteranges} =~ @header['content-type']
        @header.delete('content-length')
      elsif @header['content-length'].nil?
        unless @body.is_a?(IO)
          @header['content-length'] = @body ? @body.size : 0
        end
      end

      # Keep-Alive connection.
      if @header['connection'] == "close"
         @keep_alive = false
      elsif keep_alive?
        if chunked? || @header['content-length']
          @header['connection'] = "Keep-Alive"
        end
      else
        @header['connection'] = "close"
      end

      # Location is a single absoluteURI.
      if location = @header['location']
        if @request_uri
          @header['location'] = @request_uri.merge(location)
        end
      end
    end

    def send_header(socket)
      if @http_version.major > 0
        data = status_line()
        @header.each{|key, value|
          tmp = key.gsub(/\bwww|^te$|\b\w/){|s| s.upcase }
          data << "#{tmp}: #{value}" << CRLF
        }
        @cookies.each{|cookie|
          data << "Set-Cookie: " << cookie.to_s << CRLF
        }
        data << CRLF
        _write_data(socket, data)
      end
    end

    def send_body(socket)
      case @body
      when IO then send_body_io(socket)
      else send_body_string(socket)
      end
    end

    def to_s
      ret = ""
      send_response(ret)
      ret
    end

    def set_redirect(status, url)
      @body = "<HTML><A HREF=\"#{url.to_s}\">#{url.to_s}</A>.</HTML>\n"
      @header['location'] = url.to_s
      raise status
    end

    def set_error(ex, backtrace=false)
      case ex
      when HTTPStatus::Status 
        @keep_alive = false if HTTPStatus::error?(ex.code)
        self.status = ex.code
      else 
        @keep_alive = false
        self.status = HTTPStatus::RC_INTERNAL_SERVER_ERROR
      end
      @header['content-type'] = "text/html; charset=ISO-8859-1"

      if respond_to?(:create_error_page)
        create_error_page()
        return
      end

      if @request_uri
        host, port = @request_uri.host, @request_uri.port
      else
        host, port = @config[:ServerName], @config[:Port]
      end

      @body = ''
      @body << <<-_end_of_html_
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
  <HEAD><TITLE>#{HTMLUtils::escape(@reason_phrase)}</TITLE></HEAD>
  <BODY>
    <H1>#{HTMLUtils::escape(@reason_phrase)}</H1>
    #{HTMLUtils::escape(ex.message)}
    <HR>
      _end_of_html_

      if backtrace && $DEBUG
        @body << "backtrace of `#{HTMLUtils::escape(ex.class.to_s)}' "
        @body << "#{HTMLUtils::escape(ex.message)}"
        @body << "<PRE>"
        ex.backtrace.each{|line| @body << "\t#{line}\n"}
        @body << "</PRE><HR>"
      end

      @body << <<-_end_of_html_
    <ADDRESS>
     #{HTMLUtils::escape(@config[:ServerSoftware])} at
     #{host}:#{port}
    </ADDRESS>
  </BODY>
</HTML>
      _end_of_html_
    end

    private

    def send_body_io(socket)
      begin
        if @request_method == "HEAD"
          # do nothing
        elsif chunked?
          while buf = @body.read(BUFSIZE)
            next if buf.empty?
            data = ""
            data << format("%x", buf.size) << CRLF
            data << buf << CRLF
            _write_data(socket, data)
            @sent_size += buf.size
          end
          _write_data(socket, "0#{CRLF}#{CRLF}")
        else
          size = @header['content-length'].to_i
          _send_file(socket, @body, 0, size)
          @sent_size = size
        end
      ensure
        @body.close
      end
    end

    def send_body_string(socket)
      if @request_method == "HEAD"
        # do nothing
      elsif chunked?
        remain = body ? @body.size : 0
        while buf = @body[@sent_size, BUFSIZE]
          break if buf.empty?
          data = ""
          data << format("%x", buf.size) << CRLF
          data << buf << CRLF
          _write_data(socket, data)
          @sent_size += buf.size
        end
        _write_data(socket, "0#{CRLF}#{CRLF}")
      else
        if @body && @body.size > 0
          _write_data(socket, @body)
          @sent_size = @body.size
        end
      end
    end

    def _send_file(output, input, offset, size)
      while offset > 0
        sz = BUFSIZE < offset ? BUFSIZE : offset
        buf = input.read(sz)
        offset -= buf.size
      end

      if size == 0
        while buf = input.read(BUFSIZE)
          _write_data(output, buf)
        end
      else
        while size > 0
          sz = BUFSIZE < size ? BUFSIZE : size
          buf = input.read(sz)
          _write_data(output, buf)
          size -= buf.size
        end
      end
    end

    def _write_data(socket, data)
      socket << data
    end
  end
end
PK     nY\DgQ,
  ,
    webrick/utils.rbnu [        #
# utils.rb -- Miscellaneous utilities
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: utils.rb,v 1.10 2003/02/16 22:22:54 gotoyuzo Exp $

require 'socket'
require 'fcntl'
begin
  require 'etc'
rescue LoadError
  nil
end

module WEBrick
  module Utils
    def set_non_blocking(io)
      flag = File::NONBLOCK
      if defined?(Fcntl::F_GETFL)
        flag |= io.fcntl(Fcntl::F_GETFL)
      end
      io.fcntl(Fcntl::F_SETFL, flag)
    end
    module_function :set_non_blocking

    def set_close_on_exec(io)
      if defined?(Fcntl::FD_CLOEXEC)
        io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
      end
    end
    module_function :set_close_on_exec

    def su(user)
      if defined?(Etc)
        pw = Etc.getpwnam(user)
        Process::initgroups(user, pw.gid)
        Process::Sys::setgid(pw.gid)
        Process::Sys::setuid(pw.uid)
      else
        warn("WEBrick::Utils::su doesn't work on this platform")
      end
    end
    module_function :su

    def getservername
      host = Socket::gethostname
      begin
        Socket::gethostbyname(host)[0]
      rescue
        host
      end
    end
    module_function :getservername

    def create_listeners(address, port, logger=nil)
      unless port
        raise ArgumentError, "must specify port"
      end
      res = Socket::getaddrinfo(address, port,
                                Socket::AF_UNSPEC,   # address family
                                Socket::SOCK_STREAM, # socket type
                                0,                   # protocol
                                Socket::AI_PASSIVE)  # flag
      last_error = nil
      sockets = []
      res.each{|ai|
        begin
          logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger
          sock = TCPServer.new(ai[3], port)
          port = sock.addr[1] if port == 0
          Utils::set_close_on_exec(sock)
          sockets << sock
        rescue => ex
          logger.warn("TCPServer Error: #{ex}") if logger
          last_error  = ex
        end
      }
      raise last_error if sockets.empty?
      return sockets
    end
    module_function :create_listeners

    RAND_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
                 "0123456789" +
                 "abcdefghijklmnopqrstuvwxyz" 

    def random_string(len)
      rand_max = RAND_CHARS.size
      ret = "" 
      len.times{ ret << RAND_CHARS[rand(rand_max)] }
      ret 
    end
    module_function :random_string

  end
end
PK     oY\~      webrick/httpproxy.rbnu [        #
# httpproxy.rb -- HTTPProxy Class
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2002 GOTO Kentaro
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: httpproxy.rb,v 1.18 2003/03/08 18:58:10 gotoyuzo Exp $
# $kNotwork: straw.rb,v 1.3 2002/02/12 15:13:07 gotoken Exp $

require "webrick/httpserver"
require "net/http"

Net::HTTP::version_1_2 if RUBY_VERSION < "1.7"

module WEBrick
  NullReader = Object.new
  class << NullReader
    def read(*args)
      nil
    end
    alias gets read
  end

  class HTTPProxyServer < HTTPServer
    def initialize(config)
      super
      c = @config
      @via = "#{c[:HTTPVersion]} #{c[:ServerName]}:#{c[:Port]}"
    end

    def service(req, res)
      if req.request_method == "CONNECT"
        proxy_connect(req, res)
      elsif req.unparsed_uri =~ %r!^http://!
        proxy_service(req, res)
      else
        super(req, res)
      end
    end

    def proxy_auth(req, res)
      if proc = @config[:ProxyAuthProc]
        proc.call(req, res)
      end
      req.header.delete("proxy-authorization")
    end

    # Some header fields should not be transferred.
    HopByHop = %w( connection keep-alive proxy-authenticate upgrade
                   proxy-authorization te trailers transfer-encoding )
    ShouldNotTransfer = %w( set-cookie proxy-connection )
    def split_field(f) f ? f.split(/,\s+/).collect{|i| i.downcase } : [] end

    def choose_header(src, dst)
      connections = split_field(src['connection'])
      src.each{|key, value|
        key = key.downcase
        if HopByHop.member?(key)          || # RFC2616: 13.5.1
           connections.member?(key)       || # RFC2616: 14.10
           ShouldNotTransfer.member?(key)    # pragmatics
          @logger.debug("choose_header: `#{key}: #{value}'")
          next
        end
        dst[key] = value
      }
    end

    # Net::HTTP is stupid about the multiple header fields.
    # Here is workaround:
    def set_cookie(src, dst)
      if str = src['set-cookie']
        cookies = []
        str.split(/,\s*/).each{|token|
          if /^[^=]+;/o =~ token
            cookies[-1] << ", " << token
          elsif /=/o =~ token
            cookies << token
          else
            cookies[-1] << ", " << token
          end
        }
        dst.cookies.replace(cookies)
      end
    end

    def set_via(h)
      if @config[:ProxyVia]
        if  h['via']
          h['via'] << ", " << @via
        else
          h['via'] = @via
        end
      end
    end

    def proxy_uri(req, res)
      @config[:ProxyURI]
    end

    def proxy_service(req, res)
      # Proxy Authentication
      proxy_auth(req, res)      

      # Create Request-URI to send to the origin server
      uri  = req.request_uri
      path = uri.path.dup
      path << "?" << uri.query if uri.query

      # Choose header fields to transfer
      header = Hash.new
      choose_header(req, header)
      set_via(header)

      # select upstream proxy server
      if proxy = proxy_uri(req, res)
        proxy_host = proxy.host
        proxy_port = proxy.port
        if proxy.userinfo
          credentials = "Basic " + [proxy.userinfo].pack("m*")
          credentials.chomp!
          header['proxy-authorization'] = credentials
        end
      end

      response = nil
      begin
        http = Net::HTTP.new(uri.host, uri.port, proxy_host, proxy_port)
        http.start{
          if @config[:ProxyTimeout]
            ##################################   these issues are 
            http.open_timeout = 30   # secs  #   necessary (maybe bacause
            http.read_timeout = 60   # secs  #   Ruby's bug, but why?)
            ##################################
          end
          case req.request_method
          when "GET"  then response = http.get(path, header)
          when "POST" then response = http.post(path, req.body || "", header)
          when "HEAD" then response = http.head(path, header)
          else
            raise HTTPStatus::MethodNotAllowed,
              "unsupported method `#{req.request_method}'."
          end
        }
      rescue => err
        logger.debug("#{err.class}: #{err.message}")
        raise HTTPStatus::ServiceUnavailable, err.message
      end
  
      # Persistent connction requirements are mysterious for me.
      # So I will close the connection in every response.
      res['proxy-connection'] = "close"
      res['connection'] = "close"

      # Convert Net::HTTP::HTTPResponse to WEBrick::HTTPProxy
      res.status = response.code.to_i
      choose_header(response, res)
      set_cookie(response, res)
      set_via(res)
      res.body = response.body

      # Process contents
      if handler = @config[:ProxyContentHandler]
        handler.call(req, res)
      end
    end

    def proxy_connect(req, res)
      # Proxy Authentication
      proxy_auth(req, res)

      ua = Thread.current[:WEBrickSocket]  # User-Agent
      raise HTTPStatus::InternalServerError,
        "[BUG] cannot get socket" unless ua

      host, port = req.unparsed_uri.split(":", 2)
      # Proxy authentication for upstream proxy server
      if proxy = proxy_uri(req, res)
        proxy_request_line = "CONNECT #{host}:#{port} HTTP/1.0"
        if proxy.userinfo
          credentials = "Basic " + [proxy.userinfo].pack("m*")
          credentials.chomp!
        end
        host, port = proxy.host, proxy.port
      end

      begin
        @logger.debug("CONNECT: upstream proxy is `#{host}:#{port}'.")
        os = TCPSocket.new(host, port)     # origin server

        if proxy
          @logger.debug("CONNECT: sending a Request-Line")
          os << proxy_request_line << CRLF
          @logger.debug("CONNECT: > #{proxy_request_line}")
          if credentials
            @logger.debug("CONNECT: sending a credentials")
            os << "Proxy-Authorization: " << credentials << CRLF
          end
          os << CRLF
          proxy_status_line = os.gets(LF)
          @logger.debug("CONNECT: read a Status-Line form the upstream server")
          @logger.debug("CONNECT: < #{proxy_status_line}")
          if %r{^HTTP/\d+\.\d+\s+200\s*} =~ proxy_status_line
            while line = os.gets(LF)
              break if /\A(#{CRLF}|#{LF})\z/om =~ line
            end
          else
            raise HTTPStatus::BadGateway
          end
        end
        @logger.debug("CONNECT #{host}:#{port}: succeeded")
        res.status = HTTPStatus::RC_OK
      rescue => ex
        @logger.debug("CONNECT #{host}:#{port}: failed `#{ex.message}'")
        res.set_error(ex)
        raise HTTPStatus::EOFError
      ensure
        if handler = @config[:ProxyContentHandler]
          handler.call(req, res)
        end
        res.send_response(ua)
        access_log(@config, req, res)

        # Should clear request-line not to send the sesponse twice.
        # see: HTTPServer#run
        req.parse(NullReader) rescue nil
      end

      begin
        while fds = IO::select([ua, os])
          if fds[0].member?(ua)
            buf = ua.sysread(1024);
            @logger.debug("CONNECT: #{buf.size} byte from User-Agent")
            os.syswrite(buf)
          elsif fds[0].member?(os)
            buf = os.sysread(1024);
            @logger.debug("CONNECT: #{buf.size} byte from #{host}:#{port}")
            ua.syswrite(buf)
          end
        end
      rescue => ex
        os.close
        @logger.debug("CONNECT #{host}:#{port}: closed")
      end

      raise HTTPStatus::EOFError
    end

    def do_OPTIONS(req, res)
      res['allow'] = "GET,HEAD,POST,OPTIONS,CONNECT"
    end
  end
end
PK     pY\O-      webrick/accesslog.rbnu [        #
# accesslog.rb -- Access log handling utilities
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2002 keita yamaguchi
# Copyright (c) 2002 Internet Programming with Ruby writers
#
# $IPR: accesslog.rb,v 1.1 2002/10/01 17:16:32 gotoyuzo Exp $

module WEBrick
  module AccessLog
    class AccessLogError < StandardError; end

    CLF_TIME_FORMAT     = "[%d/%b/%Y:%H:%M:%S %Z]"
    COMMON_LOG_FORMAT   = "%h %l %u %t \"%r\" %s %b"
    CLF                 = COMMON_LOG_FORMAT
    REFERER_LOG_FORMAT  = "%{Referer}i -> %U"
    AGENT_LOG_FORMAT    = "%{User-Agent}i"
    COMBINED_LOG_FORMAT = "#{CLF} \"%{Referer}i\" \"%{User-agent}i\""

    module_function

    # This format specification is a subset of mod_log_config of Apache.
    #   http://httpd.apache.org/docs/mod/mod_log_config.html#formats
    def setup_params(config, req, res)
      params = Hash.new("")
      params["a"] = req.peeraddr[3]
      params["b"] = res.sent_size
      params["e"] = ENV
      params["f"] = res.filename || ""
      params["h"] = req.peeraddr[2]
      params["i"] = req
      params["l"] = "-"
      params["m"] = req.request_method
      params["n"] = req.attributes
      params["o"] = res
      params["p"] = req.port
      params["q"] = req.query_string
      params["r"] = req.request_line.sub(/\x0d?\x0a\z/o, '')
      params["s"] = res.status       # won't support "%>s"
      params["t"] = req.request_time
      params["T"] = Time.now - req.request_time
      params["u"] = req.user || "-"
      params["U"] = req.unparsed_uri
      params["v"] = config[:ServerName]
      params
    end

    def format(format_string, params)
      format_string.gsub(/\%(?:\{(.*?)\})?>?([a-zA-Z%])/){
         param, spec = $1, $2
         case spec[0]
         when ?e, ?i, ?n, ?o
           raise AccessLogError,
             "parameter is required for \"#{spec}\"" unless param
           (param = params[spec][param]) ? escape(param) : "-"
         when ?t
           params[spec].strftime(param || CLF_TIME_FORMAT)
         when ?%
           "%"
         else
           escape(params[spec].to_s)
         end
      }
    end

    def escape(data)
      if data.tainted?
        data.gsub(/[[:cntrl:]\\]+/) {$&.dump[1...-1]}.untaint
      else
        data
      end
    end
  end
end
PK     qY\rO      webrick/server.rbnu [        #
# server.rb -- GenericServer Class
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: server.rb,v 1.62 2003/07/22 19:20:43 gotoyuzo Exp $

require 'thread'
require 'socket'
require 'timeout'
require 'webrick/config'
require 'webrick/log'

module WEBrick

  class ServerError < StandardError; end

  class SimpleServer
    def SimpleServer.start
      yield
    end
  end

  class Daemon
    def Daemon.start
      exit!(0) if fork
      Process::setsid
      exit!(0) if fork
      Dir::chdir("/")
      File::umask(0)
      STDIN.reopen("/dev/null")
      STDOUT.reopen("/dev/null", "w")
      STDERR.reopen("/dev/null", "w")
      yield if block_given?
    end
  end

  class GenericServer
    attr_reader :status, :config, :logger, :tokens, :listeners

    def initialize(config={}, default=Config::General)
      @config = default.dup.update(config)
      @status = :Stop
      @config[:Logger] ||= Log::new
      @logger = @config[:Logger]

      @tokens = SizedQueue.new(@config[:MaxClients])
      @config[:MaxClients].times{ @tokens.push(nil) }

      webrickv = WEBrick::VERSION
      rubyv = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
      @logger.info("WEBrick #{webrickv}")
      @logger.info("ruby #{rubyv}")

      @listeners = []
      unless @config[:DoNotListen]
        if @config[:Listen]
          warn(":Listen option is deprecated; use GenericServer#listen")
        end
        listen(@config[:BindAddress], @config[:Port])
        if @config[:Port] == 0
          @config[:Port] = @listeners[0].addr[1]
        end
      end
    end

    def [](key)
      @config[key]
    end

    def listen(address, port)
      @listeners += Utils::create_listeners(address, port, @logger)
    end

    def start(&block)
      raise ServerError, "already started." if @status != :Stop
      server_type = @config[:ServerType] || SimpleServer

      server_type.start{
        @logger.info \
          "#{self.class}#start: pid=#{$$} port=#{@config[:Port]}"
        call_callback(:StartCallback)

        thgroup = ThreadGroup.new
        @status = :Running
        while @status == :Running
          begin
            if svrs = IO.select(@listeners, nil, nil, 2.0)
              svrs[0].each{|svr|
                @tokens.pop          # blocks while no token is there.
                if sock = accept_client(svr)
                  th = start_thread(sock, &block)
                  th[:WEBrickThread] = true
                  thgroup.add(th)
                else
                  @tokens.push(nil)
                end
              }
            end
          rescue Errno::EBADF, IOError => ex
            # if the listening socket was closed in GenericServer#shutdown,
            # IO::select raise it.
          rescue Exception => ex
            msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
            @logger.error msg
          end
        end

        @logger.info "going to shutdown ..."
        thgroup.list.each{|th| th.join if th[:WEBrickThread] }
        call_callback(:StopCallback)
        @logger.info "#{self.class}#start done."
        @status = :Stop
      }
    end

    def stop
      if @status == :Running
        @status = :Shutdown
      end
    end

    def shutdown
      stop
      @listeners.each{|s|
        if @logger.debug?
          addr = s.addr
          @logger.debug("close TCPSocket(#{addr[2]}, #{addr[1]})")
        end
        s.close
      }
      @listeners.clear
    end

    def run(sock)
      @logger.fatal "run() must be provided by user."
    end

    private

    def accept_client(svr)
      sock = nil
      begin
        sock = svr.accept
        sock.sync = true
        Utils::set_non_blocking(sock)
        Utils::set_close_on_exec(sock)
      rescue Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPROTO => ex
        # TCP connection was established but RST segment was sent
        # from peer before calling TCPServer#accept.
      rescue Exception => ex
        msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
        @logger.error msg
      end
      return sock
    end

    def start_thread(sock, &block)
      Thread.start{
        begin
          Thread.current[:WEBrickSocket] = sock
          begin
            addr = sock.peeraddr
            @logger.debug "accept: #{addr[3]}:#{addr[1]}"
          rescue SocketError
            @logger.debug "accept: <address unknown>"
            raise
          end
          call_callback(:AcceptCallback, sock)
          block ? block.call(sock) : run(sock)
        rescue Errno::ENOTCONN
          @logger.debug "Errno::ENOTCONN raised"
        rescue ServerError => ex
          msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
          @logger.error msg
        rescue Exception => ex
          @logger.error ex
        ensure
          @tokens.push(nil)
          Thread.current[:WEBrickSocket] = nil
          if addr
            @logger.debug "close: #{addr[3]}:#{addr[1]}"
          else
            @logger.debug "close: <address unknown>"
          end
          sock.close
        end
      }
    end

    def call_callback(callback_name, *args)
      if cb = @config[callback_name]
        cb.call(*args)
      end
    end
  end    # end of GenericServer
end
PK     sY\ɒQ=  =    webrick/httpauth.rbnu [        #
# httpauth.rb -- HTTP access authentication
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: httpauth.rb,v 1.14 2003/07/22 19:20:42 gotoyuzo Exp $

require 'webrick/httpauth/basicauth'
require 'webrick/httpauth/digestauth'
require 'webrick/httpauth/htpasswd'
require 'webrick/httpauth/htdigest'
require 'webrick/httpauth/htgroup'

module WEBrick
  module HTTPAuth
    module_function

    def _basic_auth(req, res, realm, req_field, res_field, err_type, block)
      user = pass = nil
      if /^Basic\s+(.*)/o =~ req[req_field]
        userpass = $1
        user, pass = userpass.unpack("m*")[0].split(":", 2)
      end
      if block.call(user, pass)
        req.user = user
        return
      end
      res[res_field] = "Basic realm=\"#{realm}\""
      raise err_type
    end

    def basic_auth(req, res, realm, &block)
      _basic_auth(req, res, realm, "Authorization", "WWW-Authenticate",
                  HTTPStatus::Unauthorized, block)
    end

    def proxy_basic_auth(req, res, realm, &block)
      _basic_auth(req, res, realm, "Proxy-Authorization", "Proxy-Authenticate",
                  HTTPStatus::ProxyAuthenticationRequired, block)
    end
  end
end
PK     vY\	t8      webrick/ssl.rbnu [        #
# ssl.rb -- SSL/TLS enhancement for GenericServer
#
# Copyright (c) 2003 GOTOU Yuuzou All rights reserved.
# 
# $Id: ssl.rb 29858 2010-11-22 07:21:52Z shyouhei $

require 'webrick'
require 'openssl'

module WEBrick
  module Config
    svrsoft = General[:ServerSoftware]
    osslv = ::OpenSSL::OPENSSL_VERSION.split[1]
    SSL = {
      :ServerSoftware       => "#{svrsoft} OpenSSL/#{osslv}",
      :SSLEnable            => false,
      :SSLCertificate       => nil,
      :SSLPrivateKey        => nil,
      :SSLClientCA          => nil,
      :SSLExtraChainCert    => nil,
      :SSLCACertificateFile => nil,
      :SSLCACertificatePath => nil,
      :SSLCertificateStore  => nil,
      :SSLVerifyClient      => ::OpenSSL::SSL::VERIFY_NONE,
      :SSLVerifyDepth       => nil,
      :SSLVerifyCallback    => nil,   # custom verification
      :SSLTimeout           => nil,
      :SSLOptions           => nil,
      :SSLStartImmediately  => true,
      # Must specify if you use auto generated certificate.
      :SSLCertName          => nil,
      :SSLCertComment       => "Generated by Ruby/OpenSSL"
    }
    General.update(SSL)
  end

  module Utils
    def create_self_signed_cert(bits, cn, comment)
      rsa = OpenSSL::PKey::RSA.new(bits){|p, n|
        case p
        when 0; $stderr.putc "."  # BN_generate_prime
        when 1; $stderr.putc "+"  # BN_generate_prime
        when 2; $stderr.putc "*"  # searching good prime,  
                                  # n = #of try,
                                  # but also data from BN_generate_prime
        when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
                                  # but also data from BN_generate_prime
        else;   $stderr.putc "*"  # BN_generate_prime
        end
      }
      cert = OpenSSL::X509::Certificate.new
      cert.version = 2
      cert.serial = 1
      name = OpenSSL::X509::Name.new(cn)
      cert.subject = name
      cert.issuer = name
      cert.not_before = Time.now
      cert.not_after = Time.now + (365*24*60*60)
      cert.public_key = rsa.public_key

      ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
      ef.issuer_certificate = cert
      cert.extensions = [
        ef.create_extension("basicConstraints","CA:FALSE"),
        ef.create_extension("keyUsage", "keyEncipherment"),
        ef.create_extension("subjectKeyIdentifier", "hash"),
        ef.create_extension("extendedKeyUsage", "serverAuth"),
        ef.create_extension("nsComment", comment),
      ]
      aki = ef.create_extension("authorityKeyIdentifier",
                                "keyid:always,issuer:always")
      cert.add_extension(aki)
      cert.sign(rsa, OpenSSL::Digest::SHA1.new)

      return [ cert, rsa ]
    end
    module_function :create_self_signed_cert
  end

  class GenericServer
    def ssl_context
      @ssl_context ||= nil
    end

    def listen(address, port)
      listeners = Utils::create_listeners(address, port, @logger)
      if @config[:SSLEnable]
        unless ssl_context
          @ssl_context = setup_ssl_context(@config)
          @logger.info("\n" + @config[:SSLCertificate].to_text) 
        end
        listeners.collect!{|svr|
          ssvr = ::OpenSSL::SSL::SSLServer.new(svr, ssl_context)
          ssvr.start_immediately = @config[:SSLStartImmediately]
          ssvr
        }
      end
      @listeners += listeners
    end

    def setup_ssl_context(config)
      unless config[:SSLCertificate]
        cn = config[:SSLCertName]
        comment = config[:SSLCertComment]
        cert, key = Utils::create_self_signed_cert(1024, cn, comment)
        config[:SSLCertificate] = cert
        config[:SSLPrivateKey] = key
      end
      ctx = OpenSSL::SSL::SSLContext.new
      ctx.key = config[:SSLPrivateKey]
      ctx.cert = config[:SSLCertificate]
      ctx.client_ca = config[:SSLClientCA]
      ctx.extra_chain_cert = config[:SSLExtraChainCert]
      ctx.ca_file = config[:SSLCACertificateFile]
      ctx.ca_path = config[:SSLCACertificatePath]
      ctx.cert_store = config[:SSLCertificateStore]
      ctx.verify_mode = config[:SSLVerifyClient]
      ctx.verify_depth = config[:SSLVerifyDepth]
      ctx.verify_callback = config[:SSLVerifyCallback]
      ctx.timeout = config[:SSLTimeout]
      ctx.options = config[:SSLOptions]
      ctx
    end
  end
end
PK     vY\=%w      webrick/config.rbnu [        #
# config.rb -- Default configurations.
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: config.rb,v 1.52 2003/07/22 19:20:42 gotoyuzo Exp $

require 'webrick/version'
require 'webrick/httpversion'
require 'webrick/httputils'
require 'webrick/utils'
require 'webrick/log'

module WEBrick
  module Config
    LIBDIR = File::dirname(__FILE__)

    # for GenericServer
    General = {
      :ServerName     => Utils::getservername,
      :BindAddress    => nil,   # "0.0.0.0" or "::" or nil
      :Port           => nil,   # users MUST specifiy this!!
      :MaxClients     => 100,   # maximum number of the concurrent connections
      :ServerType     => nil,   # default: WEBrick::SimpleServer
      :Logger         => nil,   # default: WEBrick::Log.new
      :ServerSoftware => "WEBrick/#{WEBrick::VERSION} " +
                         "(Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})",
      :TempDir        => ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'/tmp',
      :DoNotListen    => false,
      :StartCallback  => nil,
      :StopCallback   => nil,
      :AcceptCallback => nil,
    }

    # for HTTPServer, HTTPRequest, HTTPResponse ...
    HTTP = General.dup.update(
      :Port           => 80,
      :RequestTimeout => 30,
      :HTTPVersion    => HTTPVersion.new("1.1"),
      :AccessLog      => nil,
      :MimeTypes      => HTTPUtils::DefaultMimeTypes,
      :DirectoryIndex => ["index.html","index.htm","index.cgi","index.rhtml"],
      :DocumentRoot   => nil,
      :DocumentRootOptions => { :FancyIndexing => true },
      :RequestHandler => nil,
      :RequestCallback => nil,  # alias of :RequestHandler
      :ServerAlias    => nil,

      # for HTTPProxyServer
      :ProxyAuthProc  => nil,
      :ProxyContentHandler => nil,
      :ProxyVia       => true,
      :ProxyTimeout   => true,
      :ProxyURI       => nil,

      :CGIInterpreter => nil,
      :CGIPathEnv     => nil,

      # workaround: if Request-URIs contain 8bit chars,
      # they should be escaped before calling of URI::parse().
      :Escape8bitURI  => false
    )

    FileHandler = {
      :NondisclosureName => [".ht*", "*~"],
      :FancyIndexing     => false,
      :HandlerTable      => {},
      :HandlerCallback   => nil,
      :DirectoryCallback => nil,
      :FileCallback      => nil,
      :UserDir           => nil,  # e.g. "public_html"
      :AcceptableLanguages => []  # ["en", "ja", ... ]
    }

    BasicAuth = {
      :AutoReloadUserDB     => true,
    }

    DigestAuth = {
      :Algorithm            => 'MD5-sess', # or 'MD5' 
      :Domain               => nil,        # an array includes domain names.
      :Qop                  => [ 'auth' ], # 'auth' or 'auth-int' or both.
      :UseOpaque            => true,
      :UseNextNonce         => false,
      :CheckNc              => false,
      :UseAuthenticationInfoHeader => true,
      :AutoReloadUserDB     => true,
      :NonceExpirePeriod    => 30*60,
      :NonceExpireDelta     => 60,
      :InternetExplorerHack => true,
      :OperaHack            => true,
    }
  end
end
PK     xY\n>      webrick/httpservlet.rbnu [        #
# httpservlet.rb -- HTTPServlet Utility File
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: httpservlet.rb,v 1.21 2003/02/23 12:24:46 gotoyuzo Exp $

require 'webrick/httpservlet/abstract'
require 'webrick/httpservlet/filehandler'
require 'webrick/httpservlet/cgihandler'
require 'webrick/httpservlet/erbhandler'
require 'webrick/httpservlet/prochandler'

module WEBrick
  module HTTPServlet
    FileHandler.add_handler("cgi", CGIHandler)
    FileHandler.add_handler("rhtml", ERBHandler)
  end
end
PK     yY\`      webrick/httpservlet/abstract.rbnu [        #
# httpservlet.rb -- HTTPServlet Module
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: abstract.rb,v 1.24 2003/07/11 11:16:46 gotoyuzo Exp $

require 'thread'

require 'webrick/htmlutils'
require 'webrick/httputils'
require 'webrick/httpstatus'

module WEBrick
  module HTTPServlet
    class HTTPServletError < StandardError; end

    class AbstractServlet
      def self.get_instance(config, *options)
        self.new(config, *options)
      end

      def initialize(server, *options)
        @server = @config = server
        @logger = @server[:Logger]
        @options = options
      end

      def service(req, res)
        method_name = "do_" + req.request_method.gsub(/-/, "_")
        if respond_to?(method_name)
          __send__(method_name, req, res)
        else
          raise HTTPStatus::MethodNotAllowed,
                "unsupported method `#{req.request_method}'."
        end
      end

      def do_GET(req, res)
        raise HTTPStatus::NotFound, "not found."
      end

      def do_HEAD(req, res)
        do_GET(req, res)
      end

      def do_OPTIONS(req, res)
        m = self.methods.grep(/^do_[A-Z]+$/)
        m.collect!{|i| i.sub(/do_/, "") }
        m.sort!
        res["allow"] = m.join(",")
      end

      private

      def redirect_to_directory_uri(req, res)
        if req.path[-1] != ?/
          location = WEBrick::HTTPUtils.escape_path(req.path + "/")
          if req.query_string && req.query_string.size > 0
            location << "?" << req.query_string
          end
          res.set_redirect(HTTPStatus::MovedPermanently, location)
        end
      end
    end

  end
end
PK     yY\Bh    "  webrick/httpservlet/prochandler.rbnu [        # 
# prochandler.rb -- ProcHandler Class
#       
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#   
# $IPR: prochandler.rb,v 1.7 2002/09/21 12:23:42 gotoyuzo Exp $

require 'webrick/httpservlet/abstract.rb'

module WEBrick
  module HTTPServlet

    class ProcHandler < AbstractServlet
      def get_instance(server, *options)
        self
      end  

      def initialize(proc)
        @proc = proc
      end

      def do_GET(request, response)
        @proc.call(request, response)
      end

      alias do_POST do_GET
    end

  end
end
PK     zY\8iɚ    !  webrick/httpservlet/erbhandler.rbnu [        # 
# erbhandler.rb -- ERBHandler Class
# 
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
# 
# $IPR: erbhandler.rb,v 1.25 2003/02/24 19:25:31 gotoyuzo Exp $

require 'webrick/httpservlet/abstract.rb'

require 'erb'

module WEBrick
  module HTTPServlet

    class ERBHandler < AbstractServlet
      def initialize(server, name)
        super
        @script_filename = name
      end

      def do_GET(req, res)
        unless defined?(ERB)
          @logger.warn "#{self.class}: ERB not defined."
          raise HTTPStatus::Forbidden, "ERBHandler cannot work."
        end
        begin
          data = open(@script_filename){|io| io.read }
          res.body = evaluate(ERB.new(data), req, res)
          res['content-type'] =
            HTTPUtils::mime_type(@script_filename, @config[:MimeTypes])
        rescue StandardError => ex
          raise
        rescue Exception => ex
          @logger.error(ex)
          raise HTTPStatus::InternalServerError, ex.message
        end
      end

      alias do_POST do_GET

      private
      def evaluate(erb, servlet_request, servlet_response)
        Module.new.module_eval{
          meta_vars = servlet_request.meta_vars
          query = servlet_request.query
          erb.result(binding)
        }
      end
    end
  end
end
PK     zY\XgV    !  webrick/httpservlet/cgihandler.rbnu [        # 
# cgihandler.rb -- CGIHandler Class
#       
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#   
# $IPR: cgihandler.rb,v 1.27 2003/03/21 19:56:01 gotoyuzo Exp $

require 'rbconfig'
require 'tempfile'
require 'webrick/config'
require 'webrick/httpservlet/abstract'

module WEBrick
  module HTTPServlet

    class CGIHandler < AbstractServlet
      Ruby = File::join(::Config::CONFIG['bindir'],
                        ::Config::CONFIG['ruby_install_name'])
      Ruby << ::Config::CONFIG['EXEEXT']
      CGIRunner = "\"#{Ruby}\" \"#{Config::LIBDIR}/httpservlet/cgi_runner.rb\""

      def initialize(server, name)
        super
        @script_filename = name
        @tempdir = server[:TempDir]
        @cgicmd = "#{CGIRunner} #{server[:CGIInterpreter]}"
      end

      def do_GET(req, res)
        data = nil
        status = -1

        cgi_in = IO::popen(@cgicmd, "wb")
        cgi_out = Tempfile.new("webrick.cgiout.", @tempdir)
        cgi_err = Tempfile.new("webrick.cgierr.", @tempdir)
        begin
          cgi_in.sync = true
          meta = req.meta_vars
          meta["SCRIPT_FILENAME"] = @script_filename
          meta["PATH"] = @config[:CGIPathEnv]
          if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
            meta["SystemRoot"] = ENV["SystemRoot"]
          end
          dump = Marshal.dump(meta)

          cgi_in.write("%8d" % cgi_out.path.size)
          cgi_in.write(cgi_out.path)
          cgi_in.write("%8d" % cgi_err.path.size)
          cgi_in.write(cgi_err.path)
          cgi_in.write("%8d" % dump.size)
          cgi_in.write(dump)

          if req.body and req.body.size > 0
            cgi_in.write(req.body)
          end
        ensure
          cgi_in.close
          status = $?.exitstatus
          sleep 0.1 if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
          data = cgi_out.read
          cgi_out.close(true)
          if errmsg = cgi_err.read
            if errmsg.size > 0
              @logger.error("CGIHandler: #{@script_filename}:\n" + errmsg)
            end
          end 
          cgi_err.close(true)
        end
        
        if status != 0
          @logger.error("CGIHandler: #{@script_filename} exit with #{status}")
        end

        data = "" unless data
        raw_header, body = data.split(/^[\xd\xa]+/on, 2) 
        raise HTTPStatus::InternalServerError,
          "Premature end of script headers: #{@script_filename}" if body.nil?

        begin
          header = HTTPUtils::parse_header(raw_header)
          if /^(\d+)/ =~ header['status'][0]
            res.status = $1.to_i
            header.delete('status')
          end
          if header.has_key?('location')
            # RFC 3875 6.2.3, 6.2.4
            res.status = 302 unless (300...400) === res.status
          end
          if header.has_key?('set-cookie')
            header['set-cookie'].each{|k|
              res.cookies << Cookie.parse_set_cookie(k)
            }
            header.delete('set-cookie')
          end
          header.each{|key, val| res[key] = val.join(", ") }
        rescue => ex
          raise HTTPStatus::InternalServerError, ex.message
        end
        res.body = body
      end
      alias do_POST do_GET
    end

  end
end
PK     {Y\'6  6  "  webrick/httpservlet/filehandler.rbnu [        #
# filehandler.rb -- FileHandler Module
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: filehandler.rb,v 1.44 2003/06/07 01:34:51 gotoyuzo Exp $

require 'thread'
require 'time'

require 'webrick/htmlutils'
require 'webrick/httputils'
require 'webrick/httpstatus'

module WEBrick
  module HTTPServlet

    class DefaultFileHandler < AbstractServlet
      def initialize(server, local_path)
        super
        @local_path = local_path
      end

      def do_GET(req, res)
        st = File::stat(@local_path)
        mtime = st.mtime
        res['etag'] = sprintf("%x-%x-%x", st.ino, st.size, st.mtime.to_i)

        if not_modified?(req, res, mtime, res['etag'])
          res.body = ''
          raise HTTPStatus::NotModified
        elsif req['range'] 
          make_partial_content(req, res, @local_path, st.size)
          raise HTTPStatus::PartialContent
        else
          mtype = HTTPUtils::mime_type(@local_path, @config[:MimeTypes])
          res['content-type'] = mtype
          res['content-length'] = st.size
          res['last-modified'] = mtime.httpdate
          res.body = open(@local_path, "rb")
        end
      end

      def not_modified?(req, res, mtime, etag)
        if ir = req['if-range']
          begin
            if Time.httpdate(ir) >= mtime
              return true
            end
          rescue
            if HTTPUtils::split_header_value(ir).member?(res['etag'])
              return true
            end
          end
        end

        if (ims = req['if-modified-since']) && Time.parse(ims) >= mtime
          return true
        end

        if (inm = req['if-none-match']) &&
           HTTPUtils::split_header_value(inm).member?(res['etag'])
          return true
        end

        return false
      end

      def make_partial_content(req, res, filename, filesize)
        mtype = HTTPUtils::mime_type(filename, @config[:MimeTypes])
        unless ranges = HTTPUtils::parse_range_header(req['range'])
          raise HTTPStatus::BadRequest,
            "Unrecognized range-spec: \"#{req['range']}\""
        end
        open(filename, "rb"){|io|
          if ranges.size > 1
            time = Time.now
            boundary = "#{time.sec}_#{time.usec}_#{Process::pid}"
            body = ''
            ranges.each{|range|
              first, last = prepare_range(range, filesize)
              next if first < 0
              io.pos = first
              content = io.read(last-first+1)
              body << "--" << boundary << CRLF
              body << "Content-Type: #{mtype}" << CRLF
              body << "Content-Range: bytes #{first}-#{last}/#{filesize}" << CRLF
              body << CRLF
              body << content
              body << CRLF
            }
            raise HTTPStatus::RequestRangeNotSatisfiable if body.empty?
            body << "--" << boundary << "--" << CRLF
            res["content-type"] = "multipart/byteranges; boundary=#{boundary}"
            res.body = body
          elsif range = ranges[0]
            first, last = prepare_range(range, filesize)
            raise HTTPStatus::RequestRangeNotSatisfiable if first < 0
            if last == filesize - 1
              content = io.dup
              content.pos = first
            else
              io.pos = first
              content = io.read(last-first+1)
            end
            res['content-type'] = mtype
            res['content-range'] = "bytes #{first}-#{last}/#{filesize}"
            res['content-length'] = last - first + 1
            res.body = content
          else
            raise HTTPStatus::BadRequest
          end
        }
      end

      def prepare_range(range, filesize)
        first = range.first < 0 ? filesize + range.first : range.first
        return -1, -1 if first < 0 || first >= filesize
        last = range.last < 0 ? filesize + range.last : range.last
        last = filesize - 1 if last >= filesize
        return first, last
      end
    end

    class FileHandler < AbstractServlet
      HandlerTable = Hash.new

      def self.add_handler(suffix, handler)
        HandlerTable[suffix] = handler
      end

      def self.remove_handler(suffix)
        HandlerTable.delete(suffix)
      end

      def initialize(server, root, options={}, default=Config::FileHandler)
        @config = server.config
        @logger = @config[:Logger]
        @root = File.expand_path(root)
        if options == true || options == false
          options = { :FancyIndexing => options }
        end
        @options = default.dup.update(options)
      end

      def service(req, res)
        # if this class is mounted on "/" and /~username is requested.
        # we're going to override path informations before invoking service.
        if defined?(Etc) && @options[:UserDir] && req.script_name.empty?
          if %r|^(/~([^/]+))| =~ req.path_info
            script_name, user = $1, $2
            path_info = $'
            begin
              passwd = Etc::getpwnam(user)
              @root = File::join(passwd.dir, @options[:UserDir])
              req.script_name = script_name
              req.path_info = path_info
            rescue
              @logger.debug "#{self.class}#do_GET: getpwnam(#{user}) failed"
            end
          end
        end
        prevent_directory_traversal(req, res)
        super(req, res)
      end

      def do_GET(req, res)
        unless exec_handler(req, res)
          set_dir_list(req, res)
        end
      end

      def do_POST(req, res)
        unless exec_handler(req, res)
          raise HTTPStatus::NotFound, "`#{req.path}' not found."
        end
      end

      def do_OPTIONS(req, res)
        unless exec_handler(req, res)
          super(req, res)
        end
      end

      # ToDo
      # RFC2518: HTTP Extensions for Distributed Authoring -- WEBDAV
      #
      # PROPFIND PROPPATCH MKCOL DELETE PUT COPY MOVE
      # LOCK UNLOCK

      # RFC3253: Versioning Extensions to WebDAV
      #          (Web Distributed Authoring and Versioning)
      #
      # VERSION-CONTROL REPORT CHECKOUT CHECK_IN UNCHECKOUT
      # MKWORKSPACE UPDATE LABEL MERGE ACTIVITY

      private

      def trailing_pathsep?(path)
        # check for trailing path separator:
        #   File.dirname("/aaaa/bbbb/")      #=> "/aaaa")
        #   File.dirname("/aaaa/bbbb/x")     #=> "/aaaa/bbbb")
        #   File.dirname("/aaaa/bbbb")       #=> "/aaaa")
        #   File.dirname("/aaaa/bbbbx")      #=> "/aaaa")
        return File.dirname(path) != File.dirname(path+"x")
      end

      def prevent_directory_traversal(req, res)
        # Preventing directory traversal on Windows platforms;
        # Backslashes (0x5c) in path_info are not interpreted as special
        # character in URI notation. So the value of path_info should be
        # normalize before accessing to the filesystem.

        if trailing_pathsep?(req.path_info)
          # File.expand_path removes the trailing path separator.
          # Adding a character is a workaround to save it.
          #  File.expand_path("/aaa/")        #=> "/aaa"
          #  File.expand_path("/aaa/" + "x")  #=> "/aaa/x"
          expanded = File.expand_path(req.path_info + "x")
          expanded.chop!  # remove trailing "x"
        else
          expanded = File.expand_path(req.path_info)
        end
        req.path_info = expanded
      end

      def exec_handler(req, res)
        raise HTTPStatus::NotFound, "`#{req.path}' not found" unless @root
        if set_filename(req, res)
          handler = get_handler(req, res)
          call_callback(:HandlerCallback, req, res)
          h = handler.get_instance(@config, res.filename)
          h.service(req, res)
          return true
        end
        call_callback(:HandlerCallback, req, res)
        return false
      end

      def get_handler(req, res)
        suffix1 = (/\.(\w+)\z/ =~ res.filename) && $1.downcase
        if /\.(\w+)\.([\w\-]+)\z/ =~ res.filename
          if @options[:AcceptableLanguages].include?($2.downcase)
            suffix2 = $1.downcase
          end
        end
        handler_table = @options[:HandlerTable]
        return handler_table[suffix1] || handler_table[suffix2] ||
               HandlerTable[suffix1] || HandlerTable[suffix2] ||
               DefaultFileHandler
      end

      def set_filename(req, res)
        res.filename = @root.dup
        path_info = req.path_info.scan(%r|/[^/]*|)

        path_info.unshift("")  # dummy for checking @root dir
        while base = path_info.first
          break if base == "/"
          break unless File.directory?(File.expand_path(res.filename + base))
          shift_path_info(req, res, path_info)
          call_callback(:DirectoryCallback, req, res)
        end

        if base = path_info.first
          if base == "/"
            if file = search_index_file(req, res)
              shift_path_info(req, res, path_info, file)
              call_callback(:FileCallback, req, res)
              return true
            end
            shift_path_info(req, res, path_info)
          elsif file = search_file(req, res, base)
            shift_path_info(req, res, path_info, file)
            call_callback(:FileCallback, req, res)
            return true
          else
            raise HTTPStatus::NotFound, "`#{req.path}' not found."
          end
        end

        return false
      end

      def check_filename(req, res, name)
        if nondisclosure_name?(name) || windows_ambiguous_name?(name)
          @logger.warn("the request refers nondisclosure name `#{name}'.")
          raise HTTPStatus::NotFound, "`#{req.path}' not found."
        end
      end

      def shift_path_info(req, res, path_info, base=nil)
        tmp = path_info.shift
        base = base || tmp
        req.path_info = path_info.join
        req.script_name << base
        res.filename = File.expand_path(res.filename + base)
        check_filename(req, res, File.basename(res.filename))
      end

      def search_index_file(req, res)
        @config[:DirectoryIndex].each{|index|
          if file = search_file(req, res, "/"+index)
            return file
          end
        }
        return nil
      end

      def search_file(req, res, basename)
        langs = @options[:AcceptableLanguages]
        path = res.filename + basename
        if File.file?(path)
          return basename
        elsif langs.size > 0
          req.accept_language.each{|lang|
            path_with_lang = path + ".#{lang}"
            if langs.member?(lang) && File.file?(path_with_lang)
              return basename + ".#{lang}"
            end
          }
          (langs - req.accept_language).each{|lang|
            path_with_lang = path + ".#{lang}"
            if File.file?(path_with_lang)
              return basename + ".#{lang}"
            end
          }
        end
        return nil
      end

      def call_callback(callback_name, req, res)
        if cb = @options[callback_name]
          cb.call(req, res)
        end
      end

      def windows_ambiguous_name?(name)
        return true if /[. ]+\z/ =~ name
        return true if /::\$DATA\z/ =~ name
        return false
      end

      def nondisclosure_name?(name)
        @options[:NondisclosureName].each{|pattern|
          if File.fnmatch(pattern, name, File::FNM_CASEFOLD)
            return true
          end
        }
        return false
      end

      def set_dir_list(req, res)
        redirect_to_directory_uri(req, res)
        unless @options[:FancyIndexing]
          raise HTTPStatus::Forbidden, "no access permission to `#{req.path}'"
        end
        local_path = res.filename
        list = Dir::entries(local_path).collect{|name|
          next if name == "." || name == ".."
          next if nondisclosure_name?(name)
          next if windows_ambiguous_name?(name)
          st = (File::stat(File.join(local_path, name)) rescue nil)
          if st.nil?
            [ name, nil, -1 ]
          elsif st.directory?
            [ name + "/", st.mtime, -1 ]
          else
            [ name, st.mtime, st.size ]
          end
        }
        list.compact!

        if    d0 = req.query["N"]; idx = 0
        elsif d0 = req.query["M"]; idx = 1
        elsif d0 = req.query["S"]; idx = 2
        else  d0 = "A"           ; idx = 0
        end
        d1 = (d0 == "A") ? "D" : "A"

        if d0 == "A"
          list.sort!{|a,b| a[idx] <=> b[idx] }
        else
          list.sort!{|a,b| b[idx] <=> a[idx] }
        end

        res['content-type'] = "text/html"

        res.body = <<-_end_of_html_
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
  <HEAD><TITLE>Index of #{HTMLUtils::escape(req.path)}</TITLE></HEAD>
  <BODY>
    <H1>Index of #{HTMLUtils::escape(req.path)}</H1>
        _end_of_html_

        res.body << "<PRE>\n"
        res.body << " <A HREF=\"?N=#{d1}\">Name</A>                          "
        res.body << "<A HREF=\"?M=#{d1}\">Last modified</A>         "
        res.body << "<A HREF=\"?S=#{d1}\">Size</A>\n"
        res.body << "<HR>\n"
       
        list.unshift [ "..", File::mtime(local_path+"/.."), -1 ]
        list.each{ |name, time, size|
          if name == ".."
            dname = "Parent Directory"
          elsif name.size > 25
            dname = name.sub(/^(.{23})(.*)/){ $1 + ".." }
          else
            dname = name
          end
          s =  " <A HREF=\"#{HTTPUtils::escape(name)}\">#{dname}</A>"
          s << " " * (30 - dname.size)
          s << (time ? time.strftime("%Y/%m/%d %H:%M      ") : " " * 22)
          s << (size >= 0 ? size.to_s : "-") << "\n"
          res.body << s
        }
        res.body << "</PRE><HR>"

        res.body << <<-_end_of_html_    
    <ADDRESS>
     #{HTMLUtils::escape(@config[:ServerSoftware])}<BR>
     at #{req.host}:#{req.port}
    </ADDRESS>
  </BODY>
</HTML>
        _end_of_html_
      end

    end
  end
end
PK     {Y\-!    !  webrick/httpservlet/cgi_runner.rbnu [        #
# cgi_runner.rb -- CGI launcher.
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: cgi_runner.rb,v 1.9 2002/09/25 11:33:15 gotoyuzo Exp $

def sysread(io, size)
  buf = ""
  while size > 0
    tmp = io.sysread(size)
    buf << tmp
    size -= tmp.size
  end
  return buf
end

STDIN.binmode

buf = ""
len = sysread(STDIN, 8).to_i
out = sysread(STDIN, len)
STDOUT.reopen(open(out, "w"))

len = sysread(STDIN, 8).to_i
err = sysread(STDIN, len)
STDERR.reopen(open(err, "w"))

len  = sysread(STDIN, 8).to_i
dump = sysread(STDIN, len)
hash = Marshal.restore(dump)
ENV.keys.each{|name| ENV.delete(name) }
hash.each{|k, v| ENV[k] = v if v }

dir = File::dirname(ENV["SCRIPT_FILENAME"])
Dir::chdir dir

if interpreter = ARGV[0]
  argv = ARGV.dup
  argv << ENV["SCRIPT_FILENAME"]
  exec(*argv)
  # NOTREACHED
end
exec ENV["SCRIPT_FILENAME"]
PK     |Y\6f|u      webrick/compat.rbnu [        #
# compat.rb -- cross platform compatibility
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2002 GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: compat.rb,v 1.6 2002/10/01 17:16:32 gotoyuzo Exp $

module Errno
  class EPROTO       < SystemCallError; end
  class ECONNRESET   < SystemCallError; end
  class ECONNABORTED < SystemCallError; end
end
PK     Y\9
E	  E	  !  webrick/httpauth/authenticator.rbnu [        #
# httpauth/authenticator.rb -- Authenticator mix-in module.
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: authenticator.rb,v 1.3 2003/02/20 07:15:47 gotoyuzo Exp $

module WEBrick
  module HTTPAuth
    module Authenticator
      RequestField      = "Authorization"
      ResponseField     = "WWW-Authenticate"
      ResponseInfoField = "Authentication-Info"
      AuthException     = HTTPStatus::Unauthorized
      AuthScheme        = nil # must override by the derived class

      attr_reader :realm, :userdb, :logger

      private

      def check_init(config)
        [:UserDB, :Realm].each{|sym|
          unless config[sym]
            raise ArgumentError, "Argument #{sym.inspect} missing."
          end
        } 
        @realm     = config[:Realm]
        @userdb    = config[:UserDB]
        @logger    = config[:Logger] || Log::new($stderr)
        @reload_db = config[:AutoReloadUserDB]
        @request_field   = self::class::RequestField
        @response_field  = self::class::ResponseField
        @resp_info_field = self::class::ResponseInfoField
        @auth_exception  = self::class::AuthException
        @auth_scheme     = self::class::AuthScheme
      end

      def check_scheme(req)
        unless credentials = req[@request_field]
          error("no credentials in the request.")
          return nil 
        end  
        unless match = /^#{@auth_scheme}\s+/.match(credentials)
          error("invalid scheme in %s.", credentials)
          info("%s: %s", @request_field, credentials) if $DEBUG
          return nil
        end
        return match.post_match
      end

      def log(meth, fmt, *args)
        msg = format("%s %s: ", @auth_scheme, @realm)
        msg << fmt % args
        @logger.send(meth, msg)
      end

      def error(fmt, *args)
        if @logger.error?
          log(:error, fmt, *args)
        end
      end                             

      def info(fmt, *args)
        if @logger.info?
          log(:info, fmt, *args)
        end
      end
    end

    module ProxyAuthenticator
      RequestField  = "Proxy-Authorization"
      ResponseField = "Proxy-Authenticate"
      InfoField     = "Proxy-Authentication-Info"
      AuthException = HTTPStatus::ProxyAuthenticationRequired
    end
  end
end
PK     Y\x{,  ,    webrick/httpauth/digestauth.rbnu [        #
# httpauth/digestauth.rb -- HTTP digest access authentication
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2003 Internet Programming with Ruby writers.
# Copyright (c) 2003 H.M.
#
# The original implementation is provided by H.M.
#   URL: http://rwiki.jin.gr.jp/cgi-bin/rw-cgi.rb?cmd=view;name=
#        %C7%A7%BE%DA%B5%A1%C7%BD%A4%F2%B2%FE%C2%A4%A4%B7%A4%C6%A4%DF%A4%EB
#
# $IPR: digestauth.rb,v 1.5 2003/02/20 07:15:47 gotoyuzo Exp $

require 'webrick/config'
require 'webrick/httpstatus'
require 'webrick/httpauth/authenticator'
require 'digest/md5'
require 'digest/sha1'

module WEBrick
  module HTTPAuth
    class DigestAuth
      include Authenticator

      AuthScheme = "Digest"
      OpaqueInfo = Struct.new(:time, :nonce, :nc)
      attr_reader :algorithm, :qop

      def self.make_passwd(realm, user, pass)
        pass ||= ""
        Digest::MD5::hexdigest([user, realm, pass].join(":"))
      end

      def initialize(config, default=Config::DigestAuth)
        check_init(config)
        @config                 = default.dup.update(config)
        @algorithm              = @config[:Algorithm]
        @domain                 = @config[:Domain]
        @qop                    = @config[:Qop]
        @use_opaque             = @config[:UseOpaque]
        @use_next_nonce         = @config[:UseNextNonce]
        @check_nc               = @config[:CheckNc]
        @use_auth_info_header   = @config[:UseAuthenticationInfoHeader]
        @nonce_expire_period    = @config[:NonceExpirePeriod]
        @nonce_expire_delta     = @config[:NonceExpireDelta]
        @internet_explorer_hack = @config[:InternetExplorerHack]
        @opera_hack             = @config[:OperaHack]

        case @algorithm
        when 'MD5','MD5-sess'
          @h = Digest::MD5
        when 'SHA1','SHA1-sess'  # it is a bonus feature :-)
          @h = Digest::SHA1
        else
          msg = format('Alogrithm "%s" is not supported.', @algorithm)
          raise ArgumentError.new(msg)
        end

        @instance_key = hexdigest(self.__id__, Time.now.to_i, Process.pid)
        @opaques = {}
        @last_nonce_expire = Time.now
        @mutex = Mutex.new
      end

      def authenticate(req, res)
        unless result = @mutex.synchronize{ _authenticate(req, res) }
          challenge(req, res)
        end
        if result == :nonce_is_stale
          challenge(req, res, true)
        end
        return true
      end

      def challenge(req, res, stale=false)
        nonce = generate_next_nonce(req)
        if @use_opaque
          opaque = generate_opaque(req)
          @opaques[opaque].nonce = nonce
        end

        param = Hash.new
        param["realm"]  = HTTPUtils::quote(@realm)
        param["domain"] = HTTPUtils::quote(@domain.to_a.join(" ")) if @domain
        param["nonce"]  = HTTPUtils::quote(nonce)
        param["opaque"] = HTTPUtils::quote(opaque) if opaque
        param["stale"]  = stale.to_s
        param["algorithm"] = @algorithm
        param["qop"]    = HTTPUtils::quote(@qop.to_a.join(",")) if @qop

        res[@response_field] =
          "#{@auth_scheme} " + param.map{|k,v| "#{k}=#{v}" }.join(", ")
        info("%s: %s", @response_field, res[@response_field]) if $DEBUG
        raise @auth_exception
      end

      private

      MustParams = ['username','realm','nonce','uri','response']
      MustParamsAuth = ['cnonce','nc']

      def _authenticate(req, res)
        unless digest_credentials = check_scheme(req)
          return false
        end

        auth_req = split_param_value(digest_credentials)
        if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
          req_params = MustParams + MustParamsAuth
        else
          req_params = MustParams
        end
        req_params.each{|key|
          unless auth_req.has_key?(key)
            error('%s: parameter missing. "%s"', auth_req['username'], key)
            raise HTTPStatus::BadRequest
          end
        }

        if !check_uri(req, auth_req)
          raise HTTPStatus::BadRequest  
        end

        if auth_req['realm'] != @realm  
          error('%s: realm unmatch. "%s" for "%s"',
                auth_req['username'], auth_req['realm'], @realm)
          return false
        end

        auth_req['algorithm'] ||= 'MD5' 
        if auth_req['algorithm'] != @algorithm &&
           (@opera_hack && auth_req['algorithm'] != @algorithm.upcase)
          error('%s: algorithm unmatch. "%s" for "%s"',
                auth_req['username'], auth_req['algorithm'], @algorithm)
          return false
        end

        if (@qop.nil? && auth_req.has_key?('qop')) ||
           (@qop && (! @qop.member?(auth_req['qop'])))
          error('%s: the qop is not allowed. "%s"',
                auth_req['username'], auth_req['qop'])
          return false
        end

        password = @userdb.get_passwd(@realm, auth_req['username'], @reload_db)
        unless password
          error('%s: the user is not allowd.', auth_req['username'])
          return false
        end

        nonce_is_invalid = false
        if @use_opaque
          info("@opaque = %s", @opaque.inspect) if $DEBUG
          if !(opaque = auth_req['opaque'])
            error('%s: opaque is not given.', auth_req['username'])
            nonce_is_invalid = true
          elsif !(opaque_struct = @opaques[opaque])
            error('%s: invalid opaque is given.', auth_req['username'])
            nonce_is_invalid = true
          elsif !check_opaque(opaque_struct, req, auth_req)
            @opaques.delete(auth_req['opaque'])
            nonce_is_invalid = true
          end
        elsif !check_nonce(req, auth_req)
          nonce_is_invalid = true
        end

        if /-sess$/ =~ auth_req['algorithm'] ||
           (@opera_hack && /-SESS$/ =~ auth_req['algorithm'])
          ha1 = hexdigest(password, auth_req['nonce'], auth_req['cnonce'])
        else
          ha1 = password
        end

        if auth_req['qop'] == "auth" || auth_req['qop'] == nil
          ha2 = hexdigest(req.request_method, auth_req['uri'])
          ha2_res = hexdigest("", auth_req['uri'])
        elsif auth_req['qop'] == "auth-int"
          ha2 = hexdigest(req.request_method, auth_req['uri'],
                          hexdigest(req.body))
          ha2_res = hexdigest("", auth_req['uri'], hexdigest(res.body))
        end

        if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
          param2 = ['nonce', 'nc', 'cnonce', 'qop'].map{|key|
            auth_req[key]
          }.join(':')
          digest     = hexdigest(ha1, param2, ha2)
          digest_res = hexdigest(ha1, param2, ha2_res)
        else
          digest     = hexdigest(ha1, auth_req['nonce'], ha2)
          digest_res = hexdigest(ha1, auth_req['nonce'], ha2_res)
        end

        if digest != auth_req['response']
          error("%s: digest unmatch.", auth_req['username'])
          return false
        elsif nonce_is_invalid
          error('%s: digest is valid, but nonce is not valid.',
                auth_req['username'])
          return :nonce_is_stale
        elsif @use_auth_info_header
          auth_info = {
            'nextnonce' => generate_next_nonce(req),
            'rspauth'   => digest_res
          }
          if @use_opaque
            opaque_struct.time  = req.request_time
            opaque_struct.nonce = auth_info['nextnonce']
            opaque_struct.nc    = "%08x" % (auth_req['nc'].hex + 1)
          end
          if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
            ['qop','cnonce','nc'].each{|key|
              auth_info[key] = auth_req[key]
            }
          end
          res[@resp_info_field] = auth_info.keys.map{|key|
            if key == 'nc'
              key + '=' + auth_info[key]
            else
              key + "=" + HTTPUtils::quote(auth_info[key])
            end
          }.join(', ')
        end
        info('%s: authentication scceeded.', auth_req['username'])
        req.user = auth_req['username']
        return true
      end

      def split_param_value(string)
        ret = {}
        while string.size != 0
          case string           
          when /^\s*([\w\-\.\*\%\!]+)=\s*\"((\\.|[^\"])*)\"\s*,?/
            key = $1
            matched = $2
            string = $'
            ret[key] = matched.gsub(/\\(.)/, "\\1")
          when /^\s*([\w\-\.\*\%\!]+)=\s*([^,\"]*),?/
            key = $1
            matched = $2
            string = $'
            ret[key] = matched.clone
          when /^s*^,/
            string = $'
          else
            break
          end
        end
        ret
      end

      def generate_next_nonce(req)
        now = "%012d" % req.request_time.to_i
        pk  = hexdigest(now, @instance_key)[0,32]
        nonce = [now + ":" + pk].pack("m*").chop # it has 60 length of chars.
        nonce
      end

      def check_nonce(req, auth_req)
        username = auth_req['username']
        nonce = auth_req['nonce']

        pub_time, pk = nonce.unpack("m*")[0].split(":", 2)
        if (!pub_time || !pk)
          error("%s: empty nonce is given", username)
          return false
        elsif (hexdigest(pub_time, @instance_key)[0,32] != pk)
          error("%s: invalid private-key: %s for %s",
                username, hexdigest(pub_time, @instance_key)[0,32], pk)
          return false
        end

        diff_time = req.request_time.to_i - pub_time.to_i
        if (diff_time < 0)
          error("%s: difference of time-stamp is negative.", username)
          return false
        elsif diff_time > @nonce_expire_period
          error("%s: nonce is expired.", username)
          return false
        end

        return true
      end

      def generate_opaque(req)
        @mutex.synchronize{
          now = req.request_time
          if now - @last_nonce_expire > @nonce_expire_delta
            @opaques.delete_if{|key,val|
              (now - val.time) > @nonce_expire_period
            }
            @last_nonce_expire = now
          end
          begin
            opaque = Utils::random_string(16)
          end while @opaques[opaque]
          @opaques[opaque] = OpaqueInfo.new(now, nil, '00000001')
          opaque
        }
      end

      def check_opaque(opaque_struct, req, auth_req)
        if (@use_next_nonce && auth_req['nonce'] != opaque_struct.nonce)
          error('%s: nonce unmatched. "%s" for "%s"',
                auth_req['username'], auth_req['nonce'], opaque_struct.nonce)
          return false
        elsif !check_nonce(req, auth_req)
          return false
        end
        if (@check_nc && auth_req['nc'] != opaque_struct.nc)
          error('%s: nc unmatched."%s" for "%s"',
                auth_req['username'], auth_req['nc'], opaque_struct.nc)
          return false
        end
        true
      end

      def check_uri(req, auth_req)
        uri = auth_req['uri']
        if uri != req.request_uri.to_s && uri != req.unparsed_uri &&
           (@internet_explorer_hack && uri != req.path)
          error('%s: uri unmatch. "%s" for "%s"', auth_req['username'], 
                auth_req['uri'], req.request_uri.to_s)
          return false
        end
        true
      end

      def hexdigest(*args)
        @h.hexdigest(args.join(":"))
      end
    end

    class ProxyDigestAuth < DigestAuth
      include ProxyAuthenticator

      def check_uri(req, auth_req)
        return true
      end
    end
  end
end
PK     Y\^      webrick/httpauth/basicauth.rbnu [        #
# httpauth/basicauth.rb -- HTTP basic access authentication
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: basicauth.rb,v 1.5 2003/02/20 07:15:47 gotoyuzo Exp $

require 'webrick/config'
require 'webrick/httpstatus'
require 'webrick/httpauth/authenticator'

module WEBrick
  module HTTPAuth
    class BasicAuth
      include Authenticator

      AuthScheme = "Basic"

      def self.make_passwd(realm, user, pass)
        pass ||= ""
        pass.crypt(Utils::random_string(2))
      end

      attr_reader :realm, :userdb, :logger

      def initialize(config, default=Config::BasicAuth)
        check_init(config)
        @config = default.dup.update(config)
      end

      def authenticate(req, res)
        unless basic_credentials = check_scheme(req)
          challenge(req, res)
        end
        userid, password = basic_credentials.unpack("m*")[0].split(":", 2) 
        password ||= ""
        if userid.empty?
          error("user id was not given.")
          challenge(req, res)
        end
        unless encpass = @userdb.get_passwd(@realm, userid, @reload_db)
          error("%s: the user is not allowed.", userid)
          challenge(req, res)
        end
        if password.crypt(encpass) != encpass
          error("%s: password unmatch.", userid)
          challenge(req, res)
        end
        info("%s: authentication succeeded.", userid)
        req.user = userid
      end

      def challenge(req, res)
        res[@response_field] = "#{@auth_scheme} realm=\"#{@realm}\""
        raise @auth_exception
      end
    end

    class ProxyBasicAuth < BasicAuth
      include ProxyAuthenticator
    end
  end
end
PK     Y\VL      webrick/httpauth/userdb.rbnu [        #
# httpauth/userdb.rb -- UserDB mix-in module.
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: userdb.rb,v 1.2 2003/02/20 07:15:48 gotoyuzo Exp $

module WEBrick
  module HTTPAuth
    module UserDB
      attr_accessor :auth_type # BasicAuth or DigestAuth

      def make_passwd(realm, user, pass)
        @auth_type::make_passwd(realm, user, pass)
      end

      def set_passwd(realm, user, pass)
        self[user] = pass
      end                             

      def get_passwd(realm, user, reload_db=false)
        # reload_db is dummy
        make_passwd(realm, user, self[user])
      end
    end
  end
end
PK     Y\[      webrick/httpauth/htgroup.rbnu [        #
# httpauth/htgroup.rb -- Apache compatible htgroup file
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: htgroup.rb,v 1.1 2003/02/16 22:22:56 gotoyuzo Exp $

require 'tempfile'

module WEBrick
  module HTTPAuth
    class Htgroup
      def initialize(path)
        @path = path
        @mtime = Time.at(0)
        @group = Hash.new
        open(@path,"a").close unless File::exist?(@path)
        reload
      end

      def reload
        if (mtime = File::mtime(@path)) > @mtime
          @group.clear
          open(@path){|io|
            while line = io.gets
              line.chomp!
              group, members = line.split(/:\s*/)
              @group[group] = members.split(/\s+/)
            end
          }
          @mtime = mtime
        end
      end

      def flush(output=nil)
        output ||= @path
        tmp = Tempfile.new("htgroup", File::dirname(output))
        begin
          @group.keys.sort.each{|group|
            tmp.puts(format("%s: %s", group, self.members(group).join(" ")))
          }
          tmp.close
          File::rename(tmp.path, output)
        rescue
          tmp.close(true)
        end
      end

      def members(group)
        reload
        @group[group] || []
      end

      def add(group, members)
        @group[group] = members(group) | members
      end
    end
  end
end
PK     Y\w  w    webrick/httpauth/htdigest.rbnu [        #
# httpauth/htdigest.rb -- Apache compatible htdigest file
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: htdigest.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $

require 'webrick/httpauth/userdb'
require 'webrick/httpauth/digestauth'
require 'tempfile'

module WEBrick
  module HTTPAuth
    class Htdigest
      include UserDB

      def initialize(path)
        @path = path
        @mtime = Time.at(0)
        @digest = Hash.new
        @mutex = Mutex::new
        @auth_type = DigestAuth
        open(@path,"a").close unless File::exist?(@path)
        reload
      end

      def reload
        mtime = File::mtime(@path)
        if mtime > @mtime
          @digest.clear
          open(@path){|io|
            while line = io.gets
              line.chomp!
              user, realm, pass = line.split(/:/, 3)
              unless @digest[realm]
                @digest[realm] = Hash.new
              end
              @digest[realm][user] = pass
            end
          }
          @mtime = mtime
        end
      end

      def flush(output=nil)
        output ||= @path
        tmp = Tempfile.new("htpasswd", File::dirname(output))
        begin
          each{|item| tmp.puts(item.join(":")) }
          tmp.close
          File::rename(tmp.path, output)
        rescue
          tmp.close(true)
        end
      end

      def get_passwd(realm, user, reload_db)
        reload() if reload_db
        if hash = @digest[realm]
          hash[user]
        end
      end

      def set_passwd(realm, user, pass)
        @mutex.synchronize{
          unless @digest[realm]
            @digest[realm] = Hash.new
          end
          @digest[realm][user] = make_passwd(realm, user, pass)
        }
      end

      def delete_passwd(realm, user)
        if hash = @digest[realm]
          hash.delete(user)
        end
      end

      def each
        @digest.keys.sort.each{|realm|
          hash = @digest[realm]
          hash.keys.sort.each{|user|
            yield([user, realm, hash[user]])
          }
        }
      end
    end
  end
end
PK     Y\U؝m      webrick/httpauth/htpasswd.rbnu [        #
# httpauth/htpasswd -- Apache compatible htpasswd file
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: htpasswd.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $

require 'webrick/httpauth/userdb'
require 'webrick/httpauth/basicauth'
require 'tempfile'

module WEBrick
  module HTTPAuth
    class Htpasswd
      include UserDB

      def initialize(path)
        @path = path
        @mtime = Time.at(0)
        @passwd = Hash.new
        @auth_type = BasicAuth
        open(@path,"a").close unless File::exist?(@path)
        reload
      end

      def reload
        mtime = File::mtime(@path)
        if mtime > @mtime
          @passwd.clear
          open(@path){|io|
            while line = io.gets
              line.chomp!
              case line
              when %r!\A[^:]+:[a-zA-Z0-9./]{13}\z!
                user, pass = line.split(":")
              when /:\$/, /:\{SHA\}/
                raise NotImplementedError,
                      'MD5, SHA1 .htpasswd file not supported'
              else
                raise StandardError, 'bad .htpasswd file'
              end
              @passwd[user] = pass
            end
          }
          @mtime = mtime
        end
      end

      def flush(output=nil)
        output ||= @path
        tmp = Tempfile.new("htpasswd", File::dirname(output))
        begin
          each{|item| tmp.puts(item.join(":")) }
          tmp.close
          File::rename(tmp.path, output)
        rescue
          tmp.close(true)
        end
      end

      def get_passwd(realm, user, reload_db)
        reload() if reload_db
        @passwd[user]
      end

      def set_passwd(realm, user, pass)
        @passwd[user] = make_passwd(realm, user, pass)
      end

      def delete_passwd(realm, user)
        @passwd.delete(user)
      end

      def each
        @passwd.keys.sort.each{|user|
          yield([user, @passwd[user]])
        }
      end
    end
  end
end
PK     Y\-G_  _    webrick/version.rbnu [        #
# version.rb -- version and release date
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: version.rb,v 1.74 2003/07/22 19:20:43 gotoyuzo Exp $

module WEBrick
  VERSION      = "1.3.1"
end
PK     Y\F!  !    webrick/cookie.rbnu [        #
# cookie.rb -- Cookie class
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: cookie.rb,v 1.16 2002/09/21 12:23:35 gotoyuzo Exp $

require 'time'
require 'webrick/httputils'

module WEBrick
  class Cookie

    attr_reader :name
    attr_accessor :value, :version
    attr_accessor :domain, :path, :secure
    attr_accessor :comment, :max_age
    #attr_accessor :comment_url, :discard, :port

    def initialize(name, value)
      @name = name
      @value = value
      @version = 0     # Netscape Cookie

      @domain = @path = @secure = @comment = @max_age =
      @expires = @comment_url = @discard = @port = nil
    end

    def expires=(t)
      @expires = t && (t.is_a?(Time) ? t.httpdate : t.to_s)
    end

    def expires
      @expires && Time.parse(@expires)
    end

    def to_s
      ret = ""
      ret << @name << "=" << @value
      ret << "; " << "Version=" << @version.to_s if @version > 0
      ret << "; " << "Domain="  << @domain  if @domain
      ret << "; " << "Expires=" << @expires if @expires
      ret << "; " << "Max-Age=" << @max_age.to_s if @max_age
      ret << "; " << "Comment=" << @comment if @comment
      ret << "; " << "Path="    << @path if @path
      ret << "; " << "Secure"   if @secure
      ret
    end

    # Cookie::parse()
    #   It parses Cookie field sent from the user agent.
    def self.parse(str)
      if str
        ret = []
        cookie = nil
        ver = 0
        str.split(/[;,]\s+/).each{|x|
          key, val = x.split(/=/,2)
          val = val ? HTTPUtils::dequote(val) : ""
          case key
          when "$Version"; ver = val.to_i
          when "$Path";    cookie.path = val
          when "$Domain";  cookie.domain = val
          when "$Port";    cookie.port = val
          else
            ret << cookie if cookie
            cookie = self.new(key, val)
            cookie.version = ver
          end
        }
        ret << cookie if cookie
        ret
      end
    end

    def self.parse_set_cookie(str)
      cookie_elem = str.split(/;/)
      first_elem = cookie_elem.shift
      first_elem.strip!
      key, value = first_elem.split(/=/, 2)
      cookie = new(key, HTTPUtils.dequote(value))
      cookie_elem.each{|pair|
        pair.strip!
        key, value = pair.split(/=/, 2)
        if value
          value = HTTPUtils.dequote(value.strip)
        end
        case key.downcase
        when "domain"  then cookie.domain  = value
        when "path"    then cookie.path    = value
        when "expires" then cookie.expires = value
        when "max-age" then cookie.max_age = Integer(value)
        when "comment" then cookie.comment = value
        when "version" then cookie.version = Integer(value)
        when "secure"  then cookie.secure = true
        end
      }
      return cookie
    end

    def self.parse_set_cookies(str)
      return str.split(/,(?=[^;,]*=)|,$/).collect{|c|
        parse_set_cookie(c)
      }
    end
  end
end
PK     Y\"HZ   Z   
  profile.rbnu [        require 'profiler'

END {
  Profiler__::print_profile(STDERR)
}
Profiler__::start_profile
PK     Y\[k  k  
  ostruct.rbnu [        #
# = ostruct.rb: OpenStruct implementation
#
# Author:: Yukihiro Matsumoto
# Documentation:: Gavin Sinclair
#
# OpenStruct allows the creation of data objects with arbitrary attributes.
# See OpenStruct for an example.
#

#
# OpenStruct allows you to create data objects and set arbitrary attributes.
# For example:
#
#   require 'ostruct' 
#
#   record = OpenStruct.new
#   record.name    = "John Smith"
#   record.age     = 70
#   record.pension = 300
#   
#   puts record.name     # -> "John Smith"
#   puts record.address  # -> nil
#
# It is like a hash with a different way to access the data.  In fact, it is
# implemented with a hash, and you can initialize it with one.
#
#   hash = { "country" => "Australia", :population => 20_000_000 }
#   data = OpenStruct.new(hash)
#
#   p data        # -> <OpenStruct country="Australia" population=20000000>
#
class OpenStruct
  #
  # Create a new OpenStruct object.  The optional +hash+, if given, will
  # generate attributes and values.  For example.
  #
  #   require 'ostruct'
  #   hash = { "country" => "Australia", :population => 20_000_000 }
  #   data = OpenStruct.new(hash)
  #
  #   p data        # -> <OpenStruct country="Australia" population=20000000>
  #
  # By default, the resulting OpenStruct object will have no attributes. 
  #
  def initialize(hash=nil)
    @table = {}
    if hash
      for k,v in hash
        @table[k.to_sym] = v
        new_ostruct_member(k)
      end
    end
  end

  # Duplicate an OpenStruct object members. 
  def initialize_copy(orig)
    super
    @table = @table.dup
  end

  def marshal_dump
    @table
  end
  def marshal_load(x)
    @table = x
    @table.each_key{|key| new_ostruct_member(key)}
  end

  def modifiable
    if self.frozen?
      raise TypeError, "can't modify frozen #{self.class}", caller(2)
    end
    @table
  end
  protected :modifiable

  def new_ostruct_member(name)
    name = name.to_sym
    unless self.respond_to?(name)
      class << self; self; end.class_eval do
        define_method(name) { @table[name] }
        define_method("#{name}=") { |x| modifiable[name] = x }
      end
    end
    name
  end

  def method_missing(mid, *args) # :nodoc:
    mname = mid.id2name
    len = args.length
    if mname.chomp!('=')
      if len != 1
        raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
      end
      modifiable[new_ostruct_member(mname)] = args[0]
    elsif len == 0
      @table[mid]
    else
      raise NoMethodError, "undefined method `#{mname}' for #{self}", caller(1)
    end
  end

  #
  # Remove the named field from the object.
  #
  def delete_field(name)
    @table.delete name.to_sym
  end

  InspectKey = :__inspect_key__ # :nodoc:

  #
  # Returns a string containing a detailed summary of the keys and values.
  #
  def inspect
    str = "#<#{self.class}"

    ids = (Thread.current[InspectKey] ||= [])
    if ids.include?(object_id)
      return str << ' ...>'
    end

    ids << object_id
    begin
      first = true
      for k,v in @table
        str << "," unless first
        first = false
        str << " #{k}=#{v.inspect}"
      end
      return str << '>'
    ensure
      ids.pop
    end
  end
  alias :to_s :inspect

  attr_reader :table # :nodoc:
  protected :table

  #
  # Compare this object and +other+ for equality.
  #
  def ==(other)
    return false unless(other.kind_of?(OpenStruct))
    return @table == other.table
  end
end
PK     Y\$@	  @	  
  rss/2.0.rbnu [        require "rss/0.9"

module RSS

  class Rss

    class Channel

      [
        ["generator"],
        ["ttl", :integer],
      ].each do |name, type|
        install_text_element(name, "", "?", name, type)
      end

      [
        %w(category categories),
      ].each do |name, plural_name|
        install_have_children_element(name, "", "*", name, plural_name)
      end

      [
        ["image", "?"],
        ["language", "?"],
      ].each do |name, occurs|
        install_model(name, "", occurs)
      end

      Category = Item::Category

      class Item
      
        [
          ["comments", "?"],
          ["author", "?"],
        ].each do |name, occurs|
          install_text_element(name, "", occurs)
        end

        [
          ["pubDate", '?'],
        ].each do |name, occurs|
          install_date_element(name, "", occurs, name, 'rfc822')
        end
        alias date pubDate
        alias date= pubDate=

        [
          ["guid", '?'],
        ].each do |name, occurs|
          install_have_child_element(name, "", occurs)
        end

        private
        alias _setup_maker_element setup_maker_element
        def setup_maker_element(item)
          _setup_maker_element(item)
          @guid.setup_maker(item) if @guid
        end
        
        class Guid < Element
          
          include RSS09

          [
            ["isPermaLink", "", false, :boolean]
          ].each do |name, uri, required, type|
            install_get_attribute(name, uri, required, type)
          end

          content_setup

          def initialize(*args)
            if Utils.element_initialize_arguments?(args)
              super
            else
              super()
              self.isPermaLink = args[0]
              self.content = args[1]
            end
          end

          alias_method :_PermaLink?, :PermaLink?
          private :_PermaLink?
          def PermaLink?
            perma = _PermaLink?
            perma or perma.nil?
          end

          private
          def maker_target(item)
            item.guid
          end

          def setup_maker_attributes(guid)
            guid.isPermaLink = isPermaLink
            guid.content = content
          end
        end

      end

    end

  end

  RSS09::ELEMENTS.each do |name|
    BaseListener.install_get_text_element("", name, name)
  end

end
PK     Y\;}Px  x    rss/image.rbnu [        require 'rss/1.0'
require 'rss/dublincore'

module RSS

  IMAGE_PREFIX = 'image'
  IMAGE_URI = 'http://purl.org/rss/1.0/modules/image/'

  RDF.install_ns(IMAGE_PREFIX, IMAGE_URI)

  IMAGE_ELEMENTS = []

  %w(item favicon).each do |name|
    class_name = Utils.to_class_name(name)
    BaseListener.install_class_name(IMAGE_URI, name, "Image#{class_name}")
    IMAGE_ELEMENTS << "#{IMAGE_PREFIX}_#{name}"
  end
  
  module ImageModelUtils
    def validate_one_tag_name(ignore_unknown_element, name, tags)
      if !ignore_unknown_element
        invalid = tags.find {|tag| tag != name}
        raise UnknownTagError.new(invalid, IMAGE_URI) if invalid
      end
      raise TooMuchTagError.new(name, tag_name) if tags.size > 1
    end
  end
  
  module ImageItemModel
    include ImageModelUtils
    extend BaseModel

    def self.append_features(klass)
      super

      klass.install_have_child_element("item", IMAGE_URI, "?",
                                       "#{IMAGE_PREFIX}_item")
      klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
    end

    class ImageItem < Element
      include RSS10
      include DublinCoreModel

      @tag_name = "item"
      
      class << self
        def required_prefix
          IMAGE_PREFIX
        end
        
        def required_uri
          IMAGE_URI
        end
      end

      install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)

      [
        ["about", ::RSS::RDF::URI, true],
        ["resource", ::RSS::RDF::URI, false],
      ].each do |name, uri, required|
        install_get_attribute(name, uri, required, nil, nil,
                              "#{::RSS::RDF::PREFIX}:#{name}")
      end

      %w(width height).each do |tag|
        full_name = "#{IMAGE_PREFIX}_#{tag}"
        disp_name = "#{IMAGE_PREFIX}:#{tag}"
        install_text_element(tag, IMAGE_URI, "?",
                             full_name, :integer, disp_name)
        BaseListener.install_get_text_element(IMAGE_URI, tag, full_name)
      end

      alias width= image_width=
      alias width image_width
      alias height= image_height=
      alias height image_height

      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.about = args[0]
          self.resource = args[1]
        end
      end

      def full_name
        tag_name_with_prefix(IMAGE_PREFIX)
      end

      private
      def maker_target(target)
        target.image_item
      end

      def setup_maker_attributes(item)
        item.about = self.about
        item.resource = self.resource
      end
    end
  end
  
  module ImageFaviconModel
    include ImageModelUtils
    extend BaseModel
    
    def self.append_features(klass)
      super

      unless klass.class == Module
        klass.install_have_child_element("favicon", IMAGE_URI, "?",
                                         "#{IMAGE_PREFIX}_favicon")
        klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
      end
    end

    class ImageFavicon < Element
      include RSS10
      include DublinCoreModel

      @tag_name = "favicon"
      
      class << self
        def required_prefix
          IMAGE_PREFIX
        end
        
        def required_uri
          IMAGE_URI
        end
      end

      [
        ["about", ::RSS::RDF::URI, true, ::RSS::RDF::PREFIX],
        ["size", IMAGE_URI, true, IMAGE_PREFIX],
      ].each do |name, uri, required, prefix|
        install_get_attribute(name, uri, required, nil, nil,
                              "#{prefix}:#{name}")
      end

      AVAILABLE_SIZES = %w(small medium large)
      alias_method :set_size, :size=
      private :set_size
      def size=(new_value)
        if @do_validate and !new_value.nil?
          new_value = new_value.strip
          unless AVAILABLE_SIZES.include?(new_value)
            attr_name = "#{IMAGE_PREFIX}:size"
            raise NotAvailableValueError.new(full_name, new_value, attr_name)
          end
        end
        set_size(new_value)
      end
      
      alias image_size= size=
      alias image_size size

      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.about = args[0]
          self.size = args[1]
        end
      end

      def full_name
        tag_name_with_prefix(IMAGE_PREFIX)
      end

      private
      def maker_target(target)
        target.image_favicon
      end

      def setup_maker_attributes(favicon)
        favicon.about = self.about
        favicon.size = self.size
      end
    end

  end

  class RDF
    class Channel; include ImageFaviconModel; end
    class Item; include ImageItemModel; end
  end

end
PK     Y\Ye    
  rss/xml.rbnu [        require "rss/utils"

module RSS
  module XML
    class Element
      include Enumerable

      attr_reader :name, :prefix, :uri, :attributes, :children
      def initialize(name, prefix=nil, uri=nil, attributes={}, children=[])
        @name = name
        @prefix = prefix
        @uri = uri
        @attributes = attributes
        if children.is_a?(String) or !children.respond_to?(:each)
          @children = [children]
        else
          @children = children
        end
      end

      def [](name)
        @attributes[name]
      end

      def []=(name, value)
        @attributes[name] = value
      end

      def <<(child)
        @children << child
      end

      def each(&block)
        @children.each(&block)
      end

      def ==(other)
        other.kind_of?(self.class) and
          @name == other.name and
          @uri == other.uri and
          @attributes == other.attributes and
          @children == other.children
      end

      def to_s
        rv = "<#{full_name}"
        attributes.each do |key, value|
          rv << " #{Utils.html_escape(key)}=\"#{Utils.html_escape(value)}\""
        end
        if children.empty?
          rv << "/>"
        else
          rv << ">"
          children.each do |child|
            rv << child.to_s
          end
          rv << "</#{full_name}>"
        end
        rv
      end

      def full_name
        if @prefix
          "#{@prefix}:#{@name}"
        else
          @name
        end
      end
    end
  end
end
PK     Y\]S        rss/dublincore/2.0.rbnu [        require "rss/2.0"
require "rss/dublincore"

module RSS
  Rss.install_ns(DC_PREFIX, DC_URI)

  class Rss
    class Channel
      include DublinCoreModel
      class Item; include DublinCoreModel; end
    end
  end
end
PK     Y\T      rss/dublincore/atom.rbnu [        require "rss/atom"
require "rss/dublincore"

module RSS
  module Atom
    Feed.install_ns(DC_PREFIX, DC_URI)

    class Feed
      include DublinCoreModel
      class Entry; include DublinCoreModel; end
    end

    class Entry
      include DublinCoreModel
    end
  end
end
PK     Y\G/  /    rss/dublincore/1.0.rbnu [        require "rss/1.0"
require "rss/dublincore"

module RSS
  RDF.install_ns(DC_PREFIX, DC_URI)

  class RDF
    class Channel; include DublinCoreModel; end
    class Image; include DublinCoreModel; end
    class Item; include DublinCoreModel; end
    class Textinput; include DublinCoreModel; end
  end
end
PK     Y\/H      rss/content.rbnu [        require "rss/rss"

module RSS
  CONTENT_PREFIX = 'content'
  CONTENT_URI = "http://purl.org/rss/1.0/modules/content/"

  module ContentModel
    extend BaseModel

    ELEMENTS = ["#{CONTENT_PREFIX}_encoded"]

    def self.append_features(klass)
      super

      klass.install_must_call_validator(CONTENT_PREFIX, CONTENT_URI)
      ELEMENTS.each do |full_name|
        name = full_name[(CONTENT_PREFIX.size + 1)..-1]
        klass.install_text_element(name, CONTENT_URI, "?", full_name)
      end
    end
  end

  prefix_size = CONTENT_PREFIX.size + 1
  ContentModel::ELEMENTS.each do |full_name|
    name = full_name[prefix_size..-1]
    BaseListener.install_get_text_element(CONTENT_URI, name, full_name)
  end
end

require 'rss/content/1.0'
require 'rss/content/2.0'
PK     Y\usK  K    rss/atom.rbnu [        require 'base64'
require 'rss/parser'

module RSS
  module Atom
    URI = "http://www.w3.org/2005/Atom"
    XHTML_URI = "http://www.w3.org/1999/xhtml"

    module CommonModel
      NSPOOL = {}
      ELEMENTS = []

      def self.append_features(klass)
        super
        klass.install_must_call_validator("atom", URI)
        [
         ["lang", :xml],
         ["base", :xml],
        ].each do |name, uri, required|
          klass.install_get_attribute(name, uri, required, [nil, :inherit])
        end
        klass.class_eval do
          class << self
            def required_uri
              URI
            end

            def need_parent?
              true
            end
          end
        end
      end
    end

    module ContentModel
      module ClassMethods
        def content_type
          @content_type ||= nil
        end
      end

      class << self
        def append_features(klass)
          super
          klass.extend(ClassMethods)
          klass.content_setup(klass.content_type, klass.tag_name)
        end
      end

      def maker_target(target)
        target
      end

      private
      def setup_maker_element_writer
        "#{self.class.name.split(/::/).last.downcase}="
      end

      def setup_maker_element(target)
        target.__send__(setup_maker_element_writer, content)
        super
      end
    end

    module URIContentModel
      class  << self
        def append_features(klass)
          super
          klass.class_eval do
            @content_type = [nil, :uri]
            include(ContentModel)
          end
        end
      end
    end

    module TextConstruct
      def self.append_features(klass)
        super
        klass.class_eval do
          [
           ["type", ""],
          ].each do |name, uri, required|
            install_get_attribute(name, uri, required, :text_type)
          end

          content_setup
          add_need_initialize_variable("xhtml")

          class << self
            def xml_getter
              "xhtml"
            end

            def xml_setter
              "xhtml="
            end
          end
        end
      end

      attr_writer :xhtml
      def xhtml
        return @xhtml if @xhtml.nil?
        if @xhtml.is_a?(XML::Element) and
            [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI]
          return @xhtml
        end

        children = @xhtml
        children = [children] unless children.is_a?(Array)
        XML::Element.new("div", nil, XHTML_URI,
                         {"xmlns" => XHTML_URI}, children)
      end

      def have_xml_content?
        @type == "xhtml"
      end

      def atom_validate(ignore_unknown_element, tags, uri)
        if have_xml_content?
          if @xhtml.nil?
            raise MissingTagError.new("div", tag_name)
          end
          unless [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI]
            raise NotExpectedTagError.new(@xhtml.name, @xhtml.uri, tag_name)
          end
        end
      end

      private
      def maker_target(target)
        target.__send__(self.class.name.split(/::/).last.downcase) {|x| x}
      end

      def setup_maker_attributes(target)
        target.type = type
        target.content = content
        target.xml_content = @xhtml
      end
    end

    module PersonConstruct
      def self.append_features(klass)
        super
        klass.class_eval do
          [
           ["name", nil],
           ["uri", "?"],
           ["email", "?"],
          ].each do |tag, occurs|
            install_have_attribute_element(tag, URI, occurs, nil, :content)
          end
        end
      end

      def maker_target(target)
        target.__send__("new_#{self.class.name.split(/::/).last.downcase}")
      end

      class Name < RSS::Element
        include CommonModel
        include ContentModel
      end

      class Uri < RSS::Element
        include CommonModel
        include URIContentModel
      end

      class Email < RSS::Element
        include CommonModel
        include ContentModel
      end
    end

    module DateConstruct
      def self.append_features(klass)
        super
        klass.class_eval do
          @content_type = :w3cdtf
          include(ContentModel)
        end
      end

      def atom_validate(ignore_unknown_element, tags, uri)
        raise NotAvailableValueError.new(tag_name, "") if content.nil?
      end
    end

    module DuplicateLinkChecker
      def validate_duplicate_links(links)
        link_infos = {}
        links.each do |link|
          rel = link.rel || "alternate"
          next unless rel == "alternate"
          key = [link.hreflang, link.type]
          if link_infos.has_key?(key)
            raise TooMuchTagError.new("link", tag_name)
          end
          link_infos[key] = true
        end
      end
    end

    class Feed < RSS::Element
      include RootElementMixin
      include CommonModel
      include DuplicateLinkChecker

      install_ns('', URI)

      [
       ["author", "*", :children],
       ["category", "*", :children, "categories"],
       ["contributor", "*", :children],
       ["generator", "?"],
       ["icon", "?", nil, :content],
       ["id", nil, nil, :content],
       ["link", "*", :children],
       ["logo", "?"],
       ["rights", "?"],
       ["subtitle", "?", nil, :content],
       ["title", nil, nil, :content],
       ["updated", nil, nil, :content],
       ["entry", "*", :children, "entries"],
      ].each do |tag, occurs, type, *args|
        type ||= :child
        __send__("install_have_#{type}_element",
                 tag, URI, occurs, tag, *args)
      end

      def initialize(version=nil, encoding=nil, standalone=nil)
        super("1.0", version, encoding, standalone)
        @feed_type = "atom"
        @feed_subtype = "feed"
      end

      alias_method :items, :entries

      def have_author?
        authors.any? {|author| !author.to_s.empty?} or
          entries.any? {|entry| entry.have_author?(false)}
      end

      private
      def atom_validate(ignore_unknown_element, tags, uri)
        unless have_author?
          raise MissingTagError.new("author", tag_name)
        end
        validate_duplicate_links(links)
      end

      def have_required_elements?
        super and have_author?
      end

      def maker_target(maker)
        maker.channel
      end

      def setup_maker_element(channel)
        prev_dc_dates = channel.dc_dates.to_a.dup
        super
        channel.about = id.content if id
        channel.dc_dates.replace(prev_dc_dates)
      end

      def setup_maker_elements(channel)
        super
        items = channel.maker.items
        entries.each do |entry|
          entry.setup_maker(items)
        end
      end

      class Author < RSS::Element
        include CommonModel
        include PersonConstruct
      end

      class Category < RSS::Element
        include CommonModel

        [
         ["term", "", true],
         ["scheme", "", false, [nil, :uri]],
         ["label", ""],
        ].each do |name, uri, required, type|
          install_get_attribute(name, uri, required, type)
        end

        private
        def maker_target(target)
          target.new_category
        end
      end

      class Contributor < RSS::Element
        include CommonModel
        include PersonConstruct
      end

      class Generator < RSS::Element
        include CommonModel
        include ContentModel

        [
         ["uri", "", false, [nil, :uri]],
         ["version", ""],
        ].each do |name, uri, required, type|
          install_get_attribute(name, uri, required, type)
        end

        private
        def setup_maker_attributes(target)
          target.generator do |generator|
            generator.uri = uri if uri
            generator.version = version if version
          end
        end
      end

      class Icon < RSS::Element
        include CommonModel
        include URIContentModel
      end

      class Id < RSS::Element
        include CommonModel
        include URIContentModel
      end

      class Link < RSS::Element
        include CommonModel

        [
         ["href", "", true, [nil, :uri]],
         ["rel", ""],
         ["type", ""],
         ["hreflang", ""],
         ["title", ""],
         ["length", ""],
        ].each do |name, uri, required, type|
          install_get_attribute(name, uri, required, type)
        end

        private
        def maker_target(target)
          target.new_link
        end
      end

      class Logo < RSS::Element
        include CommonModel
        include URIContentModel

        def maker_target(target)
          target.maker.image
        end

        private
        def setup_maker_element_writer
          "url="
        end
      end

      class Rights < RSS::Element
        include CommonModel
        include TextConstruct
      end

      class Subtitle < RSS::Element
        include CommonModel
        include TextConstruct
      end

      class Title < RSS::Element
        include CommonModel
        include TextConstruct
      end

      class Updated < RSS::Element
        include CommonModel
        include DateConstruct
      end

      class Entry < RSS::Element
        include CommonModel
        include DuplicateLinkChecker

        [
         ["author", "*", :children],
         ["category", "*", :children, "categories"],
         ["content", "?", :child],
         ["contributor", "*", :children],
         ["id", nil, nil, :content],
         ["link", "*", :children],
         ["published", "?", :child, :content],
         ["rights", "?", :child],
         ["source", "?"],
         ["summary", "?", :child],
         ["title", nil],
         ["updated", nil, :child, :content],
        ].each do |tag, occurs, type, *args|
          type ||= :attribute
          __send__("install_have_#{type}_element",
                   tag, URI, occurs, tag, *args)
        end

        def have_author?(check_parent=true)
          authors.any? {|author| !author.to_s.empty?} or
            (check_parent and @parent and @parent.have_author?) or
            (source and source.have_author?)
        end

        private
        def atom_validate(ignore_unknown_element, tags, uri)
          unless have_author?
            raise MissingTagError.new("author", tag_name)
          end
          validate_duplicate_links(links)
        end

        def have_required_elements?
          super and have_author?
        end

        def maker_target(items)
          if items.respond_to?("items")
            # For backward compatibility
            items = items.items
          end
          items.new_item
        end

        Author = Feed::Author
        Category = Feed::Category

        class Content < RSS::Element
          include CommonModel

          class << self
            def xml_setter
              "xml="
            end

            def xml_getter
              "xml"
            end
          end

          [
           ["type", ""],
           ["src", "", false, [nil, :uri]],
          ].each do |name, uri, required, type|
            install_get_attribute(name, uri, required, type)
          end

          content_setup
          add_need_initialize_variable("xml")

          attr_writer :xml
          def have_xml_content?
            inline_xhtml? or inline_other_xml?
          end

          def xml
            return @xml unless inline_xhtml?
            return @xml if @xml.nil?
            if @xml.is_a?(XML::Element) and
                [@xml.name, @xml.uri] == ["div", XHTML_URI]
              return @xml
            end

            children = @xml
            children = [children] unless children.is_a?(Array)
            XML::Element.new("div", nil, XHTML_URI,
                             {"xmlns" => XHTML_URI}, children)
          end

          def xhtml
            if inline_xhtml?
              xml
            else
              nil
            end
          end

          def atom_validate(ignore_unknown_element, tags, uri)
            if out_of_line?
              raise MissingAttributeError.new(tag_name, "type") if @type.nil?
              unless (content.nil? or content.empty?)
                raise NotAvailableValueError.new(tag_name, content)
              end
            elsif inline_xhtml?
              if @xml.nil?
                raise MissingTagError.new("div", tag_name)
              end
              unless @xml.name == "div" and @xml.uri == XHTML_URI
                raise NotExpectedTagError.new(@xml.name, @xml.uri, tag_name)
              end
            end
          end

          def inline_text?
            !out_of_line? and [nil, "text", "html"].include?(@type)
          end

          def inline_html?
            return false if out_of_line?
            @type == "html" or mime_split == ["text", "html"]
          end

          def inline_xhtml?
            !out_of_line? and @type == "xhtml"
          end

          def inline_other?
            return false if out_of_line?
            media_type, subtype = mime_split
            return false if media_type.nil? or subtype.nil?
            true
          end

          def inline_other_text?
            return false unless inline_other?
            return false if inline_other_xml?

            media_type, subtype = mime_split
            return true if "text" == media_type.downcase
            false
          end

          def inline_other_xml?
            return false unless inline_other?

            media_type, subtype = mime_split
            normalized_mime_type = "#{media_type}/#{subtype}".downcase
            if /(?:\+xml|^xml)$/ =~ subtype or
                %w(text/xml-external-parsed-entity
                   application/xml-external-parsed-entity
                   application/xml-dtd).find {|x| x == normalized_mime_type}
              return true
            end
            false
          end

          def inline_other_base64?
            inline_other? and !inline_other_text? and !inline_other_xml?
          end

          def out_of_line?
            not @src.nil?
          end

          def mime_split
            media_type = subtype = nil
            if /\A\s*([a-z]+)\/([a-z\+]+)\s*(?:;.*)?\z/i =~ @type.to_s
              media_type = $1.downcase
              subtype = $2.downcase
            end
            [media_type, subtype]
          end

          def need_base64_encode?
            inline_other_base64?
          end

          private
          def empty_content?
            out_of_line? or super
          end
        end

        Contributor = Feed::Contributor
        Id = Feed::Id
        Link = Feed::Link

        class Published < RSS::Element
          include CommonModel
          include DateConstruct
        end

        Rights = Feed::Rights

        class Source < RSS::Element
          include CommonModel

          [
           ["author", "*", :children],
           ["category", "*", :children, "categories"],
           ["contributor", "*", :children],
           ["generator", "?"],
           ["icon", "?"],
           ["id", "?", nil, :content],
           ["link", "*", :children],
           ["logo", "?"],
           ["rights", "?"],
           ["subtitle", "?"],
           ["title", "?"],
           ["updated", "?", nil, :content],
          ].each do |tag, occurs, type, *args|
            type ||= :attribute
            __send__("install_have_#{type}_element",
                     tag, URI, occurs, tag, *args)
          end

          def have_author?
            !author.to_s.empty?
          end

          Author = Feed::Author
          Category = Feed::Category
          Contributor = Feed::Contributor
          Generator = Feed::Generator
          Icon = Feed::Icon
          Id = Feed::Id
          Link = Feed::Link
          Logo = Feed::Logo
          Rights = Feed::Rights
          Subtitle = Feed::Subtitle
          Title = Feed::Title
          Updated = Feed::Updated
        end

        class Summary < RSS::Element
          include CommonModel
          include TextConstruct
        end

        Title = Feed::Title
        Updated = Feed::Updated
      end
    end

    class Entry < RSS::Element
      include RootElementMixin
      include CommonModel
      include DuplicateLinkChecker

      [
       ["author", "*", :children],
       ["category", "*", :children, "categories"],
       ["content", "?"],
       ["contributor", "*", :children],
       ["id", nil, nil, :content],
       ["link", "*", :children],
       ["published", "?", :child, :content],
       ["rights", "?"],
       ["source", "?"],
       ["summary", "?"],
       ["title", nil],
       ["updated", nil, nil, :content],
      ].each do |tag, occurs, type, *args|
        type ||= :attribute
        __send__("install_have_#{type}_element",
                 tag, URI, occurs, tag, *args)
      end

      def initialize(version=nil, encoding=nil, standalone=nil)
        super("1.0", version, encoding, standalone)
        @feed_type = "atom"
        @feed_subtype = "entry"
      end

      def items
        [self]
      end

      def setup_maker(maker)
        maker = maker.maker if maker.respond_to?("maker")
        super(maker)
      end

      def have_author?
        authors.any? {|author| !author.to_s.empty?} or
          (source and source.have_author?)
      end

      private
      def atom_validate(ignore_unknown_element, tags, uri)
        unless have_author?
          raise MissingTagError.new("author", tag_name)
        end
        validate_duplicate_links(links)
      end

      def have_required_elements?
        super and have_author?
      end

      def maker_target(maker)
        maker.items.new_item
      end

      Author = Feed::Entry::Author
      Category = Feed::Entry::Category
      Content = Feed::Entry::Content
      Contributor = Feed::Entry::Contributor
      Id = Feed::Entry::Id
      Link = Feed::Entry::Link
      Published = Feed::Entry::Published
      Rights = Feed::Entry::Rights
      Source = Feed::Entry::Source
      Summary = Feed::Entry::Summary
      Title = Feed::Entry::Title
      Updated = Feed::Entry::Updated
    end
  end

  Atom::CommonModel::ELEMENTS.each do |name|
    BaseListener.install_get_text_element(Atom::URI, name, "#{name}=")
  end

  module ListenerMixin
    private
    def initial_start_feed(tag_name, prefix, attrs, ns)
      check_ns(tag_name, prefix, ns, Atom::URI)

      @rss = Atom::Feed.new(@version, @encoding, @standalone)
      @rss.do_validate = @do_validate
      @rss.xml_stylesheets = @xml_stylesheets
      @rss.lang = attrs["xml:lang"]
      @rss.base = attrs["xml:base"]
      @last_element = @rss
      pr = Proc.new do |text, tags|
        @rss.validate_for_stream(tags) if @do_validate
      end
      @proc_stack.push(pr)
    end

    def initial_start_entry(tag_name, prefix, attrs, ns)
      check_ns(tag_name, prefix, ns, Atom::URI)

      @rss = Atom::Entry.new(@version, @encoding, @standalone)
      @rss.do_validate = @do_validate
      @rss.xml_stylesheets = @xml_stylesheets
      @rss.lang = attrs["xml:lang"]
      @rss.base = attrs["xml:base"]
      @last_element = @rss
      pr = Proc.new do |text, tags|
        @rss.validate_for_stream(tags) if @do_validate
      end
      @proc_stack.push(pr)
    end
  end
end
PK     Y\?y        rss/content/2.0.rbnu [        require "rss/2.0"
require "rss/content"

module RSS
  Rss.install_ns(CONTENT_PREFIX, CONTENT_URI)

  class Rss
    class Channel
      class Item; include ContentModel; end
    end
  end
end
PK     Y\
        rss/content/1.0.rbnu [        require 'rss/1.0'
require 'rss/content'

module RSS
  RDF.install_ns(CONTENT_PREFIX, CONTENT_URI)

  class RDF
    class Item; include ContentModel; end
  end
end
PK     Y\Vq@  @  
  rss/rss.rbnu [        require "time"

class Time
  class << self
    unless respond_to?(:w3cdtf)
      def w3cdtf(date)
        if /\A\s*
            (-?\d+)-(\d\d)-(\d\d)
            (?:T
            (\d\d):(\d\d)(?::(\d\d))?
            (\.\d+)?
            (Z|[+-]\d\d:\d\d)?)?
            \s*\z/ix =~ date and (($5 and $8) or (!$5 and !$8))
          datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i]
          usec = 0
          usec = $7.to_f * 1000000 if $7
          zone = $8
          if zone
            off = zone_offset(zone, datetime[0])
            datetime = apply_offset(*(datetime + [off]))
            datetime << usec
            time = Time.utc(*datetime)
            time.localtime unless zone_utc?(zone)
            time
          else
            datetime << usec
            Time.local(*datetime)
          end
        else
          raise ArgumentError.new("invalid date: #{date.inspect}")
        end
      end
    end
  end

  unless method_defined?(:w3cdtf)
    def w3cdtf
      if usec.zero?
        fraction_digits = 0
      else
        fraction_digits = Math.log10(usec.to_s.sub(/0*$/, '').to_i).floor + 1
      end
      xmlschema(fraction_digits)
    end
  end
end

require "English"
require "rss/utils"
require "rss/converter"
require "rss/xml-stylesheet"

module RSS

  VERSION = "0.2.4"

  URI = "http://purl.org/rss/1.0/"

  DEBUG = false

  class Error < StandardError; end

  class OverlappedPrefixError < Error
    attr_reader :prefix
    def initialize(prefix)
      @prefix = prefix
    end
  end

  class InvalidRSSError < Error; end

  class MissingTagError < InvalidRSSError
    attr_reader :tag, :parent
    def initialize(tag, parent)
      @tag, @parent = tag, parent
      super("tag <#{tag}> is missing in tag <#{parent}>")
    end
  end

  class TooMuchTagError < InvalidRSSError
    attr_reader :tag, :parent
    def initialize(tag, parent)
      @tag, @parent = tag, parent
      super("tag <#{tag}> is too much in tag <#{parent}>")
    end
  end

  class MissingAttributeError < InvalidRSSError
    attr_reader :tag, :attribute
    def initialize(tag, attribute)
      @tag, @attribute = tag, attribute
      super("attribute <#{attribute}> is missing in tag <#{tag}>")
    end
  end

  class UnknownTagError < InvalidRSSError
    attr_reader :tag, :uri
    def initialize(tag, uri)
      @tag, @uri = tag, uri
      super("tag <#{tag}> is unknown in namespace specified by uri <#{uri}>")
    end
  end

  class NotExpectedTagError < InvalidRSSError
    attr_reader :tag, :uri, :parent
    def initialize(tag, uri, parent)
      @tag, @uri, @parent = tag, uri, parent
      super("tag <{#{uri}}#{tag}> is not expected in tag <#{parent}>")
    end
  end
  # For backward compatibility :X
  NotExceptedTagError = NotExpectedTagError

  class NotAvailableValueError < InvalidRSSError
    attr_reader :tag, :value, :attribute
    def initialize(tag, value, attribute=nil)
      @tag, @value, @attribute = tag, value, attribute
      message = "value <#{value}> of "
      message << "attribute <#{attribute}> of " if attribute
      message << "tag <#{tag}> is not available."
      super(message)
    end
  end

  class UnknownConversionMethodError < Error
    attr_reader :to, :from
    def initialize(to, from)
      @to = to
      @from = from
      super("can't convert to #{to} from #{from}.")
    end
  end
  # for backward compatibility
  UnknownConvertMethod = UnknownConversionMethodError

  class ConversionError < Error
    attr_reader :string, :to, :from
    def initialize(string, to, from)
      @string = string
      @to = to
      @from = from
      super("can't convert #{@string} to #{to} from #{from}.")
    end
  end

  class NotSetError < Error
    attr_reader :name, :variables
    def initialize(name, variables)
      @name = name
      @variables = variables
      super("required variables of #{@name} are not set: #{@variables.join(', ')}")
    end
  end

  class UnsupportedMakerVersionError < Error
    attr_reader :version
    def initialize(version)
      @version = version
      super("Maker doesn't support version: #{@version}")
    end
  end

  module BaseModel
    include Utils

    def install_have_child_element(tag_name, uri, occurs, name=nil, type=nil)
      name ||= tag_name
      add_need_initialize_variable(name)
      install_model(tag_name, uri, occurs, name)

      writer_type, reader_type = type
      def_corresponded_attr_writer name, writer_type
      def_corresponded_attr_reader name, reader_type
      install_element(name) do |n, elem_name|
        <<-EOC
        if @#{n}
          "\#{@#{n}.to_s(need_convert, indent)}"
        else
          ''
        end
EOC
      end
    end
    alias_method(:install_have_attribute_element, :install_have_child_element)

    def install_have_children_element(tag_name, uri, occurs, name=nil, plural_name=nil)
      name ||= tag_name
      plural_name ||= "#{name}s"
      add_have_children_element(name, plural_name)
      add_plural_form(name, plural_name)
      install_model(tag_name, uri, occurs, plural_name, true)

      def_children_accessor(name, plural_name)
      install_element(name, "s") do |n, elem_name|
        <<-EOC
        rv = []
        @#{n}.each do |x|
          value = "\#{x.to_s(need_convert, indent)}"
          rv << value if /\\A\\s*\\z/ !~ value
        end
        rv.join("\n")
EOC
      end
    end

    def install_text_element(tag_name, uri, occurs, name=nil, type=nil,
                             disp_name=nil)
      name ||= tag_name
      disp_name ||= name
      self::ELEMENTS << name unless self::ELEMENTS.include?(name)
      add_need_initialize_variable(name)
      install_model(tag_name, uri, occurs, name)

      def_corresponded_attr_writer(name, type, disp_name)
      def_corresponded_attr_reader(name, type || :convert)
      install_element(name) do |n, elem_name|
        <<-EOC
        if respond_to?(:#{n}_content)
          content = #{n}_content
        else
          content = @#{n}
        end
        if content
          rv = "\#{indent}<#{elem_name}>"
          value = html_escape(content)
          if need_convert
            rv << convert(value)
          else
            rv << value
          end
    	    rv << "</#{elem_name}>"
          rv
        else
          ''
        end
EOC
      end
    end

    def install_date_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil)
      name ||= tag_name
      type ||= :w3cdtf
      disp_name ||= name
      self::ELEMENTS << name
      add_need_initialize_variable(name)
      install_model(tag_name, uri, occurs, name)

      # accessor
      convert_attr_reader name
      date_writer(name, type, disp_name)
      
      install_element(name) do |n, elem_name|
        <<-EOC
        if @#{n}
          rv = "\#{indent}<#{elem_name}>"
          value = html_escape(@#{n}.#{type})
          if need_convert
            rv << convert(value)
          else
            rv << value
          end
    	    rv << "</#{elem_name}>"
          rv
        else
          ''
        end
EOC
      end

    end

    private
    def install_element(name, postfix="")
      elem_name = name.sub('_', ':')
      method_name = "#{name}_element#{postfix}"
      add_to_element_method(method_name)
      module_eval(<<-EOC, *get_file_and_line_from_caller(2))
      def #{method_name}(need_convert=true, indent='')
        #{yield(name, elem_name)}
      end
      private :#{method_name}
EOC
    end

    def inherit_convert_attr_reader(*attrs)
      attrs.each do |attr|
        attr = attr.id2name if attr.kind_of?(Integer)
        module_eval(<<-EOC, *get_file_and_line_from_caller(2))
        def #{attr}_without_inherit
          convert(@#{attr})
        end

        def #{attr}
          if @#{attr}
            #{attr}_without_inherit
          elsif @parent
            @parent.#{attr}
          else
            nil
          end
        end
EOC
      end
    end

    def uri_convert_attr_reader(*attrs)
      attrs.each do |attr|
        attr = attr.id2name if attr.kind_of?(Integer)
        module_eval(<<-EOC, *get_file_and_line_from_caller(2))
        def #{attr}_without_base
          convert(@#{attr})
        end

        def #{attr}
          value = #{attr}_without_base
          return nil if value.nil?
          if /\\A[a-z][a-z0-9+.\\-]*:/i =~ value
            value
          else
            "\#{base}\#{value}"
          end
        end
EOC
      end
    end

    def convert_attr_reader(*attrs)
      attrs.each do |attr|
        attr = attr.id2name if attr.kind_of?(Integer)
        module_eval(<<-EOC, *get_file_and_line_from_caller(2))
        def #{attr}
          convert(@#{attr})
        end
EOC
      end
    end

    def yes_clean_other_attr_reader(*attrs)
      attrs.each do |attr|
        attr = attr.id2name if attr.kind_of?(Integer)
        module_eval(<<-EOC, __FILE__, __LINE__ + 1)
          attr_reader(:#{attr})
          def #{attr}?
            YesCleanOther.parse(@#{attr})
          end
        EOC
      end
    end

    def yes_other_attr_reader(*attrs)
      attrs.each do |attr|
        attr = attr.id2name if attr.kind_of?(Integer)
        module_eval(<<-EOC, __FILE__, __LINE__ + 1)
          attr_reader(:#{attr})
          def #{attr}?
            Utils::YesOther.parse(@#{attr})
          end
        EOC
      end
    end

    def csv_attr_reader(*attrs)
      separator = nil
      if attrs.last.is_a?(Hash)
        options = attrs.pop
        separator = options[:separator]
      end
      separator ||= ", "
      attrs.each do |attr|
        attr = attr.id2name if attr.kind_of?(Integer)
        module_eval(<<-EOC, __FILE__, __LINE__ + 1)
          attr_reader(:#{attr})
          def #{attr}_content
            if @#{attr}.nil?
              @#{attr}
            else
              @#{attr}.join(#{separator.dump})
            end
          end
        EOC
      end
    end

    def date_writer(name, type, disp_name=name)
      module_eval(<<-EOC, *get_file_and_line_from_caller(2))
      def #{name}=(new_value)
        if new_value.nil?
          @#{name} = new_value
        elsif new_value.kind_of?(Time)
          @#{name} = new_value.dup
        else
          if @do_validate
            begin
              @#{name} = Time.__send__('#{type}', new_value)
            rescue ArgumentError
              raise NotAvailableValueError.new('#{disp_name}', new_value)
            end
          else
            @#{name} = nil
            if /\\A\\s*\\z/ !~ new_value.to_s
              begin
                unless Date._parse(new_value, false).empty?
                  @#{name} = Time.parse(new_value)
                end
              rescue ArgumentError
              end
            end
          end
        end

        # Is it need?
        if @#{name}
          class << @#{name}
            undef_method(:to_s)
            alias_method(:to_s, :#{type})
          end
        end

      end
EOC
    end

    def integer_writer(name, disp_name=name)
      module_eval(<<-EOC, *get_file_and_line_from_caller(2))
      def #{name}=(new_value)
        if new_value.nil?
          @#{name} = new_value
        else
          if @do_validate
            begin
              @#{name} = Integer(new_value)
            rescue ArgumentError
              raise NotAvailableValueError.new('#{disp_name}', new_value)
            end
          else
            @#{name} = new_value.to_i
          end
        end
      end
EOC
    end

    def positive_integer_writer(name, disp_name=name)
      module_eval(<<-EOC, *get_file_and_line_from_caller(2))
      def #{name}=(new_value)
        if new_value.nil?
          @#{name} = new_value
        else
          if @do_validate
            begin
              tmp = Integer(new_value)
              raise ArgumentError if tmp <= 0
              @#{name} = tmp
            rescue ArgumentError
              raise NotAvailableValueError.new('#{disp_name}', new_value)
            end
          else
            @#{name} = new_value.to_i
          end
        end
      end
EOC
    end

    def boolean_writer(name, disp_name=name)
      module_eval(<<-EOC, *get_file_and_line_from_caller(2))
      def #{name}=(new_value)
        if new_value.nil?
          @#{name} = new_value
        else
          if @do_validate and
              ![true, false, "true", "false"].include?(new_value)
            raise NotAvailableValueError.new('#{disp_name}', new_value)
          end
          if [true, false].include?(new_value)
            @#{name} = new_value
          else
            @#{name} = new_value == "true"
          end
        end
      end
EOC
    end

    def text_type_writer(name, disp_name=name)
      module_eval(<<-EOC, *get_file_and_line_from_caller(2))
      def #{name}=(new_value)
        if @do_validate and
            !["text", "html", "xhtml", nil].include?(new_value)
          raise NotAvailableValueError.new('#{disp_name}', new_value)
        end
        @#{name} = new_value
      end
EOC
    end

    def content_writer(name, disp_name=name)
      klass_name = "self.class::#{Utils.to_class_name(name)}"
      module_eval(<<-EOC, *get_file_and_line_from_caller(2))
      def #{name}=(new_value)
        if new_value.is_a?(#{klass_name})
          @#{name} = new_value
        else
          @#{name} = #{klass_name}.new
          @#{name}.content = new_value
        end
      end
EOC
    end

    def yes_clean_other_writer(name, disp_name=name)
      module_eval(<<-EOC, __FILE__, __LINE__ + 1)
        def #{name}=(value)
          value = (value ? "yes" : "no") if [true, false].include?(value)
          @#{name} = value
        end
      EOC
    end

    def yes_other_writer(name, disp_name=name)
      module_eval(<<-EOC, __FILE__, __LINE__ + 1)
        def #{name}=(new_value)
          if [true, false].include?(new_value)
            new_value = new_value ? "yes" : "no"
          end
          @#{name} = new_value
        end
      EOC
    end

    def csv_writer(name, disp_name=name)
      module_eval(<<-EOC, __FILE__, __LINE__ + 1)
        def #{name}=(new_value)
          @#{name} = Utils::CSV.parse(new_value)
        end
      EOC
    end

    def csv_integer_writer(name, disp_name=name)
      module_eval(<<-EOC, __FILE__, __LINE__ + 1)
        def #{name}=(new_value)
          @#{name} = Utils::CSV.parse(new_value) {|v| Integer(v)}
        end
      EOC
    end

    def def_children_accessor(accessor_name, plural_name)
      module_eval(<<-EOC, *get_file_and_line_from_caller(2))
      def #{plural_name}
        @#{accessor_name}
      end

      def #{accessor_name}(*args)
        if args.empty?
          @#{accessor_name}.first
        else
          @#{accessor_name}[*args]
        end
      end

      def #{accessor_name}=(*args)
        receiver = self.class.name
        warn("Warning:\#{caller.first.sub(/:in `.*'\z/, '')}: " \
             "Don't use `\#{receiver}\##{accessor_name} = XXX'/" \
             "`\#{receiver}\#set_#{accessor_name}(XXX)'. " \
             "Those APIs are not sense of Ruby. " \
             "Use `\#{receiver}\##{plural_name} << XXX' instead of them.")
        if args.size == 1
          @#{accessor_name}.push(args[0])
        else
          @#{accessor_name}.__send__("[]=", *args)
        end
      end
      alias_method(:set_#{accessor_name}, :#{accessor_name}=)
EOC
    end
  end

  module SetupMaker
    def setup_maker(maker)
      target = maker_target(maker)
      unless target.nil?
        setup_maker_attributes(target)
        setup_maker_element(target)
        setup_maker_elements(target)
      end
    end

    private
    def maker_target(maker)
      nil
    end

    def setup_maker_attributes(target)
    end

    def setup_maker_element(target)
      self.class.need_initialize_variables.each do |var|
        value = __send__(var)
        next if value.nil?
        if value.respond_to?("setup_maker") and
            !not_need_to_call_setup_maker_variables.include?(var)
          value.setup_maker(target)
        else
          setter = "#{var}="
          if target.respond_to?(setter)
            target.__send__(setter, value)
          end
        end
      end
    end

    def not_need_to_call_setup_maker_variables
      []
    end

    def setup_maker_elements(parent)
      self.class.have_children_elements.each do |name, plural_name|
        if parent.respond_to?(plural_name)
          target = parent.__send__(plural_name)
          __send__(plural_name).each do |elem|
            elem.setup_maker(target)
          end
        end
      end
    end
  end

  class Element
    extend BaseModel
    include Utils
    extend Utils::InheritedReader
    include SetupMaker

    INDENT = "  "
    
    MUST_CALL_VALIDATORS = {}
    MODELS = []
    GET_ATTRIBUTES = []
    HAVE_CHILDREN_ELEMENTS = []
    TO_ELEMENT_METHODS = []
    NEED_INITIALIZE_VARIABLES = []
    PLURAL_FORMS = {}

    class << self
      def must_call_validators
        inherited_hash_reader("MUST_CALL_VALIDATORS")
      end
      def models
        inherited_array_reader("MODELS")
      end
      def get_attributes
        inherited_array_reader("GET_ATTRIBUTES")
      end
      def have_children_elements
        inherited_array_reader("HAVE_CHILDREN_ELEMENTS")
      end
      def to_element_methods
        inherited_array_reader("TO_ELEMENT_METHODS")
      end
      def need_initialize_variables
        inherited_array_reader("NEED_INITIALIZE_VARIABLES")
      end
      def plural_forms
        inherited_hash_reader("PLURAL_FORMS")
      end

      def inherited_base
        ::RSS::Element
      end

      def inherited(klass)
        klass.const_set("MUST_CALL_VALIDATORS", {})
        klass.const_set("MODELS", [])
        klass.const_set("GET_ATTRIBUTES", [])
        klass.const_set("HAVE_CHILDREN_ELEMENTS", [])
        klass.const_set("TO_ELEMENT_METHODS", [])
        klass.const_set("NEED_INITIALIZE_VARIABLES", [])
        klass.const_set("PLURAL_FORMS", {})

        tag_name = klass.name.split(/::/).last
        tag_name[0, 1] = tag_name[0, 1].downcase
        klass.instance_variable_set("@tag_name", tag_name)
        klass.instance_variable_set("@have_content", false)
      end

      def install_must_call_validator(prefix, uri)
        self::MUST_CALL_VALIDATORS[uri] = prefix
      end

      def install_model(tag, uri, occurs=nil, getter=nil, plural=false)
        getter ||= tag
        if m = self::MODELS.find {|t, u, o, g, p| t == tag and u == uri}
          m[2] = occurs
        else
          self::MODELS << [tag, uri, occurs, getter, plural]
        end
      end

      def install_get_attribute(name, uri, required=true,
                                type=nil, disp_name=nil,
                                element_name=nil)
        disp_name ||= name
        element_name ||= name
        writer_type, reader_type = type
        def_corresponded_attr_writer name, writer_type, disp_name
        def_corresponded_attr_reader name, reader_type
        if type == :boolean and /^is/ =~ name
          alias_method "#{$POSTMATCH}?", name
        end
        self::GET_ATTRIBUTES << [name, uri, required, element_name]
        add_need_initialize_variable(disp_name)
      end

      def def_corresponded_attr_writer(name, type=nil, disp_name=nil)
        disp_name ||= name
        case type
        when :integer
          integer_writer name, disp_name
        when :positive_integer
          positive_integer_writer name, disp_name
        when :boolean
          boolean_writer name, disp_name
        when :w3cdtf, :rfc822, :rfc2822
          date_writer name, type, disp_name
        when :text_type
          text_type_writer name, disp_name
        when :content
          content_writer name, disp_name
        when :yes_clean_other
          yes_clean_other_writer name, disp_name
        when :yes_other
          yes_other_writer name, disp_name
        when :csv
          csv_writer name
        when :csv_integer
          csv_integer_writer name
        else
          attr_writer name
        end
      end

      def def_corresponded_attr_reader(name, type=nil)
        case type
        when :inherit
          inherit_convert_attr_reader name
        when :uri
          uri_convert_attr_reader name
        when :yes_clean_other
          yes_clean_other_attr_reader name
        when :yes_other
          yes_other_attr_reader name
        when :csv
          csv_attr_reader name
        when :csv_integer
          csv_attr_reader name, :separator => ","
        else
          convert_attr_reader name
        end
      end

      def content_setup(type=nil, disp_name=nil)
        writer_type, reader_type = type
        def_corresponded_attr_writer :content, writer_type, disp_name
        def_corresponded_attr_reader :content, reader_type
        @have_content = true
      end

      def have_content?
        @have_content
      end

      def add_have_children_element(variable_name, plural_name)
        self::HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name]
      end

      def add_to_element_method(method_name)
        self::TO_ELEMENT_METHODS << method_name
      end

      def add_need_initialize_variable(variable_name)
        self::NEED_INITIALIZE_VARIABLES << variable_name
      end

      def add_plural_form(singular, plural)
        self::PLURAL_FORMS[singular] = plural
      end

      def required_prefix
        nil
      end

      def required_uri
        ""
      end

      def need_parent?
        false
      end

      def install_ns(prefix, uri)
        if self::NSPOOL.has_key?(prefix)
          raise OverlappedPrefixError.new(prefix)
        end
        self::NSPOOL[prefix] = uri
      end

      def tag_name
        @tag_name
      end
    end

    attr_accessor :parent, :do_validate

    def initialize(do_validate=true, attrs=nil)
      @parent = nil
      @converter = nil
      if attrs.nil? and (do_validate.is_a?(Hash) or do_validate.is_a?(Array))
        do_validate, attrs = true, do_validate
      end
      @do_validate = do_validate
      initialize_variables(attrs || {})
    end

    def tag_name
      self.class.tag_name
    end

    def full_name
      tag_name
    end
    
    def converter=(converter)
      @converter = converter
      targets = children.dup
      self.class.have_children_elements.each do |variable_name, plural_name|
        targets.concat(__send__(plural_name))
      end
      targets.each do |target|
        target.converter = converter unless target.nil?
      end
    end

    def convert(value)
      if @converter
        @converter.convert(value)
      else
        value
      end
    end

    def valid?(ignore_unknown_element=true)
      validate(ignore_unknown_element)
      true
    rescue RSS::Error
      false
    end

    def validate(ignore_unknown_element=true)
      do_validate = @do_validate
      @do_validate = true
      validate_attribute
      __validate(ignore_unknown_element)
    ensure
      @do_validate = do_validate
    end
    
    def validate_for_stream(tags, ignore_unknown_element=true)
      validate_attribute
      __validate(ignore_unknown_element, tags, false)
    end

    def to_s(need_convert=true, indent='')
      if self.class.have_content?
        return "" if !empty_content? and !content_is_set?
        rv = tag(indent) do |next_indent|
          if empty_content?
            ""
          else
            xmled_content
          end
        end
      else
        rv = tag(indent) do |next_indent|
          self.class.to_element_methods.collect do |method_name|
            __send__(method_name, false, next_indent)
          end
        end
      end
      rv = convert(rv) if need_convert
      rv
    end

    def have_xml_content?
      false
    end

    def need_base64_encode?
      false
    end

    def set_next_element(tag_name, next_element)
      klass = next_element.class
      prefix = ""
      prefix << "#{klass.required_prefix}_" if klass.required_prefix
      key = "#{prefix}#{tag_name.gsub(/-/, '_')}"
      if self.class.plural_forms.has_key?(key)
        ary = __send__("#{self.class.plural_forms[key]}")
        ary << next_element
      else
        __send__("#{key}=", next_element)
      end
    end

    protected
    def have_required_elements?
      self.class::MODELS.all? do |tag, uri, occurs, getter|
        if occurs.nil? or occurs == "+"
          child = __send__(getter)
          if child.is_a?(Array)
            children = child
            children.any? {|c| c.have_required_elements?}
          else
            !child.to_s.empty?
          end
        else
          true
        end
      end
    end

    private
    def initialize_variables(attrs)
      normalized_attrs = {}
      attrs.each do |key, value|
        normalized_attrs[key.to_s] = value
      end
      self.class.need_initialize_variables.each do |variable_name|
        value = normalized_attrs[variable_name.to_s]
        if value
          __send__("#{variable_name}=", value)
        else
          instance_variable_set("@#{variable_name}", nil)
        end
      end
      initialize_have_children_elements
      @content = normalized_attrs["content"] if self.class.have_content?
    end

    def initialize_have_children_elements
      self.class.have_children_elements.each do |variable_name, plural_name|
        instance_variable_set("@#{variable_name}", [])
      end
    end

    def tag(indent, additional_attrs={}, &block)
      next_indent = indent + INDENT

      attrs = collect_attrs
      return "" if attrs.nil?

      return "" unless have_required_elements?

      attrs.update(additional_attrs)
      start_tag = make_start_tag(indent, next_indent, attrs.dup)

      if block
        content = block.call(next_indent)
      else
        content = []
      end

      if content.is_a?(String)
        content = [content]
        start_tag << ">"
        end_tag = "</#{full_name}>"
      else
        content = content.reject{|x| x.empty?}
        if content.empty?
          return "" if attrs.empty?
          end_tag = "/>"
        else
          start_tag << ">\n"
          end_tag = "\n#{indent}</#{full_name}>"
        end
      end
      
      start_tag + content.join("\n") + end_tag
    end

    def make_start_tag(indent, next_indent, attrs)
      start_tag = ["#{indent}<#{full_name}"]
      unless attrs.empty?
        start_tag << attrs.collect do |key, value|
          %Q[#{h key}="#{h value}"]
        end.join("\n#{next_indent}")
      end
      start_tag.join(" ")
    end

    def collect_attrs
      attrs = {}
      _attrs.each do |name, required, alias_name|
        value = __send__(alias_name || name)
        return nil if required and value.nil?
        next if value.nil?
        return nil if attrs.has_key?(name)
        attrs[name] = value
      end
      attrs
    end
    
    def tag_name_with_prefix(prefix)
      "#{prefix}:#{tag_name}"
    end

    # For backward compatibility
    def calc_indent
      ''
    end

    def children
      rv = []
      self.class.models.each do |name, uri, occurs, getter|
        value = __send__(getter)
        next if value.nil?
        value = [value] unless value.is_a?(Array)
        value.each do |v|
          rv << v if v.is_a?(Element)
        end
      end
      rv
    end

    def _tags
      rv = []
      self.class.models.each do |name, uri, occurs, getter, plural|
        value = __send__(getter)
        next if value.nil?
        if plural and value.is_a?(Array)
          rv.concat([[uri, name]] * value.size)
        else
          rv << [uri, name]
        end
      end
      rv
    end

    def _attrs
      self.class.get_attributes.collect do |name, uri, required, element_name|
        [element_name, required, name]
      end
    end

    def __validate(ignore_unknown_element, tags=_tags, recursive=true)
      if recursive
        children.compact.each do |child|
          child.validate
        end
      end
      must_call_validators = self.class.must_call_validators
      tags = tag_filter(tags.dup)
      p tags if DEBUG
      must_call_validators.each do |uri, prefix|
        _validate(ignore_unknown_element, tags[uri], uri)
        meth = "#{prefix}_validate"
        if !prefix.empty? and respond_to?(meth, true)
          __send__(meth, ignore_unknown_element, tags[uri], uri)
        end
      end
    end

    def validate_attribute
      _attrs.each do |a_name, required, alias_name|
        value = instance_variable_get("@#{alias_name || a_name}")
        if required and value.nil?
          raise MissingAttributeError.new(tag_name, a_name)
        end
        __send__("#{alias_name || a_name}=", value)
      end
    end

    def _validate(ignore_unknown_element, tags, uri, models=self.class.models)
      count = 1
      do_redo = false
      not_shift = false
      tag = nil
      models = models.find_all {|model| model[1] == uri}
      element_names = models.collect {|model| model[0]}
      if tags
        tags_size = tags.size
        tags = tags.sort_by {|x| element_names.index(x) || tags_size}
      end

      _tags = tags.dup if tags
      models.each_with_index do |model, i|
        name, model_uri, occurs, getter = model

        if DEBUG
          p "before"
          p tags
          p model
        end

        if not_shift
          not_shift = false
        elsif tags
          tag = tags.shift
        end

        if DEBUG
          p "mid"
          p count
        end

        case occurs
        when '?'
          if count > 2
            raise TooMuchTagError.new(name, tag_name)
          else
            if name == tag
              do_redo = true
            else
              not_shift = true
            end
          end
        when '*'
          if name == tag
            do_redo = true
          else
            not_shift = true
          end
        when '+'
          if name == tag
            do_redo = true
          else
            if count > 1
              not_shift = true
            else
              raise MissingTagError.new(name, tag_name)
            end
          end
        else
          if name == tag
            if models[i+1] and models[i+1][0] != name and
                tags and tags.first == name
              raise TooMuchTagError.new(name, tag_name)
            end
          else
            raise MissingTagError.new(name, tag_name)
          end
        end

        if DEBUG
          p "after"
          p not_shift
          p do_redo
          p tag
        end

        if do_redo
          do_redo = false
          count += 1
          redo
        else
          count = 1
        end

      end

      if !ignore_unknown_element and !tags.nil? and !tags.empty?
        raise NotExpectedTagError.new(tags.first, uri, tag_name)
      end

    end

    def tag_filter(tags)
      rv = {}
      tags.each do |tag|
        rv[tag[0]] = [] unless rv.has_key?(tag[0])
        rv[tag[0]].push(tag[1])
      end
      rv
    end

    def empty_content?
      false
    end

    def content_is_set?
      if have_xml_content?
        __send__(self.class.xml_getter)
      else
        content
      end
    end

    def xmled_content
      if have_xml_content?
        __send__(self.class.xml_getter).to_s
      else
        _content = content
        _content = Base64.encode64(_content) if need_base64_encode?
        h(_content)
      end
    end
  end

  module RootElementMixin

    include XMLStyleSheetMixin
    
    attr_reader :output_encoding
    attr_reader :feed_type, :feed_subtype, :feed_version
    attr_accessor :version, :encoding, :standalone
    def initialize(feed_version, version=nil, encoding=nil, standalone=nil)
      super()
      @feed_type = nil
      @feed_subtype = nil
      @feed_version = feed_version
      @version = version || '1.0'
      @encoding = encoding
      @standalone = standalone
      @output_encoding = nil
    end

    def feed_info
      [@feed_type, @feed_version, @feed_subtype]
    end

    def output_encoding=(enc)
      @output_encoding = enc
      self.converter = Converter.new(@output_encoding, @encoding)
    end

    def setup_maker(maker)
      maker.version = version
      maker.encoding = encoding
      maker.standalone = standalone

      xml_stylesheets.each do |xss|
        xss.setup_maker(maker)
      end

      super
    end

    def to_feed(type, &block)
      Maker.make(type) do |maker|
        setup_maker(maker)
        block.call(maker) if block
      end
    end

    def to_rss(type, &block)
      to_feed("rss#{type}", &block)
    end

    def to_atom(type, &block)
      to_feed("atom:#{type}", &block)
    end

    def to_xml(type=nil, &block)
      if type.nil? or same_feed_type?(type)
        to_s
      else
        to_feed(type, &block).to_s
      end
    end

    private
    def same_feed_type?(type)
      if /^(atom|rss)?(\d+\.\d+)?(?::(.+))?$/i =~ type
        feed_type = ($1 || @feed_type).downcase
        feed_version = $2 || @feed_version
        feed_subtype = $3 || @feed_subtype
        [feed_type, feed_version, feed_subtype] == feed_info
      else
        false
      end
    end

    def tag(indent, attrs={}, &block)
      rv = super(indent, ns_declarations.merge(attrs), &block)
      return rv if rv.empty?
      "#{xmldecl}#{xml_stylesheet_pi}#{rv}"
    end

    def xmldecl
      rv = %Q[<?xml version="#{@version}"]
      if @output_encoding or @encoding
        rv << %Q[ encoding="#{@output_encoding or @encoding}"]
      end
      rv << %Q[ standalone="yes"] if @standalone
      rv << "?>\n"
      rv
    end
    
    def ns_declarations
      decls = {}
      self.class::NSPOOL.collect do |prefix, uri|
        prefix = ":#{prefix}" unless prefix.empty?
        decls["xmlns#{prefix}"] = uri
      end
      decls
    end

    def maker_target(target)
      target
    end
  end
end
PK     Y\       rss/xml-stylesheet.rbnu [        require "rss/utils"

module RSS

  module XMLStyleSheetMixin
    attr_accessor :xml_stylesheets
    def initialize(*args)
      super
      @xml_stylesheets = []
    end
    
    private
    def xml_stylesheet_pi
      xsss = @xml_stylesheets.collect do |xss|
        pi = xss.to_s
        pi = nil if /\A\s*\z/ =~ pi
        pi
      end.compact
      xsss.push("") unless xsss.empty?
      xsss.join("\n")
    end
  end

  class XMLStyleSheet

    include Utils

    ATTRIBUTES = %w(href type title media charset alternate)

    GUESS_TABLE = {
      "xsl" => "text/xsl",
      "css" => "text/css",
    }

    attr_accessor(*ATTRIBUTES)
    attr_accessor(:do_validate)
    def initialize(*attrs)
      if attrs.size == 1 and
          (attrs.first.is_a?(Hash) or attrs.first.is_a?(Array))
        attrs = attrs.first
      end
      @do_validate = true
      ATTRIBUTES.each do |attr|
        __send__("#{attr}=", nil)
      end
      vars = ATTRIBUTES.dup
      vars.unshift(:do_validate)
      attrs.each do |name, value|
        if vars.include?(name.to_s)
          __send__("#{name}=", value)
        end
      end
    end

    def to_s
      rv = ""
      if @href
        rv << %Q[<?xml-stylesheet]
        ATTRIBUTES.each do |name|
          if __send__(name)
            rv << %Q[ #{name}="#{h __send__(name)}"]
          end
        end
        rv << %Q[?>]
      end
      rv
    end

    remove_method(:href=)
    def href=(value)
      @href = value
      if @href and @type.nil?
        @type = guess_type(@href)
      end
      @href
    end

    remove_method(:alternate=)
    def alternate=(value)
      if value.nil? or /\A(?:yes|no)\z/ =~ value
        @alternate = value
      else
        if @do_validate
          args = ["?xml-stylesheet?", %Q[alternate="#{value}"]]
          raise NotAvailableValueError.new(*args)
        end
      end
      @alternate
    end

    def setup_maker(maker)
      xss = maker.xml_stylesheets.new_xml_stylesheet
      ATTRIBUTES.each do |attr|
        xss.__send__("#{attr}=", __send__(attr))
      end
    end
    
    private
    def guess_type(filename)
      /\.([^.]+)$/ =~ filename
      GUESS_TABLE[$1]
    end

  end
end
PK     Y\o      rss/slash.rbnu [        require 'rss/1.0'

module RSS
  SLASH_PREFIX = 'slash'
  SLASH_URI = "http://purl.org/rss/1.0/modules/slash/"

  RDF.install_ns(SLASH_PREFIX, SLASH_URI)

  module SlashModel
    extend BaseModel

    ELEMENT_INFOS = \
    [
     ["section"],
     ["department"],
     ["comments", :positive_integer],
     ["hit_parade", :csv_integer],
    ]

    class << self
      def append_features(klass)
        super

        return if klass.instance_of?(Module)
        klass.install_must_call_validator(SLASH_PREFIX, SLASH_URI)
        ELEMENT_INFOS.each do |name, type, *additional_infos|
          full_name = "#{SLASH_PREFIX}_#{name}"
          klass.install_text_element(full_name, SLASH_URI, "?",
                                     full_name, type, name)
        end

        klass.module_eval do
          alias_method(:slash_hit_parades, :slash_hit_parade)
          undef_method(:slash_hit_parade)
          alias_method(:slash_hit_parade, :slash_hit_parade_content)
        end
      end
    end
  end

  class RDF
    class Item; include SlashModel; end
  end

  SlashModel::ELEMENT_INFOS.each do |name, type|
    accessor_base = "#{SLASH_PREFIX}_#{name}"
    BaseListener.install_get_text_element(SLASH_URI, name, accessor_base)
  end
end
PK     Y\LN{
  {
    rss/utils.rbnu [        module RSS
  module Utils
    module_function

    # Convert a name_with_underscores to CamelCase.
    def to_class_name(name)
      name.split(/[_\-]/).collect do |part|
        "#{part[0, 1].upcase}#{part[1..-1]}"
      end.join("")
    end
    
    def get_file_and_line_from_caller(i=0)
      file, line, = caller[i].split(':')
      line = line.to_i
      line += 1 if i.zero?
      [file, line]
    end

    # escape '&', '"', '<' and '>' for use in HTML.
    def html_escape(s)
      s.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
    end
    alias h html_escape
    
    # If +value+ is an instance of class +klass+, return it, else
    # create a new instance of +klass+ with value +value+.
    def new_with_value_if_need(klass, value)
      if value.is_a?(klass)
        value
      else
        klass.new(value)
      end
    end

    def element_initialize_arguments?(args)
      [true, false].include?(args[0]) and args[1].is_a?(Hash)
    end

    module YesCleanOther
      module_function
      def parse(value)
        if [true, false, nil].include?(value)
          value
        else
          case value.to_s
          when /\Ayes\z/i
            true
          when /\Aclean\z/i
            false
          else
            nil
          end
        end
      end
    end

    module YesOther
      module_function
      def parse(value)
        if [true, false].include?(value)
          value
        else
          /\Ayes\z/i.match(value.to_s) ? true : false
        end
      end
    end

    module CSV
      module_function
      def parse(value, &block)
        if value.is_a?(String)
          value = value.strip.split(/\s*,\s*/)
          value = value.collect(&block) if block_given?
          value
        else
          value
        end
      end
    end

    module InheritedReader
      def inherited_reader(constant_name)
        base_class = inherited_base
        result = base_class.const_get(constant_name)
        found_base_class = false
        ancestors.reverse_each do |klass|
          if found_base_class
            if klass.const_defined?(constant_name)
              result = yield(result, klass.const_get(constant_name))
            end
          else
            found_base_class = klass == base_class
          end
        end
        result
      end

      def inherited_array_reader(constant_name)
        inherited_reader(constant_name) do |result, current|
          current + result
        end
      end

      def inherited_hash_reader(constant_name)
        inherited_reader(constant_name) do |result, current|
          result.merge(current)
        end
      end
    end
  end
end
PK     Y\&@      rss/taxonomy.rbnu [        require "rss/1.0"
require "rss/dublincore"

module RSS

  TAXO_PREFIX = "taxo"
  TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/"

  RDF.install_ns(TAXO_PREFIX, TAXO_URI)

  TAXO_ELEMENTS = []

  %w(link).each do |name|
    full_name = "#{TAXO_PREFIX}_#{name}"
    BaseListener.install_get_text_element(TAXO_URI, name, full_name)
    TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}"
  end

  %w(topic topics).each do |name|
    class_name = Utils.to_class_name(name)
    BaseListener.install_class_name(TAXO_URI, name, "Taxonomy#{class_name}")
    TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}"
  end

  module TaxonomyTopicsModel
    extend BaseModel
    
    def self.append_features(klass)
      super

      klass.install_must_call_validator(TAXO_PREFIX, TAXO_URI)
      %w(topics).each do |name|
        klass.install_have_child_element(name, TAXO_URI, "?",
                                         "#{TAXO_PREFIX}_#{name}")
      end
    end

    class TaxonomyTopics < Element
      include RSS10
      
      Bag = ::RSS::RDF::Bag

      class << self
        def required_prefix
          TAXO_PREFIX
        end
        
        def required_uri
          TAXO_URI
        end
      end

      @tag_name = "topics"
      
      install_have_child_element("Bag", RDF::URI, nil)
      install_must_call_validator('rdf', RDF::URI)

      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.Bag = args[0]
        end
        self.Bag ||= Bag.new
      end

      def full_name
        tag_name_with_prefix(TAXO_PREFIX)
      end

      def maker_target(target)
        target.taxo_topics
      end

      def resources
        if @Bag
          @Bag.lis.collect do |li|
            li.resource
          end
        else
          []
        end
      end
    end
  end
  
  module TaxonomyTopicModel
    extend BaseModel
    
    def self.append_features(klass)
      super
      var_name = "#{TAXO_PREFIX}_topic"
      klass.install_have_children_element("topic", TAXO_URI, "*", var_name)
    end

    class TaxonomyTopic < Element
      include RSS10

      include DublinCoreModel
      include TaxonomyTopicsModel
      
      class << self
        def required_prefix
          TAXO_PREFIX
        end
        
        def required_uri
          TAXO_URI
        end
      end

      @tag_name = "topic"

      install_get_attribute("about", ::RSS::RDF::URI, true, nil, nil,
                            "#{RDF::PREFIX}:about")
      install_text_element("link", TAXO_URI, "?", "#{TAXO_PREFIX}_link")
        
      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.about = args[0]
        end
      end

      def full_name
        tag_name_with_prefix(TAXO_PREFIX)
      end

      def maker_target(target)
        target.new_taxo_topic
      end
    end
  end

  class RDF
    include TaxonomyTopicModel
    class Channel
      include TaxonomyTopicsModel
    end
    class Item; include TaxonomyTopicsModel; end
  end
end
PK     Y\Y%  %  
  rss/0.9.rbnu [        require "rss/parser"

module RSS

  module RSS09
    NSPOOL = {}
    ELEMENTS = []

    def self.append_features(klass)
      super
      
      klass.install_must_call_validator('', "")
    end
  end

  class Rss < Element

    include RSS09
    include RootElementMixin

    %w(channel).each do |name|
      install_have_child_element(name, "", nil)
    end

    attr_writer :feed_version
    alias_method(:rss_version, :feed_version)
    alias_method(:rss_version=, :feed_version=)

    def initialize(feed_version, version=nil, encoding=nil, standalone=nil)
      super
      @feed_type = "rss"
    end

    def items
      if @channel
        @channel.items
      else
        []
      end
    end

    def image
      if @channel
        @channel.image
      else
        nil
      end
    end

    def textinput
      if @channel
        @channel.textInput
      else
        nil
      end
    end

    def setup_maker_elements(maker)
      super
      items.each do |item|
        item.setup_maker(maker.items)
      end
      image.setup_maker(maker) if image
      textinput.setup_maker(maker) if textinput
    end

    private
    def _attrs
      [
        ["version", true, "feed_version"],
      ]
    end

    class Channel < Element

      include RSS09

      [
        ["title", nil, :text],
        ["link", nil, :text],
        ["description", nil, :text],
        ["language", nil, :text],
        ["copyright", "?", :text],
        ["managingEditor", "?", :text],
        ["webMaster", "?", :text],
        ["rating", "?", :text],
        ["pubDate", "?", :date, :rfc822],
        ["lastBuildDate", "?", :date, :rfc822],
        ["docs", "?", :text],
        ["cloud", "?", :have_attribute],
        ["skipDays", "?", :have_child],
        ["skipHours", "?", :have_child],
        ["image", nil, :have_child],
        ["item", "*", :have_children],
        ["textInput", "?", :have_child],
      ].each do |name, occurs, type, *args|
        __send__("install_#{type}_element", name, "", occurs, name, *args)
      end
      alias date pubDate
      alias date= pubDate=

      private
      def maker_target(maker)
        maker.channel
      end

      def setup_maker_elements(channel)
        super
        [
          [skipDays, "day"],
          [skipHours, "hour"],
        ].each do |skip, key|
          if skip
            skip.__send__("#{key}s").each do |val|
              target_skips = channel.__send__("skip#{key.capitalize}s")
              new_target = target_skips.__send__("new_#{key}")
              new_target.content = val.content
            end
          end
        end
      end

      def not_need_to_call_setup_maker_variables
        %w(image textInput)
      end
    
      class SkipDays < Element
        include RSS09

        [
          ["day", "*"]
        ].each do |name, occurs|
          install_have_children_element(name, "", occurs)
        end

        class Day < Element
          include RSS09

          content_setup

          def initialize(*args)
            if Utils.element_initialize_arguments?(args)
              super
            else
              super()
              self.content = args[0]
            end
          end
      
        end
        
      end
      
      class SkipHours < Element
        include RSS09

        [
          ["hour", "*"]
        ].each do |name, occurs|
          install_have_children_element(name, "", occurs)
        end

        class Hour < Element
          include RSS09

          content_setup(:integer)

          def initialize(*args)
            if Utils.element_initialize_arguments?(args)
              super
            else
              super()
              self.content = args[0]
            end
          end
        end
        
      end
      
      class Image < Element

        include RSS09
        
        %w(url title link).each do |name|
          install_text_element(name, "", nil)
        end
        [
          ["width", :integer],
          ["height", :integer],
          ["description"],
        ].each do |name, type|
          install_text_element(name, "", "?", name, type)
        end

        def initialize(*args)
          if Utils.element_initialize_arguments?(args)
            super
          else
            super()
            self.url = args[0]
            self.title = args[1]
            self.link = args[2]
            self.width = args[3]
            self.height = args[4]
            self.description = args[5]
          end
        end

        private
        def maker_target(maker)
          maker.image
        end
      end

      class Cloud < Element

        include RSS09

        [
          ["domain", "", true],
          ["port", "", true, :integer],
          ["path", "", true],
          ["registerProcedure", "", true],
          ["protocol", "", true],
        ].each do |name, uri, required, type|
          install_get_attribute(name, uri, required, type)
        end

        def initialize(*args)
          if Utils.element_initialize_arguments?(args)
            super
          else
            super()
            self.domain = args[0]
            self.port = args[1]
            self.path = args[2]
            self.registerProcedure = args[3]
            self.protocol = args[4]
          end
        end
      end
      
      class Item < Element
        
        include RSS09

        [
          ["title", '?', :text],
          ["link", '?', :text],
          ["description", '?', :text],
          ["category", '*', :have_children, "categories"],
          ["source", '?', :have_child],
          ["enclosure", '?', :have_child],
        ].each do |tag, occurs, type, *args|
          __send__("install_#{type}_element", tag, "", occurs, tag, *args)
        end

        private
        def maker_target(items)
          if items.respond_to?("items")
            # For backward compatibility
            items = items.items
          end
          items.new_item
        end

        def setup_maker_element(item)
          super
          @enclosure.setup_maker(item) if @enclosure
          @source.setup_maker(item) if @source
        end
        
        class Source < Element

          include RSS09

          [
            ["url", "", true]
          ].each do |name, uri, required|
            install_get_attribute(name, uri, required)
          end
          
          content_setup

          def initialize(*args)
            if Utils.element_initialize_arguments?(args)
              super
            else
              super()
              self.url = args[0]
              self.content = args[1]
            end
          end

          private
          def maker_target(item)
            item.source
          end

          def setup_maker_attributes(source)
            source.url = url
            source.content = content
          end
        end

        class Enclosure < Element

          include RSS09

          [
            ["url", "", true],
            ["length", "", true, :integer],
            ["type", "", true],
          ].each do |name, uri, required, type|
            install_get_attribute(name, uri, required, type)
          end

          def initialize(*args)
            if Utils.element_initialize_arguments?(args)
              super
            else
              super()
              self.url = args[0]
              self.length = args[1]
              self.type = args[2]
            end
          end

          private
          def maker_target(item)
            item.enclosure
          end

          def setup_maker_attributes(enclosure)
            enclosure.url = url
            enclosure.length = length
            enclosure.type = type
          end
        end

        class Category < Element

          include RSS09
          
          [
            ["domain", "", false]
          ].each do |name, uri, required|
            install_get_attribute(name, uri, required)
          end

          content_setup

          def initialize(*args)
            if Utils.element_initialize_arguments?(args)
              super
            else
              super()
              self.domain = args[0]
              self.content = args[1]
            end
          end

          private
          def maker_target(item)
            item.new_category
          end

          def setup_maker_attributes(category)
            category.domain = domain
            category.content = content
          end
          
        end

      end
      
      class TextInput < Element

        include RSS09

        %w(title description name link).each do |name|
          install_text_element(name, "", nil)
        end

        def initialize(*args)
          if Utils.element_initialize_arguments?(args)
            super
          else
            super()
            self.title = args[0]
            self.description = args[1]
            self.name = args[2]
            self.link = args[3]
          end
        end

        private
        def maker_target(maker)
          maker.textinput
        end
      end
      
    end
    
  end

  RSS09::ELEMENTS.each do |name|
    BaseListener.install_get_text_element("", name, name)
  end

  module ListenerMixin
    private
    def initial_start_rss(tag_name, prefix, attrs, ns)
      check_ns(tag_name, prefix, ns, "")
      
      @rss = Rss.new(attrs['version'], @version, @encoding, @standalone)
      @rss.do_validate = @do_validate
      @rss.xml_stylesheets = @xml_stylesheets
      @last_element = @rss
      pr = Proc.new do |text, tags|
        @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate
      end
      @proc_stack.push(pr)
    end
    
  end

end
PK     Y\(|  |    rss/xmlscanner.rbnu [        require 'xmlscan/scanner'
require 'stringio'

module RSS
  
  class XMLScanParser < BaseParser
    
    class << self
      def listener
        XMLScanListener
      end
    end
    
    private
    def _parse
      begin
        if @rss.is_a?(String)
          input = StringIO.new(@rss)
        else
          input = @rss
        end
        scanner = XMLScan::XMLScanner.new(@listener)
        scanner.parse(input)
      rescue XMLScan::Error => e
        lineno = e.lineno || scanner.lineno || input.lineno
        raise NotWellFormedError.new(lineno){e.message}
      end
    end
    
  end

  class XMLScanListener < BaseListener
    
    include XMLScan::Visitor
    include ListenerMixin

    ENTITIES = {
      'lt' => '<',
      'gt' => '>',
      'amp' => '&',
      'quot' => '"',
      'apos' => '\''
    }

    def on_xmldecl_version(str)
      @version = str
    end

    def on_xmldecl_encoding(str)
      @encoding = str
    end

    def on_xmldecl_standalone(str)
      @standalone = str
    end

    def on_xmldecl_end
      xmldecl(@version, @encoding, @standalone == "yes")
    end

    alias_method(:on_pi, :instruction)
    alias_method(:on_chardata, :text)
    alias_method(:on_cdata, :text)

    def on_etag(name)
      tag_end(name)
    end

    def on_entityref(ref)
      text(entity(ref))
    end

    def on_charref(code)
      text([code].pack('U'))
    end

    alias_method(:on_charref_hex, :on_charref)

    def on_stag(name)
      @attrs = {}
    end

    def on_attribute(name)
      @attrs[name] = @current_attr = ''
    end

    def on_attr_value(str)
      @current_attr << str
    end

    def on_attr_entityref(ref)
      @current_attr << entity(ref)
    end

    def on_attr_charref(code)
      @current_attr << [code].pack('U')
    end

    alias_method(:on_attr_charref_hex, :on_attr_charref)

    def on_stag_end(name)
      tag_start(name, @attrs)
    end

    def on_stag_end_empty(name)
      tag_start(name, @attrs)
      tag_end(name)
    end

    private
    def entity(ref)
      ent = ENTITIES[ref]
      if ent
        ent
      else
        wellformed_error("undefined entity: #{ref}")
      end
    end
  end

end
PK     Y\#      rss/syndication.rbnu [        require "rss/1.0"

module RSS

  SY_PREFIX = 'sy'
  SY_URI = "http://purl.org/rss/1.0/modules/syndication/"

  RDF.install_ns(SY_PREFIX, SY_URI)

  module SyndicationModel
    
    extend BaseModel
    
    ELEMENTS = []
    
    def self.append_features(klass)
      super

      klass.install_must_call_validator(SY_PREFIX, SY_URI)
      klass.module_eval do
        [
          ["updatePeriod"],
          ["updateFrequency", :positive_integer]
        ].each do |name, type|
          install_text_element(name, SY_URI, "?",
                               "#{SY_PREFIX}_#{name}", type,
                               "#{SY_PREFIX}:#{name}")
        end

        %w(updateBase).each do |name|
          install_date_element(name, SY_URI, "?",
                               "#{SY_PREFIX}_#{name}", 'w3cdtf',
                               "#{SY_PREFIX}:#{name}")
        end
      end

      klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
        alias_method(:_sy_updatePeriod=, :sy_updatePeriod=)
        def sy_updatePeriod=(new_value)
          new_value = new_value.strip
          validate_sy_updatePeriod(new_value) if @do_validate
          self._sy_updatePeriod = new_value
        end
      EOC
    end

    private
    SY_UPDATEPERIOD_AVAILABLE_VALUES = %w(hourly daily weekly monthly yearly)
    def validate_sy_updatePeriod(value)
      unless SY_UPDATEPERIOD_AVAILABLE_VALUES.include?(value)
        raise NotAvailableValueError.new("updatePeriod", value)
      end
    end
  end

  class RDF
    class Channel; include SyndicationModel; end
  end

  prefix_size = SY_PREFIX.size + 1
  SyndicationModel::ELEMENTS.uniq!
  SyndicationModel::ELEMENTS.each do |full_name|
    name = full_name[prefix_size..-1]
    BaseListener.install_get_text_element(SY_URI, name, full_name)
  end

end
PK     Y\vEJ  J    rss/xmlparser.rbnu [        begin
  require "xml/parser"
rescue LoadError
  require "xmlparser"
end

begin
  require "xml/encoding-ja"
rescue LoadError
  require "xmlencoding-ja"
  if defined?(Kconv)
    module XMLEncoding_ja
      class SJISHandler
        include Kconv
      end
    end
  end
end

module XML
  class Parser
    unless defined?(Error)
      Error = ::XMLParserError
    end
  end
end

module RSS
  
  class REXMLLikeXMLParser < ::XML::Parser
    
    include ::XML::Encoding_ja

    def listener=(listener)
      @listener = listener
    end

    def startElement(name, attrs)
      @listener.tag_start(name, attrs)
    end
    
    def endElement(name)
      @listener.tag_end(name)
    end

    def character(data)
      @listener.text(data)
    end

    def xmlDecl(version, encoding, standalone)
      @listener.xmldecl(version, encoding, standalone == 1)
    end

    def processingInstruction(target, content)
      @listener.instruction(target, content)
    end

  end

  class XMLParserParser < BaseParser

    class << self
      def listener
        XMLParserListener
      end
    end
    
    private
    def _parse
      begin
        parser = REXMLLikeXMLParser.new
        parser.listener = @listener
        parser.parse(@rss)
      rescue ::XML::Parser::Error => e
        raise NotWellFormedError.new(parser.line){e.message}
      end
    end
    
  end
  
  class XMLParserListener < BaseListener

    include ListenerMixin
    
    def xmldecl(version, encoding, standalone)
      super
      # Encoding is converted to UTF-8 when XMLParser parses XML.
      @encoding = 'UTF-8'
    end

  end

end
PK     Y\J"u"  u"  
  rss/1.0.rbnu [        require "rss/parser"

module RSS

  module RSS10
    NSPOOL = {}
    ELEMENTS = []

    def self.append_features(klass)
      super
      
      klass.install_must_call_validator('', ::RSS::URI)
    end

  end

  class RDF < Element

    include RSS10
    include RootElementMixin

    class << self

      def required_uri
        URI
      end

    end

    @tag_name = 'RDF'

    PREFIX = 'rdf'
    URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"

    install_ns('', ::RSS::URI)
    install_ns(PREFIX, URI)

    [
      ["channel", nil],
      ["image", "?"],
      ["item", "+", :children],
      ["textinput", "?"],
    ].each do |tag, occurs, type|
      type ||= :child
      __send__("install_have_#{type}_element", tag, ::RSS::URI, occurs)
    end

    alias_method(:rss_version, :feed_version)
    def initialize(version=nil, encoding=nil, standalone=nil)
      super('1.0', version, encoding, standalone)
      @feed_type = "rss"
    end

    def full_name
      tag_name_with_prefix(PREFIX)
    end

    class Li < Element

      include RSS10

      class << self
        def required_uri
          URI
        end
      end
      
      [
        ["resource", [URI, ""], true]
      ].each do |name, uri, required|
        install_get_attribute(name, uri, required)
      end
      
      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.resource = args[0]
        end
      end

      def full_name
        tag_name_with_prefix(PREFIX)
      end
    end

    class Seq < Element

      include RSS10

      Li = ::RSS::RDF::Li

      class << self
        def required_uri
          URI
        end
      end

      @tag_name = 'Seq'
      
      install_have_children_element("li", URI, "*")
      install_must_call_validator('rdf', ::RSS::RDF::URI)
      
      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          @li = args[0] if args[0]
        end
      end

      def full_name
        tag_name_with_prefix(PREFIX)
      end
      
      def setup_maker(target)
        lis.each do |li|
          target << li.resource
        end
      end
    end

    class Bag < Element

      include RSS10

      Li = ::RSS::RDF::Li

      class << self
        def required_uri
          URI
        end
      end

      @tag_name = 'Bag'
      
      install_have_children_element("li", URI, "*")
      install_must_call_validator('rdf', URI)
      
      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          @li = args[0] if args[0]
        end
      end

      def full_name
        tag_name_with_prefix(PREFIX)
      end
      
      def setup_maker(target)
        lis.each do |li|
          target << li.resource
        end
      end
    end

    class Channel < Element

      include RSS10
      
      class << self

        def required_uri
          ::RSS::URI
        end

      end

      [
        ["about", URI, true]
      ].each do |name, uri, required|
        install_get_attribute(name, uri, required, nil, nil,
                              "#{PREFIX}:#{name}")
      end

      [
        ['title', nil, :text],
        ['link', nil, :text],
        ['description', nil, :text],
        ['image', '?', :have_child],
        ['items', nil, :have_child],
        ['textinput', '?', :have_child],
      ].each do |tag, occurs, type|
        __send__("install_#{type}_element", tag, ::RSS::URI, occurs)
      end

      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.about = args[0]
        end
      end

      private
      def maker_target(maker)
        maker.channel
      end
      
      def setup_maker_attributes(channel)
        channel.about = about
      end

      class Image < Element
        
        include RSS10

        class << self
          
          def required_uri
            ::RSS::URI
          end

        end

        [
          ["resource", URI, true]
        ].each do |name, uri, required|
          install_get_attribute(name, uri, required, nil, nil,
                                "#{PREFIX}:#{name}")
        end
      
        def initialize(*args)
          if Utils.element_initialize_arguments?(args)
            super
          else
            super()
            self.resource = args[0]
          end
        end
      end

      class Textinput < Element
        
        include RSS10

        class << self
          
          def required_uri
            ::RSS::URI
          end

        end

        [
          ["resource", URI, true]
        ].each do |name, uri, required|
          install_get_attribute(name, uri, required, nil, nil,
                                "#{PREFIX}:#{name}")
        end
      
        def initialize(*args)
          if Utils.element_initialize_arguments?(args)
            super
          else
            super()
            self.resource = args[0]
          end
        end
      end
      
      class Items < Element

        include RSS10

        Seq = ::RSS::RDF::Seq

        class << self
          
          def required_uri
            ::RSS::URI
          end
          
        end

        install_have_child_element("Seq", URI, nil)
        install_must_call_validator('rdf', URI)
        
        def initialize(*args)
          if Utils.element_initialize_arguments?(args)
            super
          else
            super()
            self.Seq = args[0]
          end
          self.Seq ||= Seq.new
        end

        def resources
          if @Seq
            @Seq.lis.collect do |li|
              li.resource
            end
          else
            []
          end
        end
      end
    end

    class Image < Element

      include RSS10

      class << self
        
        def required_uri
          ::RSS::URI
        end

      end

      [
        ["about", URI, true]
      ].each do |name, uri, required|
        install_get_attribute(name, uri, required, nil, nil,
                              "#{PREFIX}:#{name}")
      end

      %w(title url link).each do |name|
        install_text_element(name, ::RSS::URI, nil)
      end

      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.about = args[0]
        end
      end

      private
      def maker_target(maker)
        maker.image
      end
    end

    class Item < Element

      include RSS10

      class << self

        def required_uri
          ::RSS::URI
        end
        
      end


      [
        ["about", URI, true]
      ].each do |name, uri, required|
        install_get_attribute(name, uri, required, nil, nil,
                              "#{PREFIX}:#{name}")
      end

      [
        ["title", nil],
        ["link", nil],
        ["description", "?"],
      ].each do |tag, occurs|
        install_text_element(tag, ::RSS::URI, occurs)
      end

      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.about = args[0]
        end
      end

      private
      def maker_target(items)
        if items.respond_to?("items")
          # For backward compatibility
          items = items.items
        end
        items.new_item
      end
    end

    class Textinput < Element

      include RSS10

      class << self

        def required_uri
          ::RSS::URI
        end

      end

      [
        ["about", URI, true]
      ].each do |name, uri, required|
        install_get_attribute(name, uri, required, nil, nil,
                              "#{PREFIX}:#{name}")
      end

      %w(title description name link).each do |name|
        install_text_element(name, ::RSS::URI, nil)
      end

      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.about = args[0]
        end
      end

      private
      def maker_target(maker)
        maker.textinput
      end
    end

  end

  RSS10::ELEMENTS.each do |name|
    BaseListener.install_get_text_element(URI, name, name)
  end

  module ListenerMixin
    private
    def initial_start_RDF(tag_name, prefix, attrs, ns)
      check_ns(tag_name, prefix, ns, RDF::URI)

      @rss = RDF.new(@version, @encoding, @standalone)
      @rss.do_validate = @do_validate
      @rss.xml_stylesheets = @xml_stylesheets
      @last_element = @rss
      pr = Proc.new do |text, tags|
        @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate
      end
      @proc_stack.push(pr)
    end
  end

end
PK     Y\P      rss/converter.rbnu [        require "rss/utils"

module RSS

  class Converter
    
    include Utils

    def initialize(to_enc, from_enc=nil)
      normalized_to_enc = to_enc.downcase.gsub(/-/, '_')
      from_enc ||= 'utf-8'
      normalized_from_enc = from_enc.downcase.gsub(/-/, '_')
      if normalized_to_enc == normalized_from_enc
        def_same_enc()
      else
        def_diff_enc = "def_to_#{normalized_to_enc}_from_#{normalized_from_enc}"
        if respond_to?(def_diff_enc)
          __send__(def_diff_enc)
        else
          def_else_enc(to_enc, from_enc)
        end
      end
    end

    def convert(value)
      value
    end

    def def_convert(depth=0)
      instance_eval(<<-EOC, *get_file_and_line_from_caller(depth))
      def convert(value)
        if value.kind_of?(String)
          #{yield('value')}
        else
          value
        end
      end
      EOC
    end

    def def_iconv_convert(to_enc, from_enc, depth=0)
      begin
        require "iconv"
        @iconv = Iconv.new(to_enc, from_enc)
        def_convert(depth+1) do |value|
          <<-EOC
          begin
            @iconv.iconv(#{value})
          rescue Iconv::Failure
            raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}")
          end
          EOC
        end
      rescue LoadError, ArgumentError, SystemCallError
        raise UnknownConversionMethodError.new(to_enc, from_enc)
      end
    end
    
    def def_else_enc(to_enc, from_enc)
      def_iconv_convert(to_enc, from_enc, 0)
    end
    
    def def_same_enc()
      def_convert do |value|
        value
      end
    end

    def def_uconv_convert_if_can(meth, to_enc, from_enc, nkf_arg)
      begin
        require "uconv"
        def_convert(1) do |value|
          <<-EOC
          begin
            Uconv.#{meth}(#{value})
          rescue Uconv::Error
            raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}")
          end
          EOC
        end
      rescue LoadError
        require 'nkf'
        if NKF.const_defined?(:UTF8)
          def_convert(1) do |value|
            "NKF.nkf(#{nkf_arg.dump}, #{value})"
          end
        else
          def_iconv_convert(to_enc, from_enc, 1)
        end
      end
    end

    def def_to_euc_jp_from_utf_8
      def_uconv_convert_if_can('u8toeuc', 'EUC-JP', 'UTF-8', '-We')
    end
    
    def def_to_utf_8_from_euc_jp
      def_uconv_convert_if_can('euctou8', 'UTF-8', 'EUC-JP', '-Ew')
    end
    
    def def_to_shift_jis_from_utf_8
      def_uconv_convert_if_can('u8tosjis', 'Shift_JIS', 'UTF-8', '-Ws')
    end
    
    def def_to_utf_8_from_shift_jis
      def_uconv_convert_if_can('sjistou8', 'UTF-8', 'Shift_JIS', '-Sw')
    end
    
    def def_to_euc_jp_from_shift_jis
      require "nkf"
      def_convert do |value|
        "NKF.nkf('-Se', #{value})"
      end
    end
    
    def def_to_shift_jis_from_euc_jp
      require "nkf"
      def_convert do |value|
        "NKF.nkf('-Es', #{value})"
      end
    end
    
    def def_to_euc_jp_from_iso_2022_jp
      require "nkf"
      def_convert do |value|
        "NKF.nkf('-Je', #{value})"
      end
    end
    
    def def_to_iso_2022_jp_from_euc_jp
      require "nkf"
      def_convert do |value|
        "NKF.nkf('-Ej', #{value})"
      end
    end

    def def_to_utf_8_from_iso_8859_1
      def_convert do |value|
        "#{value}.unpack('C*').pack('U*')"
      end
    end
    
    def def_to_iso_8859_1_from_utf_8
      def_convert do |value|
        <<-EOC
        array_utf8 = #{value}.unpack('U*')
        array_enc = []
        array_utf8.each do |num|
          if num <= 0xFF
            array_enc << num
          else
            array_enc.concat "&\#\#{num};".unpack('C*')
          end
        end
        array_enc.pack('C*')
        EOC
      end
    end
    
  end
  
end
PK     Y\*:e	  	    rss/maker/2.0.rbnu [        require "rss/2.0"

require "rss/maker/0.9"

module RSS
  module Maker
    
    class RSS20 < RSS09
      
      def initialize(feed_version="2.0")
        super
      end

      class Channel < RSS09::Channel

        private
        def required_variable_names
          %w(link)
        end
        
        class SkipDays < RSS09::Channel::SkipDays
          class Day < RSS09::Channel::SkipDays::Day
          end
        end
        
        class SkipHours < RSS09::Channel::SkipHours
          class Hour < RSS09::Channel::SkipHours::Hour
          end
        end
        
        class Cloud < RSS09::Channel::Cloud
          def to_feed(rss, channel)
            cloud = Rss::Channel::Cloud.new
            set = setup_values(cloud)
            if set
              channel.cloud = cloud
              set_parent(cloud, channel)
              setup_other_elements(rss, cloud)
            end
          end

          private
          def required_variable_names
            %w(domain port path registerProcedure protocol)
          end
        end

        class Categories < RSS09::Channel::Categories
          def to_feed(rss, channel)
            @categories.each do |category|
              category.to_feed(rss, channel)
            end
          end
          
          class Category < RSS09::Channel::Categories::Category
            def to_feed(rss, channel)
              category = Rss::Channel::Category.new
              set = setup_values(category)
              if set
                channel.categories << category
                set_parent(category, channel)
                setup_other_elements(rss, category)
              end
            end

            private
            def required_variable_names
              %w(content)
            end
          end
        end

        class Generator < GeneratorBase
          def to_feed(rss, channel)
            channel.generator = content
          end

          private
          def required_variable_names
            %w(content)
          end
        end
      end
      
      class Image < RSS09::Image
        private
        def required_element?
          false
        end
      end
      
      class Items < RSS09::Items
        class Item < RSS09::Items::Item
          private
          def required_variable_names
            []
          end

          def not_set_required_variables
            vars = super
            if !title {|t| t.have_required_values?} and
                !description {|d| d.have_required_values?}
              vars << "title or description"
            end
            vars
          end

          def variables
            super + ["pubDate"]
          end

          class Guid < RSS09::Items::Item::Guid
            def to_feed(rss, item)
              guid = Rss::Channel::Item::Guid.new
              set = setup_values(guid)
              if set
                item.guid = guid
                set_parent(guid, item)
                setup_other_elements(rss, guid)
              end
            end

            private
            def required_variable_names
              %w(content)
            end
          end

          class Enclosure < RSS09::Items::Item::Enclosure
            def to_feed(rss, item)
              enclosure = Rss::Channel::Item::Enclosure.new
              set = setup_values(enclosure)
              if set
                item.enclosure = enclosure
                set_parent(enclosure, item)
                setup_other_elements(rss, enclosure)
              end
            end

            private
            def required_variable_names
              %w(url length type)
            end
          end

          class Source < RSS09::Items::Item::Source
            def to_feed(rss, item)
              source = Rss::Channel::Item::Source.new
              set = setup_values(source)
              if set
                item.source = source
                set_parent(source, item)
                setup_other_elements(rss, source)
              end
            end

            private
            def required_variable_names
              %w(url content)
            end

            class Links < RSS09::Items::Item::Source::Links
              def to_feed(rss, source)
                return if @links.empty?
                @links.first.to_feed(rss, source)
              end

              class Link < RSS09::Items::Item::Source::Links::Link
                def to_feed(rss, source)
                  source.url = href
                end
              end
            end
          end

          class Categories < RSS09::Items::Item::Categories
            def to_feed(rss, item)
              @categories.each do |category|
                category.to_feed(rss, item)
              end
            end
          
            class Category < RSS09::Items::Item::Categories::Category
              def to_feed(rss, item)
                category = Rss::Channel::Item::Category.new
                set = setup_values(category)
                if set
                  item.categories << category
                  set_parent(category, item)
                  setup_other_elements(rss)
                end
              end

              private
              def required_variable_names
                %w(content)
              end
            end
          end

          class Authors < RSS09::Items::Item::Authors
            def to_feed(rss, item)
              return if @authors.empty?
              @authors.first.to_feed(rss, item)
            end

            class Author < RSS09::Items::Item::Authors::Author
              def to_feed(rss, item)
                item.author = name
              end
            end
          end
        end
      end
      
      class Textinput < RSS09::Textinput
      end
    end
    
    add_maker("2.0", "2.0", RSS20)
    add_maker("rss2.0", "2.0", RSS20)
  end
end
PK     Y\ئf  f    rss/maker/image.rbnu [        require 'rss/image'
require 'rss/maker/1.0'
require 'rss/maker/dublincore'

module RSS
  module Maker
    module ImageItemModel
      def self.append_features(klass)
        super

        name = "#{RSS::IMAGE_PREFIX}_item"
        klass.def_classed_element(name)
      end

      def self.install_image_item(klass)
	klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
          class ImageItem < ImageItemBase
            DublinCoreModel.install_dublin_core(self)
          end
EOC
      end

      class ImageItemBase < Base
        include Maker::DublinCoreModel

        attr_accessor :about, :resource, :image_width, :image_height
        add_need_initialize_variable("about")
        add_need_initialize_variable("resource")
        add_need_initialize_variable("image_width")
        add_need_initialize_variable("image_height")
        alias width= image_width=
        alias width image_width
        alias height= image_height=
        alias height image_height

        def have_required_values?
          @about
        end

        def to_feed(feed, current)
          if current.respond_to?(:image_item=) and have_required_values?
            item = current.class::ImageItem.new
            setup_values(item)
            setup_other_elements(item)
            current.image_item = item
          end
        end
      end
    end

    module ImageFaviconModel
      def self.append_features(klass)
        super

        name = "#{RSS::IMAGE_PREFIX}_favicon"
        klass.def_classed_element(name)
      end

      def self.install_image_favicon(klass)
	klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
          class ImageFavicon < ImageFaviconBase
            DublinCoreModel.install_dublin_core(self)
          end
        EOC
      end

      class ImageFaviconBase < Base
        include Maker::DublinCoreModel

        attr_accessor :about, :image_size
        add_need_initialize_variable("about")
        add_need_initialize_variable("image_size")
        alias size image_size
        alias size= image_size=

        def have_required_values?
          @about and @image_size
        end

        def to_feed(feed, current)
          if current.respond_to?(:image_favicon=) and have_required_values?
            favicon = current.class::ImageFavicon.new
            setup_values(favicon)
            setup_other_elements(favicon)
            current.image_favicon = favicon
          end
        end
      end
    end

    class ChannelBase; include Maker::ImageFaviconModel; end
    
    class ItemsBase
      class ItemBase; include Maker::ImageItemModel; end
    end

    makers.each do |maker|
      maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
        class Channel
          ImageFaviconModel.install_image_favicon(self)
        end

        class Items
          class Item
            ImageItemModel.install_image_item(self)
          end
        end
      EOC
    end
  end
end
PK     Y\ë      rss/maker/content.rbnu [        require 'rss/content'
require 'rss/maker/1.0'
require 'rss/maker/2.0'

module RSS
  module Maker
    module ContentModel
      def self.append_features(klass)
        super

        ::RSS::ContentModel::ELEMENTS.each do |name|
          klass.def_other_element(name)
        end
      end
    end

    class ItemsBase
      class ItemBase; include ContentModel; end
    end
  end
end
PK     Y\}Z[  [    rss/maker/base.rbnu [        require 'forwardable'

require 'rss/rss'

module RSS
  module Maker
    class Base
      extend Utils::InheritedReader

      OTHER_ELEMENTS = []
      NEED_INITIALIZE_VARIABLES = []

      class << self
        def other_elements
          inherited_array_reader("OTHER_ELEMENTS")
        end
        def need_initialize_variables
          inherited_array_reader("NEED_INITIALIZE_VARIABLES")
        end

        def inherited_base
          ::RSS::Maker::Base
        end

        def inherited(subclass)
          subclass.const_set("OTHER_ELEMENTS", [])
          subclass.const_set("NEED_INITIALIZE_VARIABLES", [])
        end

        def add_other_element(variable_name)
          self::OTHER_ELEMENTS << variable_name
        end

        def add_need_initialize_variable(variable_name, init_value="nil")
          self::NEED_INITIALIZE_VARIABLES << [variable_name, init_value]
        end

        def def_array_element(name, plural=nil, klass_name=nil)
          include Enumerable
          extend Forwardable

          plural ||= "#{name}s"
          klass_name ||= Utils.to_class_name(name)
          def_delegators("@#{plural}", :<<, :[], :[]=, :first, :last)
          def_delegators("@#{plural}", :push, :pop, :shift, :unshift)
          def_delegators("@#{plural}", :each, :size, :empty?, :clear)

          add_need_initialize_variable(plural, "[]")

          module_eval(<<-EOC, __FILE__, __LINE__ + 1)
            def new_#{name}
              #{name} = self.class::#{klass_name}.new(@maker)
              @#{plural} << #{name}
              if block_given?
                yield #{name}
              else
                #{name}
              end
            end
            alias new_child new_#{name}

            def to_feed(*args)
              @#{plural}.each do |#{name}|
                #{name}.to_feed(*args)
              end
            end

            def replace(elements)
              @#{plural}.replace(elements.to_a)
            end
          EOC
        end

        def def_classed_element_without_accessor(name, class_name=nil)
          class_name ||= Utils.to_class_name(name)
          add_other_element(name)
          add_need_initialize_variable(name, "make_#{name}")
          module_eval(<<-EOC, __FILE__, __LINE__ + 1)
            private
            def setup_#{name}(feed, current)
              @#{name}.to_feed(feed, current)
            end

            def make_#{name}
              self.class::#{class_name}.new(@maker)
            end
          EOC
        end

        def def_classed_element(name, class_name=nil, attribute_name=nil)
          def_classed_element_without_accessor(name, class_name)
          if attribute_name
            module_eval(<<-EOC, __FILE__, __LINE__ + 1)
              def #{name}
                if block_given?
                  yield(@#{name})
                else
                  @#{name}.#{attribute_name}
                end
              end

              def #{name}=(new_value)
                @#{name}.#{attribute_name} = new_value
              end
            EOC
          else
            attr_reader name
          end
        end

        def def_classed_elements(name, attribute, plural_class_name=nil,
                                 plural_name=nil, new_name=nil)
          plural_name ||= "#{name}s"
          new_name ||= name
          def_classed_element(plural_name, plural_class_name)
          local_variable_name = "_#{name}"
          new_value_variable_name = "new_value"
          additional_setup_code = nil
          if block_given?
            additional_setup_code = yield(local_variable_name,
                                          new_value_variable_name)
          end
          module_eval(<<-EOC, __FILE__, __LINE__ + 1)
            def #{name}
              #{local_variable_name} = #{plural_name}.first
              #{local_variable_name} ? #{local_variable_name}.#{attribute} : nil
            end

            def #{name}=(#{new_value_variable_name})
              #{local_variable_name} =
                #{plural_name}.first || #{plural_name}.new_#{new_name}
              #{additional_setup_code}
              #{local_variable_name}.#{attribute} = #{new_value_variable_name}
            end
          EOC
        end

        def def_other_element(name)
          attr_accessor name
          def_other_element_without_accessor(name)
        end

        def def_other_element_without_accessor(name)
          add_need_initialize_variable(name)
          add_other_element(name)
          module_eval(<<-EOC, __FILE__, __LINE__ + 1)
            def setup_#{name}(feed, current)
              if !@#{name}.nil? and current.respond_to?(:#{name}=)
                current.#{name} = @#{name}
              end
            end
          EOC
        end

        def def_csv_element(name, type=nil)
          def_other_element_without_accessor(name)
          attr_reader(name)
          converter = ""
          if type == :integer
            converter = "{|v| Integer(v)}"
          end
          module_eval(<<-EOC, __FILE__, __LINE__ + 1)
            def #{name}=(value)
              @#{name} = Utils::CSV.parse(value)#{converter}
            end
          EOC
        end
      end

      attr_reader :maker
      def initialize(maker)
        @maker = maker
        @default_values_are_set = false
        initialize_variables
      end

      def have_required_values?
        not_set_required_variables.empty?
      end

      def variable_is_set?
        variables.any? {|var| not __send__(var).nil?}
      end

      private
      def initialize_variables
        self.class.need_initialize_variables.each do |variable_name, init_value|
          instance_eval("@#{variable_name} = #{init_value}", __FILE__, __LINE__)
        end
      end

      def setup_other_elements(feed, current=nil)
        current ||= current_element(feed)
        self.class.other_elements.each do |element|
          __send__("setup_#{element}", feed, current)
        end
      end

      def current_element(feed)
        feed
      end

      def set_default_values(&block)
        return yield if @default_values_are_set

        begin
          @default_values_are_set = true
          _set_default_values(&block)
        ensure
          @default_values_are_set = false
        end
      end

      def _set_default_values(&block)
        yield
      end

      def setup_values(target)
        set = false
        if have_required_values?
          variables.each do |var|
            setter = "#{var}="
            if target.respond_to?(setter)
              value = __send__(var)
              if value
                target.__send__(setter, value)
                set = true
              end
            end
          end
        end
        set
      end

      def set_parent(target, parent)
        target.parent = parent if target.class.need_parent?
      end

      def variables
        self.class.need_initialize_variables.find_all do |name, init|
          "nil" == init
        end.collect do |name, init|
          name
        end
      end

      def not_set_required_variables
        required_variable_names.find_all do |var|
          __send__(var).nil?
        end
      end

      def required_variables_are_set?
        required_variable_names.each do |var|
          return false if __send__(var).nil?
        end
        true
      end
    end

    module AtomPersonConstructBase
      def self.append_features(klass)
        super

        klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
          %w(name uri email).each do |element|
            attr_accessor element
            add_need_initialize_variable(element)
          end
        EOC
      end
    end

    module AtomTextConstructBase
      module EnsureXMLContent
        class << self
          def included(base)
            super
            base.class_eval do
              %w(type content xml_content).each do |element|
                attr_reader element
                attr_writer element if element != "xml_content"
                add_need_initialize_variable(element)
              end

              alias_method(:xhtml, :xml_content)
            end
          end
        end

        def ensure_xml_content(content)
          xhtml_uri = ::RSS::Atom::XHTML_URI
          unless content.is_a?(RSS::XML::Element) and
              ["div", xhtml_uri] == [content.name, content.uri]
            children = content
            children = [children] unless content.is_a?(Array)
            children = set_xhtml_uri_as_default_uri(children)
            content = RSS::XML::Element.new("div", nil, xhtml_uri,
                                            {"xmlns" => xhtml_uri},
                                            children)
          end
          content
        end

        def xml_content=(content)
          @xml_content = ensure_xml_content(content)
        end

        def xhtml=(content)
          self.xml_content = content
        end

        private
        def set_xhtml_uri_as_default_uri(children)
          children.collect do |child|
            if child.is_a?(RSS::XML::Element) and
                child.prefix.nil? and child.uri.nil?
              RSS::XML::Element.new(child.name, nil, ::RSS::Atom::XHTML_URI,
                                    child.attributes.dup,
                                    set_xhtml_uri_as_default_uri(child.children))
            else
              child
            end
          end
        end
      end

      def self.append_features(klass)
        super

        klass.class_eval do
          include EnsureXMLContent
        end
      end
    end

    module SetupDefaultDate
      private
      def _set_default_values(&block)
        keep = {
          :date => date,
          :dc_dates => dc_dates.to_a.dup,
        }
        _date = _parse_date_if_needed(date)
        if _date and !dc_dates.any? {|dc_date| dc_date.value == _date}
          dc_date = self.class::DublinCoreDates::DublinCoreDate.new(self)
          dc_date.value = _date.dup
          dc_dates.unshift(dc_date)
        end
        self.date ||= self.dc_date
        super(&block)
      ensure
        date = keep[:date]
        dc_dates.replace(keep[:dc_dates])
      end

      def _parse_date_if_needed(date_value)
        date_value = Time.parse(date_value) if date_value.is_a?(String)
        date_value
      end
    end

    class RSSBase < Base
      class << self
        def make(version, &block)
          new(version).make(&block)
        end
      end

      %w(xml_stylesheets channel image items textinput).each do |element|
        attr_reader element
        add_need_initialize_variable(element, "make_#{element}")
        module_eval(<<-EOC, __FILE__, __LINE__)
          private
          def setup_#{element}(feed)
            @#{element}.to_feed(feed)
          end

          def make_#{element}
            self.class::#{Utils.to_class_name(element)}.new(self)
          end
        EOC
      end
      
      attr_reader :feed_version
      alias_method(:rss_version, :feed_version)
      attr_accessor :version, :encoding, :standalone

      def initialize(feed_version)
        super(self)
        @feed_type = nil
        @feed_subtype = nil
        @feed_version = feed_version
        @version = "1.0"
        @encoding = "UTF-8"
        @standalone = nil
      end
      
      def make
        if block_given?
          yield(self)
          to_feed
        else
          nil
        end
      end

      def to_feed
        feed = make_feed
        setup_xml_stylesheets(feed)
        setup_elements(feed)
        setup_other_elements(feed)
        if feed.valid?
          feed
        else
          nil
        end
      end
      
      private
      remove_method :make_xml_stylesheets
      def make_xml_stylesheets
        XMLStyleSheets.new(self)
      end
    end

    class XMLStyleSheets < Base
      def_array_element("xml_stylesheet", nil, "XMLStyleSheet")

      class XMLStyleSheet < Base

        ::RSS::XMLStyleSheet::ATTRIBUTES.each do |attribute|
          attr_accessor attribute
          add_need_initialize_variable(attribute)
        end
        
        def to_feed(feed)
          xss = ::RSS::XMLStyleSheet.new
          guess_type_if_need(xss)
          set = setup_values(xss)
          if set
            feed.xml_stylesheets << xss
          end
        end

        private
        def guess_type_if_need(xss)
          if @type.nil?
            xss.href = @href
            @type = xss.type
          end
        end

        def required_variable_names
          %w(href type)
        end
      end
    end
    
    class ChannelBase < Base
      include SetupDefaultDate

      %w(cloud categories skipDays skipHours).each do |name|
        def_classed_element(name)
      end

      %w(generator copyright description title).each do |name|
        def_classed_element(name, nil, "content")
      end

      [
       ["link", "href", Proc.new {|target,| "#{target}.href = 'self'"}],
       ["author", "name"],
       ["contributor", "name"],
      ].each do |name, attribute, additional_setup_maker|
        def_classed_elements(name, attribute, &additional_setup_maker)
      end

      %w(id about language
         managingEditor webMaster rating docs ttl).each do |element|
        attr_accessor element
        add_need_initialize_variable(element)
      end

      %w(date lastBuildDate).each do |date_element|
        attr_reader date_element
        add_need_initialize_variable(date_element)
      end

      def date=(_date)
        @date = _parse_date_if_needed(_date)
      end

      def lastBuildDate=(_date)
        @lastBuildDate = _parse_date_if_needed(_date)
      end

      def pubDate
        date
      end

      def pubDate=(date)
        self.date = date
      end

      def updated
        date
      end

      def updated=(date)
        self.date = date
      end

      alias_method(:rights, :copyright)
      alias_method(:rights=, :copyright=)

      alias_method(:subtitle, :description)
      alias_method(:subtitle=, :description=)

      def icon
        image_favicon.about
      end

      def icon=(url)
        image_favicon.about = url
      end

      def logo
        maker.image.url
      end

      def logo=(url)
        maker.image.url = url
      end

      class SkipDaysBase < Base
        def_array_element("day")

        class DayBase < Base
          %w(content).each do |element|
            attr_accessor element
            add_need_initialize_variable(element)
          end
        end
      end
      
      class SkipHoursBase < Base
        def_array_element("hour")

        class HourBase < Base
          %w(content).each do |element|
            attr_accessor element
            add_need_initialize_variable(element)
          end
        end
      end
      
      class CloudBase < Base
        %w(domain port path registerProcedure protocol).each do |element|
          attr_accessor element
          add_need_initialize_variable(element)
        end
      end

      class CategoriesBase < Base
        def_array_element("category", "categories")

        class CategoryBase < Base
          %w(domain content label).each do |element|
            attr_accessor element
            add_need_initialize_variable(element)
          end

          alias_method(:term, :domain)
          alias_method(:term=, :domain=)
          alias_method(:scheme, :content)
          alias_method(:scheme=, :content=)
        end
      end

      class LinksBase < Base
        def_array_element("link")

        class LinkBase < Base
          %w(href rel type hreflang title length).each do |element|
            attr_accessor element
            add_need_initialize_variable(element)
          end
        end
      end

      class AuthorsBase < Base
        def_array_element("author")

        class AuthorBase < Base
          include AtomPersonConstructBase
        end
      end

      class ContributorsBase < Base
        def_array_element("contributor")

        class ContributorBase < Base
          include AtomPersonConstructBase
        end
      end

      class GeneratorBase < Base
        %w(uri version content).each do |element|
          attr_accessor element
          add_need_initialize_variable(element)
        end
      end

      class CopyrightBase < Base
        include AtomTextConstructBase
      end

      class DescriptionBase < Base
        include AtomTextConstructBase
      end

      class TitleBase < Base
        include AtomTextConstructBase
      end
    end
    
    class ImageBase < Base
      %w(title url width height description).each do |element|
        attr_accessor element
        add_need_initialize_variable(element)
      end

      def link
        @maker.channel.link
      end
    end
    
    class ItemsBase < Base
      def_array_element("item")

      attr_accessor :do_sort, :max_size
      
      def initialize(maker)
        super
        @do_sort = false
        @max_size = -1
      end
      
      def normalize
        if @max_size >= 0
          sort_if_need[0...@max_size]
        else
          sort_if_need[0..@max_size]
        end
      end

      private
      def sort_if_need
        if @do_sort.respond_to?(:call)
          @items.sort do |x, y|
            @do_sort.call(x, y)
          end
        elsif @do_sort
          @items.sort do |x, y|
            y <=> x
          end
        else
          @items
        end
      end

      class ItemBase < Base
        include SetupDefaultDate

        %w(guid enclosure source categories content).each do |name|
          def_classed_element(name)
        end

        %w(rights description title).each do |name|
          def_classed_element(name, nil, "content")
        end

        [
         ["author", "name"],
         ["link", "href", Proc.new {|target,| "#{target}.href = 'alternate'"}],
         ["contributor", "name"],
        ].each do |name, attribute|
          def_classed_elements(name, attribute)
	end

        %w(comments id published).each do |element|
          attr_accessor element
          add_need_initialize_variable(element)
        end

        %w(date).each do |date_element|
          attr_reader date_element
          add_need_initialize_variable(date_element)
        end

        def date=(_date)
          @date = _parse_date_if_needed(_date)
        end

        def pubDate
          date
        end

        def pubDate=(date)
          self.date = date
        end

        def updated
          date
        end

        def updated=(date)
          self.date = date
        end

        alias_method(:summary, :description)
        alias_method(:summary=, :description=)

        def <=>(other)
          _date = date || dc_date
          _other_date = other.date || other.dc_date
          if _date and _other_date
            _date <=> _other_date
          elsif _date
            1
          elsif _other_date
            -1
          else
            0
          end
        end

        class GuidBase < Base
          %w(isPermaLink content).each do |element|
            attr_accessor element
            add_need_initialize_variable(element)
          end
        end

        class EnclosureBase < Base
          %w(url length type).each do |element|
            attr_accessor element
            add_need_initialize_variable(element)
          end
        end

        class SourceBase < Base
          include SetupDefaultDate

          %w(authors categories contributors generator icon
             logo rights subtitle title).each do |name|
            def_classed_element(name)
          end

          [
           ["link", "href"],
          ].each do |name, attribute|
            def_classed_elements(name, attribute)
          end

          %w(id content).each do |element|
            attr_accessor element
            add_need_initialize_variable(element)
          end

          alias_method(:url, :link)
          alias_method(:url=, :link=)

          %w(date).each do |date_element|
            attr_reader date_element
            add_need_initialize_variable(date_element)
          end

          def date=(_date)
            @date = _parse_date_if_needed(_date)
          end

          def updated
            date
          end

          def updated=(date)
            self.date = date
          end

          private
          AuthorsBase = ChannelBase::AuthorsBase
          CategoriesBase = ChannelBase::CategoriesBase
          ContributorsBase = ChannelBase::ContributorsBase
          GeneratorBase = ChannelBase::GeneratorBase

          class IconBase < Base
            %w(url).each do |element|
              attr_accessor element
              add_need_initialize_variable(element)
            end
          end

          LinksBase = ChannelBase::LinksBase

          class LogoBase < Base
            %w(uri).each do |element|
              attr_accessor element
              add_need_initialize_variable(element)
            end
          end

          class RightsBase < Base
            include AtomTextConstructBase
          end

          class SubtitleBase < Base
            include AtomTextConstructBase
          end

          class TitleBase < Base
            include AtomTextConstructBase
          end
        end

        CategoriesBase = ChannelBase::CategoriesBase
        AuthorsBase = ChannelBase::AuthorsBase
        LinksBase = ChannelBase::LinksBase
        ContributorsBase = ChannelBase::ContributorsBase

        class RightsBase < Base
          include AtomTextConstructBase
        end

        class DescriptionBase < Base
          include AtomTextConstructBase
        end

        class ContentBase < Base
          include AtomTextConstructBase::EnsureXMLContent

          %w(src).each do |element|
            attr_accessor(element)
            add_need_initialize_variable(element)
          end

          def xml_content=(content)
            content = ensure_xml_content(content) if inline_xhtml?
            @xml_content = content
          end

          alias_method(:xml, :xml_content)
          alias_method(:xml=, :xml_content=)

          def inline_text?
            [nil, "text", "html"].include?(@type)
          end

          def inline_html?
            @type == "html"
          end

          def inline_xhtml?
            @type == "xhtml"
          end

          def inline_other?
            !out_of_line? and ![nil, "text", "html", "xhtml"].include?(@type)
          end

          def inline_other_text?
            return false if @type.nil? or out_of_line?
            /\Atext\//i.match(@type) ? true : false
          end

          def inline_other_xml?
            return false if @type.nil? or out_of_line?
            /[\+\/]xml\z/i.match(@type) ? true : false
          end

          def inline_other_base64?
            return false if @type.nil? or out_of_line?
            @type.include?("/") and !inline_other_text? and !inline_other_xml?
          end

          def out_of_line?
            not @src.nil? and @content.nil?
          end
        end

        class TitleBase < Base
          include AtomTextConstructBase
        end
      end
    end

    class TextinputBase < Base
      %w(title description name link).each do |element|
        attr_accessor element
        add_need_initialize_variable(element)
      end
    end
  end
end
PK     Y\DG`      rss/maker/atom.rbnu [        require "rss/atom"

require "rss/maker/base"

module RSS
  module Maker
    module AtomPersons
      module_function
      def def_atom_persons(klass, name, maker_name, plural=nil)
        plural ||= "#{name}s"
        klass_name = Utils.to_class_name(name)
        plural_klass_name = Utils.to_class_name(plural)

        klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
          class #{plural_klass_name} < #{plural_klass_name}Base
            class #{klass_name} < #{klass_name}Base
              def to_feed(feed, current)
                #{name} = feed.class::#{klass_name}.new
                set = setup_values(#{name})
                unless set
                  raise NotSetError.new(#{maker_name.dump},
                                        not_set_required_variables)
                end
                current.#{plural} << #{name}
                set_parent(#{name}, current)
                setup_other_elements(#{name})
              end

              private
              def required_variable_names
                %w(name)
              end
            end
          end
EOC
      end
    end

    module AtomTextConstruct
      class << self
        def def_atom_text_construct(klass, name, maker_name, klass_name=nil,
                                    atom_klass_name=nil)
          klass_name ||= Utils.to_class_name(name)
          atom_klass_name ||= Utils.to_class_name(name)

          klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
            class #{klass_name} < #{klass_name}Base
              include #{self.name}
              def to_feed(feed, current)
                #{name} = current.class::#{atom_klass_name}.new
                if setup_values(#{name})
                  current.#{name} = #{name}
                  set_parent(#{name}, current)
                  setup_other_elements(feed)
                elsif variable_is_set?
                  raise NotSetError.new(#{maker_name.dump},
                                        not_set_required_variables)
                end
              end
            end
          EOC
        end
      end

      private
      def required_variable_names
        if type == "xhtml"
          %w(xml_content)
        else
          %w(content)
        end
      end

      def variables
        if type == "xhtml"
          super + %w(xhtml)
        else
          super
        end
      end
    end

    module AtomCategory
      def to_feed(feed, current)
        category = feed.class::Category.new
        set = setup_values(category)
        if set
          current.categories << category
          set_parent(category, current)
          setup_other_elements(feed)
        else
          raise NotSetError.new(self.class.not_set_name,
                                not_set_required_variables)
        end
      end

      private
      def required_variable_names
        %w(term)
      end

      def variables
        super + ["term", "scheme"]
      end
    end

    module AtomLink
      def to_feed(feed, current)
        link = feed.class::Link.new
        set = setup_values(link)
        if set
          current.links << link
          set_parent(link, current)
          setup_other_elements(feed)
        else
          raise NotSetError.new(self.class.not_set_name,
                                not_set_required_variables)
        end
      end

      private
      def required_variable_names
        %w(href)
      end
    end

    module AtomGenerator
      def to_feed(feed, current)
        generator = current.class::Generator.new
        if setup_values(generator)
          current.generator = generator
          set_parent(generator, current)
          setup_other_elements(feed)
        elsif variable_is_set?
          raise NotSetError.new(self.class.not_set_name,
                                not_set_required_variables)
        end
      end

      private
      def required_variable_names
        %w(content)
      end
    end

    module AtomLogo
      def to_feed(feed, current)
        logo = current.class::Logo.new
        class << logo
          alias_method(:uri=, :content=)
        end
        set = setup_values(logo)
        class << logo
          remove_method(:uri=)
        end
        if set
          current.logo = logo
          set_parent(logo, current)
          setup_other_elements(feed)
        elsif variable_is_set?
          raise NotSetError.new(self.class.not_set_name,
                                not_set_required_variables)
        end
      end

      private
      def required_variable_names
        %w(uri)
      end
    end
  end
end
PK     Y\      rss/maker/slash.rbnu [        require 'rss/slash'
require 'rss/maker/1.0'

module RSS
  module Maker
    module SlashModel
      def self.append_features(klass)
        super

        ::RSS::SlashModel::ELEMENT_INFOS.each do |name, type|
          full_name = "#{RSS::SLASH_PREFIX}_#{name}"
          case type
          when :csv_integer
            klass.def_csv_element(full_name, :integer)
          else
            klass.def_other_element(full_name)
          end
        end

        klass.module_eval do
          alias_method(:slash_hit_parades, :slash_hit_parade)
          alias_method(:slash_hit_parades=, :slash_hit_parade=)
        end
      end
    end

    class ItemsBase
      class ItemBase
        include SlashModel
      end
    end
  end
end
PK     Y\_      rss/maker/taxonomy.rbnu [        require 'rss/taxonomy'
require 'rss/maker/1.0'
require 'rss/maker/dublincore'

module RSS
  module Maker
    module TaxonomyTopicsModel
      def self.append_features(klass)
        super

        klass.def_classed_element("#{RSS::TAXO_PREFIX}_topics",
                                  "TaxonomyTopics")
      end

      def self.install_taxo_topics(klass)
        klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
          class TaxonomyTopics < TaxonomyTopicsBase
            def to_feed(feed, current)
              if current.respond_to?(:taxo_topics)
                topics = current.class::TaxonomyTopics.new
                bag = topics.Bag
                @resources.each do |resource|
                  bag.lis << RDF::Bag::Li.new(resource)
                end
                current.taxo_topics = topics
              end
            end
          end
EOC
      end

      class TaxonomyTopicsBase < Base
        attr_reader :resources
        def_array_element("resource")
        remove_method :new_resource
      end
    end

    module TaxonomyTopicModel
      def self.append_features(klass)
        super

        class_name = "TaxonomyTopics"
        klass.def_classed_elements("#{TAXO_PREFIX}_topic", "value", class_name)
      end

      def self.install_taxo_topic(klass)
        klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
          class TaxonomyTopics < TaxonomyTopicsBase
            class TaxonomyTopic < TaxonomyTopicBase
              DublinCoreModel.install_dublin_core(self)
              TaxonomyTopicsModel.install_taxo_topics(self)

              def to_feed(feed, current)
                if current.respond_to?(:taxo_topics)
                  topic = current.class::TaxonomyTopic.new(value)
                  topic.taxo_link = value
                  taxo_topics.to_feed(feed, topic) if taxo_topics
                  current.taxo_topics << topic
                  setup_other_elements(feed, topic)
                end
              end
            end
          end
EOC
      end

      class TaxonomyTopicsBase < Base
        def_array_element("topic", nil, "TaxonomyTopic")
        alias_method(:new_taxo_topic, :new_topic) # For backward compatibility

        class TaxonomyTopicBase < Base
          include DublinCoreModel
          include TaxonomyTopicsModel
          
          attr_accessor :value
          add_need_initialize_variable("value")
          alias_method(:taxo_link, :value)
          alias_method(:taxo_link=, :value=)
          
          def have_required_values?
            @value
          end
        end
      end
    end

    class RSSBase
      include TaxonomyTopicModel
    end
    
    class ChannelBase
      include TaxonomyTopicsModel
    end
    
    class ItemsBase
      class ItemBase
        include TaxonomyTopicsModel
      end
    end

    makers.each do |maker|
      maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
        TaxonomyTopicModel.install_taxo_topic(self)

        class Channel
          TaxonomyTopicsModel.install_taxo_topics(self)
        end

        class Items
          class Item
            TaxonomyTopicsModel.install_taxo_topics(self)
          end
        end
      EOC
    end
  end
end
PK     Y\)j,  ,    rss/maker/0.9.rbnu [        require "rss/0.9"

require "rss/maker/base"

module RSS
  module Maker
    
    class RSS09 < RSSBase
      
      def initialize(feed_version="0.92")
        super
        @feed_type = "rss"
      end
      
      private
      def make_feed
        Rss.new(@feed_version, @version, @encoding, @standalone)
      end

      def setup_elements(rss)
        setup_channel(rss)
      end

      class Channel < ChannelBase
        def to_feed(rss)
          channel = Rss::Channel.new
          set = setup_values(channel)
          _not_set_required_variables = not_set_required_variables
          if _not_set_required_variables.empty?
            rss.channel = channel
            set_parent(channel, rss)
            setup_items(rss)
            setup_image(rss)
            setup_textinput(rss)
            setup_other_elements(rss, channel)
            rss
          else
            raise NotSetError.new("maker.channel", _not_set_required_variables)
          end
        end
        
        private
        def setup_items(rss)
          @maker.items.to_feed(rss)
        end
        
        def setup_image(rss)
          @maker.image.to_feed(rss)
        end
        
        def setup_textinput(rss)
          @maker.textinput.to_feed(rss)
        end
        
        def variables
          super + ["pubDate"]
        end

        def required_variable_names
          %w(link language)
        end

        def not_set_required_variables
          vars = super
          vars << "description" unless description {|d| d.have_required_values?}
          vars << "title" unless title {|t| t.have_required_values?}
          vars
        end

        class SkipDays < SkipDaysBase
          def to_feed(rss, channel)
            unless @days.empty?
              skipDays = Rss::Channel::SkipDays.new
              channel.skipDays = skipDays
              set_parent(skipDays, channel)
              @days.each do |day|
                day.to_feed(rss, skipDays.days)
              end
            end
          end
          
          class Day < DayBase
            def to_feed(rss, days)
              day = Rss::Channel::SkipDays::Day.new
              set = setup_values(day)
              if set
                days << day
                set_parent(day, days)
                setup_other_elements(rss, day)
              end
            end

            private
            def required_variable_names
              %w(content)
            end
          end
        end
        
        class SkipHours < SkipHoursBase
          def to_feed(rss, channel)
            unless @hours.empty?
              skipHours = Rss::Channel::SkipHours.new
              channel.skipHours = skipHours
              set_parent(skipHours, channel)
              @hours.each do |hour|
                hour.to_feed(rss, skipHours.hours)
              end
            end
          end
          
          class Hour < HourBase
            def to_feed(rss, hours)
              hour = Rss::Channel::SkipHours::Hour.new
              set = setup_values(hour)
              if set
                hours << hour
                set_parent(hour, hours)
                setup_other_elements(rss, hour)
              end
            end

            private
            def required_variable_names
              %w(content)
            end
          end
        end
        
        class Cloud < CloudBase
          def to_feed(*args)
          end
        end

        class Categories < CategoriesBase
          def to_feed(*args)
          end

          class Category < CategoryBase
          end
        end

        class Links < LinksBase
          def to_feed(rss, channel)
            return if @links.empty?
            @links.first.to_feed(rss, channel)
          end

          class Link < LinkBase
            def to_feed(rss, channel)
              if have_required_values?
                channel.link = href
              else
                raise NotSetError.new("maker.channel.link",
                                      not_set_required_variables)
              end
            end

            private
            def required_variable_names
              %w(href)
            end
          end
        end

        class Authors < AuthorsBase
          def to_feed(rss, channel)
          end

          class Author < AuthorBase
            def to_feed(rss, channel)
            end
          end
        end

        class Contributors < ContributorsBase
          def to_feed(rss, channel)
          end

          class Contributor < ContributorBase
          end
        end

        class Generator < GeneratorBase
          def to_feed(rss, channel)
          end
        end

        class Copyright < CopyrightBase
          def to_feed(rss, channel)
            channel.copyright = content if have_required_values?
          end

          private
          def required_variable_names
            %w(content)
          end
        end

        class Description < DescriptionBase
          def to_feed(rss, channel)
            channel.description = content if have_required_values?
          end

          private
          def required_variable_names
            %w(content)
          end
        end

        class Title < TitleBase
          def to_feed(rss, channel)
            channel.title = content if have_required_values?
          end

          private
          def required_variable_names
            %w(content)
          end
        end
      end

      class Image < ImageBase
        def to_feed(rss)
          image = Rss::Channel::Image.new
          set = setup_values(image)
          if set
            image.link = link
            rss.channel.image = image
            set_parent(image, rss.channel)
            setup_other_elements(rss, image)
          elsif required_element?
            raise NotSetError.new("maker.image", not_set_required_variables)
          end
        end

        private
        def required_variable_names
          %w(url title link)
        end

        def required_element?
          true
        end
      end
      
      class Items < ItemsBase
        def to_feed(rss)
          if rss.channel
            normalize.each do |item|
              item.to_feed(rss)
            end
            setup_other_elements(rss, rss.items)
          end
        end
        
        class Item < ItemBase
          def to_feed(rss)
            item = Rss::Channel::Item.new
            set = setup_values(item)
            _not_set_required_variables = not_set_required_variables
            if _not_set_required_variables.empty?
              rss.items << item
              set_parent(item, rss.channel)
              setup_other_elements(rss, item)
            elsif variable_is_set?
              raise NotSetError.new("maker.items", _not_set_required_variables)
            end
          end

          private
          def required_variable_names
            []
          end

          def not_set_required_variables
            vars = super
            if @maker.feed_version == "0.91"
              vars << "title" unless title {|t| t.have_required_values?}
              vars << "link" unless link {|l| l.have_required_values?}
            end
            vars
          end

          class Guid < GuidBase
            def to_feed(*args)
            end
          end

          class Enclosure < EnclosureBase
            def to_feed(*args)
            end
          end

          class Source < SourceBase
            def to_feed(*args)
            end

            class Authors < AuthorsBase
              def to_feed(*args)
              end

              class Author < AuthorBase
              end
            end

            class Categories < CategoriesBase
              def to_feed(*args)
              end

              class Category < CategoryBase
              end
            end

            class Contributors < ContributorsBase
              def to_feed(*args)
              end

              class Contributor < ContributorBase
              end
            end

            class Generator < GeneratorBase
              def to_feed(*args)
              end
            end

            class Icon < IconBase
              def to_feed(*args)
              end
            end

            class Links < LinksBase
              def to_feed(*args)
              end

              class Link < LinkBase
              end
            end

            class Logo < LogoBase
              def to_feed(*args)
              end
            end

            class Rights < RightsBase
              def to_feed(*args)
              end
            end

            class Subtitle < SubtitleBase
              def to_feed(*args)
              end
            end

            class Title < TitleBase
              def to_feed(*args)
              end
            end
          end

          class Categories < CategoriesBase
            def to_feed(*args)
            end

            class Category < CategoryBase
            end
          end

          class Authors < AuthorsBase
            def to_feed(*args)
            end

            class Author < AuthorBase
            end
          end

          class Links < LinksBase
            def to_feed(rss, item)
              return if @links.empty?
              @links.first.to_feed(rss, item)
            end

            class Link < LinkBase
              def to_feed(rss, item)
                if have_required_values?
                  item.link = href
                else
                  raise NotSetError.new("maker.link",
                                        not_set_required_variables)
                end
              end

              private
              def required_variable_names
                %w(href)
              end
            end
          end

          class Contributors < ContributorsBase
            def to_feed(rss, item)
            end

            class Contributor < ContributorBase
            end
          end

          class Rights < RightsBase
            def to_feed(rss, item)
            end
          end

          class Description < DescriptionBase
            def to_feed(rss, item)
              item.description = content if have_required_values?
            end

            private
            def required_variable_names
              %w(content)
            end
          end

          class Content < ContentBase
            def to_feed(rss, item)
            end
          end

          class Title < TitleBase
            def to_feed(rss, item)
              item.title = content if have_required_values?
            end

            private
            def required_variable_names
              %w(content)
            end
          end
        end
      end
      
      class Textinput < TextinputBase
        def to_feed(rss)
          textInput = Rss::Channel::TextInput.new
          set = setup_values(textInput)
          if set
            rss.channel.textInput = textInput
            set_parent(textInput, rss.channel)
            setup_other_elements(rss, textInput)
          end
        end

        private
        def required_variable_names
          %w(title description name link)
        end
      end
    end
    
    add_maker("0.9", "0.92", RSS09)
    add_maker("0.91", "0.91", RSS09)
    add_maker("0.92", "0.92", RSS09)
    add_maker("rss0.91", "0.91", RSS09)
    add_maker("rss0.92", "0.92", RSS09)
  end
end
PK     Y\r]  ]    rss/maker/syndication.rbnu [        require 'rss/syndication'
require 'rss/maker/1.0'

module RSS
  module Maker
    module SyndicationModel
      def self.append_features(klass)
        super

        ::RSS::SyndicationModel::ELEMENTS.each do |name|
          klass.def_other_element(name)
        end
      end
    end

    class ChannelBase; include SyndicationModel; end
  end
end
PK     Y\ƾ      rss/maker/entry.rbnu [        require "rss/maker/atom"
require "rss/maker/feed"

module RSS
  module Maker
    module Atom
      class Entry < RSSBase
        def initialize(feed_version="1.0")
          super
          @feed_type = "atom"
          @feed_subtype = "entry"
        end

        private
        def make_feed
          ::RSS::Atom::Entry.new(@version, @encoding, @standalone)
        end

        def setup_elements(entry)
          setup_items(entry)
        end

        class Channel < ChannelBase
          class SkipDays < SkipDaysBase
            class Day < DayBase
            end
          end

          class SkipHours < SkipHoursBase
            class Hour < HourBase
            end
          end

          class Cloud < CloudBase
          end

          Categories = Feed::Channel::Categories
          Links = Feed::Channel::Links
          Authors = Feed::Channel::Authors
          Contributors = Feed::Channel::Contributors

          class Generator < GeneratorBase
            include AtomGenerator

            def self.not_set_name
              "maker.channel.generator"
            end
          end

          Copyright = Feed::Channel::Copyright

          class Description < DescriptionBase
          end

          Title = Feed::Channel::Title
        end

        class Image < ImageBase
        end

        class Items < ItemsBase
          def to_feed(entry)
            (normalize.first || Item.new(@maker)).to_feed(entry)
          end

          class Item < ItemBase
            def to_feed(entry)
              set_default_values do
                setup_values(entry)
                entry.dc_dates.clear
                setup_other_elements(entry)
                unless have_required_values?
                  raise NotSetError.new("maker.item", not_set_required_variables)
                end
              end
            end

            private
            def required_variable_names
              %w(id updated)
            end

            def variables
              super + ["updated"]
            end

            def variable_is_set?
              super or !authors.empty?
            end

            def not_set_required_variables
              set_default_values do
                vars = super
                if authors.all? {|author| !author.have_required_values?}
                  vars << "author"
                end
                vars << "title" unless title {|t| t.have_required_values?}
                vars
              end
            end

            def _set_default_values(&block)
              keep = {
                :authors => authors.to_a.dup,
                :contributors => contributors.to_a.dup,
                :categories => categories.to_a.dup,
                :id => id,
                :links => links.to_a.dup,
                :rights => @rights,
                :title => @title,
                :updated => updated,
              }
              authors.replace(@maker.channel.authors) if keep[:authors].empty?
              if keep[:contributors].empty?
                contributors.replace(@maker.channel.contributors)
              end
              if keep[:categories].empty?
                categories.replace(@maker.channel.categories)
              end
              self.id ||= link || @maker.channel.id
              links.replace(@maker.channel.links) if keep[:links].empty?
              unless keep[:rights].variable_is_set?
                @maker.channel.rights {|r| @rights = r}
              end
              unless keep[:title].variable_is_set?
                @maker.channel.title {|t| @title = t}
              end
              self.updated ||= @maker.channel.updated
              super(&block)
            ensure
              authors.replace(keep[:authors])
              contributors.replace(keep[:contributors])
              categories.replace(keep[:categories])
              links.replace(keep[:links])
              self.id = keep[:id]
              @rights = keep[:rights]
              @title = keep[:title]
              self.updated = keep[:prev_updated]
            end

            Guid = Feed::Items::Item::Guid
            Enclosure = Feed::Items::Item::Enclosure
            Source = Feed::Items::Item::Source
            Categories = Feed::Items::Item::Categories
            Authors = Feed::Items::Item::Authors
            Contributors = Feed::Items::Item::Contributors
            Links = Feed::Items::Item::Links
            Rights = Feed::Items::Item::Rights
            Description = Feed::Items::Item::Description
            Title = Feed::Items::Item::Title
            Content = Feed::Items::Item::Content
          end
        end

        class Textinput < TextinputBase
        end
      end
    end

    add_maker("atom:entry", "1.0", Atom::Entry)
    add_maker("atom1.0:entry", "1.0", Atom::Entry)
  end
end
PK     Y\Fv(  (    rss/maker/1.0.rbnu [        require "rss/1.0"

require "rss/maker/base"

module RSS
  module Maker

    class RSS10 < RSSBase

      def initialize(feed_version="1.0")
        super
        @feed_type = "rss"
      end

      private
      def make_feed
        RDF.new(@version, @encoding, @standalone)
      end

      def setup_elements(rss)
        setup_channel(rss)
        setup_image(rss)
        setup_items(rss)
        setup_textinput(rss)
      end

      class Channel < ChannelBase

        def to_feed(rss)
          set_default_values do
            _not_set_required_variables = not_set_required_variables
            if _not_set_required_variables.empty?
              channel = RDF::Channel.new(@about)
              set = setup_values(channel)
              channel.dc_dates.clear
              rss.channel = channel
              set_parent(channel, rss)
              setup_items(rss)
              setup_image(rss)
              setup_textinput(rss)
              setup_other_elements(rss, channel)
            else
              raise NotSetError.new("maker.channel", _not_set_required_variables)
            end
          end
        end

        private
        def setup_items(rss)
          items = RDF::Channel::Items.new
          seq = items.Seq
          set_parent(items, seq)
          target_items = @maker.items.normalize
          raise NotSetError.new("maker", ["items"]) if target_items.empty?
          target_items.each do |item|
            li = RDF::Channel::Items::Seq::Li.new(item.link)
            seq.lis << li
            set_parent(li, seq)
          end
          rss.channel.items = items
          set_parent(rss.channel, items)
        end
        
        def setup_image(rss)
          if @maker.image.have_required_values?
            image = RDF::Channel::Image.new(@maker.image.url)
            rss.channel.image = image
            set_parent(image, rss.channel)
          end
        end

        def setup_textinput(rss)
          if @maker.textinput.have_required_values?
            textinput = RDF::Channel::Textinput.new(@maker.textinput.link)
            rss.channel.textinput = textinput
            set_parent(textinput, rss.channel)
          end
        end

        def required_variable_names
          %w(about link)
        end

        def not_set_required_variables
          vars = super
          vars << "description" unless description {|d| d.have_required_values?}
          vars << "title" unless title {|t| t.have_required_values?}
          vars
        end

        class SkipDays < SkipDaysBase
          def to_feed(*args)
          end
          
          class Day < DayBase
          end
        end
        
        class SkipHours < SkipHoursBase
          def to_feed(*args)
          end

          class Hour < HourBase
          end
        end
        
        class Cloud < CloudBase
          def to_feed(*args)
          end
        end

        class Categories < CategoriesBase
          def to_feed(*args)
          end

          class Category < CategoryBase
          end
        end

        class Links < LinksBase
          def to_feed(rss, channel)
            return if @links.empty?
            @links.first.to_feed(rss, channel)
          end

          class Link < LinkBase
            def to_feed(rss, channel)
              if have_required_values?
                channel.link = href
              else
                raise NotSetError.new("maker.channel.link",
                                      not_set_required_variables)
              end
            end

            private
            def required_variable_names
              %w(href)
            end
          end
        end

        class Authors < AuthorsBase
          def to_feed(rss, channel)
          end

          class Author < AuthorBase
            def to_feed(rss, channel)
            end
          end
        end

        class Contributors < ContributorsBase
          def to_feed(rss, channel)
          end

          class Contributor < ContributorBase
          end
        end

        class Generator < GeneratorBase
          def to_feed(rss, channel)
          end
        end

        class Copyright < CopyrightBase
          def to_feed(rss, channel)
          end
        end

        class Description < DescriptionBase
          def to_feed(rss, channel)
            channel.description = content if have_required_values?
          end

          private
          def required_variable_names
            %w(content)
          end
        end

        class Title < TitleBase
          def to_feed(rss, channel)
            channel.title = content if have_required_values?
          end

          private
          def required_variable_names
            %w(content)
          end
        end
      end

      class Image < ImageBase
        def to_feed(rss)
          if @url
            image = RDF::Image.new(@url)
            set = setup_values(image)
            if set
              rss.image = image
              set_parent(image, rss)
              setup_other_elements(rss, image)
            end
          end
        end

        def have_required_values?
          super and @maker.channel.have_required_values?
        end

        private
        def variables
          super + ["link"]
        end

        def required_variable_names
          %w(url title link)
        end
      end

      class Items < ItemsBase
        def to_feed(rss)
          if rss.channel
            normalize.each do |item|
              item.to_feed(rss)
            end
            setup_other_elements(rss, rss.items)
          end
        end

        class Item < ItemBase
          def to_feed(rss)
            set_default_values do
              item = RDF::Item.new(link)
              set = setup_values(item)
              if set
                item.dc_dates.clear
                rss.items << item
                set_parent(item, rss)
                setup_other_elements(rss, item)
              elsif !have_required_values?
                raise NotSetError.new("maker.item", not_set_required_variables)
              end
            end
          end

          private
          def required_variable_names
            %w(link)
          end

          def variables
            super + %w(link)
          end

          def not_set_required_variables
            set_default_values do
              vars = super
              vars << "title" unless title {|t| t.have_required_values?}
              vars
            end
          end

          class Guid < GuidBase
            def to_feed(*args)
            end
          end

          class Enclosure < EnclosureBase
            def to_feed(*args)
            end
          end

          class Source < SourceBase
            def to_feed(*args)
            end

            class Authors < AuthorsBase
              def to_feed(*args)
              end

              class Author < AuthorBase
              end
            end

            class Categories < CategoriesBase
              def to_feed(*args)
              end

              class Category < CategoryBase
              end
            end

            class Contributors < ContributorsBase
              def to_feed(*args)
              end

              class Contributor < ContributorBase
              end
            end

            class Generator < GeneratorBase
              def to_feed(*args)
              end
            end

            class Icon < IconBase
              def to_feed(*args)
              end
            end

            class Links < LinksBase
              def to_feed(*args)
              end

              class Link < LinkBase
              end
            end

            class Logo < LogoBase
              def to_feed(*args)
              end
            end

            class Rights < RightsBase
              def to_feed(*args)
              end
            end

            class Subtitle < SubtitleBase
              def to_feed(*args)
              end
            end

            class Title < TitleBase
              def to_feed(*args)
              end
            end
          end

          class Categories < CategoriesBase
            def to_feed(*args)
            end

            class Category < CategoryBase
            end
          end

          class Authors < AuthorsBase
            def to_feed(*args)
            end

            class Author < AuthorBase
            end
          end

          class Links < LinksBase
            def to_feed(*args)
            end

            class Link < LinkBase
            end
          end

          class Contributors < ContributorsBase
            def to_feed(rss, item)
            end

            class Contributor < ContributorBase
            end
          end

          class Rights < RightsBase
            def to_feed(rss, item)
            end
          end

          class Description < DescriptionBase
            def to_feed(rss, item)
              item.description = content if have_required_values?
            end

            private
            def required_variable_names
              %w(content)
            end
          end

          class Content < ContentBase
            def to_feed(rss, item)
            end
          end

          class Title < TitleBase
            def to_feed(rss, item)
              item.title = content if have_required_values?
            end

            private
            def required_variable_names
              %w(content)
            end
          end
        end
      end
      
      class Textinput < TextinputBase
        def to_feed(rss)
          if @link
            textinput = RDF::Textinput.new(@link)
            set = setup_values(textinput)
            if set
              rss.textinput = textinput
              set_parent(textinput, rss)
              setup_other_elements(rss, textinput)
            end
          end
        end

        def have_required_values?
          super and @maker.channel.have_required_values?
        end

        private
        def required_variable_names
          %w(title description name link)
        end
      end
    end

    add_maker("1.0", "1.0", RSS10)
    add_maker("rss1.0", "1.0", RSS10)
  end
end
PK     Y\-c      rss/maker/dublincore.rbnu [        require 'rss/dublincore'
require 'rss/maker/1.0'

module RSS
  module Maker
    module DublinCoreModel
      def self.append_features(klass)
        super

        ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
          plural_name ||= "#{name}s"
          full_name = "#{RSS::DC_PREFIX}_#{name}"
          full_plural_name = "#{RSS::DC_PREFIX}_#{plural_name}"
          klass_name = Utils.to_class_name(name)
          plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
          full_plural_klass_name = "self.class::#{plural_klass_name}"
          full_klass_name = "#{full_plural_klass_name}::#{klass_name}"
          klass.def_classed_elements(full_name, "value", plural_klass_name,
                                     full_plural_name, name)
          klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
            def new_#{full_name}(value=nil)
              _#{full_name} = #{full_plural_name}.new_#{name}
              _#{full_name}.value = value
              if block_given?
                yield _#{full_name}
              else
                _#{full_name}
              end
            end
          EOC
        end

        klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
          # For backward compatibility
          alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list
        EOC
      end

      ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
        plural_name ||= "#{name}s"
        full_name ||= "#{DC_PREFIX}_#{name}"
        full_plural_name ||= "#{DC_PREFIX}_#{plural_name}"
        klass_name = Utils.to_class_name(name)
        full_klass_name = "DublinCore#{klass_name}"
        plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
        module_eval(<<-EOC, __FILE__, __LINE__ + 1)
        class #{plural_klass_name}Base < Base
          def_array_element(#{name.dump}, #{full_plural_name.dump},
                            #{full_klass_name.dump})

          class #{full_klass_name}Base < Base
            attr_accessor :value
            add_need_initialize_variable("value")
            alias_method(:content, :value)
            alias_method(:content=, :value=)

            def have_required_values?
              @value
            end

            def to_feed(feed, current)
              if value and current.respond_to?(:#{full_name})
                new_item = current.class::#{full_klass_name}.new(value)
                current.#{full_plural_name} << new_item
              end
            end
          end
          #{klass_name}Base = #{full_klass_name}Base
        end
        EOC
      end

      def self.install_dublin_core(klass)
        ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
          plural_name ||= "#{name}s"
          klass_name = Utils.to_class_name(name)
          full_klass_name = "DublinCore#{klass_name}"
          plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
          klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
          class #{plural_klass_name} < #{plural_klass_name}Base
            class #{full_klass_name} < #{full_klass_name}Base
            end
            #{klass_name} = #{full_klass_name}
          end
EOC
        end
      end
    end

    class ChannelBase
      include DublinCoreModel
    end
    
    class ImageBase; include DublinCoreModel; end
    class ItemsBase
      class ItemBase
        include DublinCoreModel
      end
    end
    class TextinputBase; include DublinCoreModel; end

    makers.each do |maker|
      maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
        class Channel
          DublinCoreModel.install_dublin_core(self)
        end

        class Image
          DublinCoreModel.install_dublin_core(self)
        end

        class Items
          class Item
            DublinCoreModel.install_dublin_core(self)
          end
        end

        class Textinput
          DublinCoreModel.install_dublin_core(self)
        end
      EOC
    end
  end
end
PK     Y\g      rss/maker/itunes.rbnu [        require 'rss/itunes'
require 'rss/maker/2.0'

module RSS
  module Maker
    module ITunesBaseModel
      def def_class_accessor(klass, name, type, *args)
        name = name.gsub(/-/, "_").gsub(/^itunes_/, '')
        full_name = "#{RSS::ITUNES_PREFIX}_#{name}"
        case type
        when nil
          klass.def_other_element(full_name)
        when :yes_other
          def_yes_other_accessor(klass, full_name)
        when :yes_clean_other
          def_yes_clean_other_accessor(klass, full_name)
        when :csv
          def_csv_accessor(klass, full_name)
        when :element, :attribute
          recommended_attribute_name, = *args
          klass_name = "ITunes#{Utils.to_class_name(name)}"
          klass.def_classed_element(full_name, klass_name,
                                    recommended_attribute_name)
        when :elements
          plural_name, recommended_attribute_name = args
          plural_name ||= "#{name}s"
          full_plural_name = "#{RSS::ITUNES_PREFIX}_#{plural_name}"
          klass_name = "ITunes#{Utils.to_class_name(name)}"
          plural_klass_name = "ITunes#{Utils.to_class_name(plural_name)}"
          def_elements_class_accessor(klass, name, full_name, full_plural_name,
                                      klass_name, plural_klass_name,
                                      recommended_attribute_name)
        end
      end

      def def_yes_other_accessor(klass, full_name)
        klass.def_other_element(full_name)
        klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
          def #{full_name}?
            Utils::YesOther.parse(@#{full_name})
          end
        EOC
      end

      def def_yes_clean_other_accessor(klass, full_name)
        klass.def_other_element(full_name)
        klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
          def #{full_name}?
            Utils::YesCleanOther.parse(#{full_name})
          end
        EOC
      end

      def def_csv_accessor(klass, full_name)
        klass.def_csv_element(full_name)
      end

      def def_elements_class_accessor(klass, name, full_name, full_plural_name,
                                      klass_name, plural_klass_name,
                                      recommended_attribute_name=nil)
        if recommended_attribute_name
          klass.def_classed_elements(full_name, recommended_attribute_name,
                                     plural_klass_name, full_plural_name)
        else
          klass.def_classed_element(full_plural_name, plural_klass_name)
        end
        klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
          def new_#{full_name}(text=nil)
            #{full_name} = @#{full_plural_name}.new_#{name}
            #{full_name}.text = text
            if block_given?
              yield #{full_name}
            else
              #{full_name}
            end
          end
        EOC
      end
    end

    module ITunesChannelModel
      extend ITunesBaseModel

      class << self
        def append_features(klass)
          super

          ::RSS::ITunesChannelModel::ELEMENT_INFOS.each do |name, type, *args|
            def_class_accessor(klass, name, type, *args)
          end
        end
      end

      class ITunesCategoriesBase < Base
        def_array_element("category", "itunes_categories",
                          "ITunesCategory")
        class ITunesCategoryBase < Base
          attr_accessor :text
          add_need_initialize_variable("text")
          def_array_element("category", "itunes_categories",
                            "ITunesCategory")

          def have_required_values?
            text
          end

          alias_method :to_feed_for_categories, :to_feed
          def to_feed(feed, current)
            if text and current.respond_to?(:itunes_category)
              new_item = current.class::ITunesCategory.new(text)
              to_feed_for_categories(feed, new_item)
              current.itunes_categories << new_item
            end
          end
        end
      end

      class ITunesImageBase < Base
        add_need_initialize_variable("href")
        attr_accessor("href")

        def to_feed(feed, current)
          if @href and current.respond_to?(:itunes_image)
            current.itunes_image ||= current.class::ITunesImage.new
            current.itunes_image.href = @href
          end
        end
      end

      class ITunesOwnerBase < Base
        %w(itunes_name itunes_email).each do |name|
          add_need_initialize_variable(name)
          attr_accessor(name)
        end

        def to_feed(feed, current)
          if current.respond_to?(:itunes_owner=)
            _not_set_required_variables = not_set_required_variables
            if (required_variable_names - _not_set_required_variables).empty?
              return
            end

            unless have_required_values?
              raise NotSetError.new("maker.channel.itunes_owner",
                                    _not_set_required_variables)
            end
            current.itunes_owner ||= current.class::ITunesOwner.new
            current.itunes_owner.itunes_name = @itunes_name
            current.itunes_owner.itunes_email = @itunes_email
          end
        end

        private
        def required_variable_names
          %w(itunes_name itunes_email)
        end
      end
    end

    module ITunesItemModel
      extend ITunesBaseModel

      class << self
        def append_features(klass)
          super

          ::RSS::ITunesItemModel::ELEMENT_INFOS.each do |name, type, *args|
            def_class_accessor(klass, name, type, *args)
          end
        end
      end

      class ITunesDurationBase < Base
        attr_reader :content
        add_need_initialize_variable("content")

        %w(hour minute second).each do |name|
          attr_reader(name)
          add_need_initialize_variable(name, '0')
        end

        def content=(content)
          if content.nil?
            @hour, @minute, @second, @content = nil
          else
            @hour, @minute, @second =
              ::RSS::ITunesItemModel::ITunesDuration.parse(content)
            @content = content
          end
        end

        def hour=(hour)
          @hour = Integer(hour)
          update_content
        end

        def minute=(minute)
          @minute = Integer(minute)
          update_content
        end

        def second=(second)
          @second = Integer(second)
          update_content
        end

        def to_feed(feed, current)
          if @content and current.respond_to?(:itunes_duration=)
            current.itunes_duration ||= current.class::ITunesDuration.new
            current.itunes_duration.content = @content
          end
        end

        private
        def update_content
          components = [@hour, @minute, @second]
          @content =
            ::RSS::ITunesItemModel::ITunesDuration.construct(*components)
        end
      end
    end

    class ChannelBase
      include Maker::ITunesChannelModel
      class ITunesCategories < ITunesCategoriesBase
        class ITunesCategory < ITunesCategoryBase
          ITunesCategory = self
        end
      end

      class ITunesImage < ITunesImageBase; end
      class ITunesOwner < ITunesOwnerBase; end
    end

    class ItemsBase
      class ItemBase
        include Maker::ITunesItemModel
        class ITunesDuration < ITunesDurationBase; end
      end
    end
  end
end
PK     Y\tP  P    rss/maker/trackback.rbnu [        require 'rss/trackback'
require 'rss/maker/1.0'
require 'rss/maker/2.0'

module RSS
  module Maker
    module TrackBackModel
      def self.append_features(klass)
        super

        klass.def_other_element("#{RSS::TRACKBACK_PREFIX}_ping")
        klass.def_classed_elements("#{RSS::TRACKBACK_PREFIX}_about", "value",
                                   "TrackBackAbouts")
      end

      class TrackBackAboutsBase < Base
        def_array_element("about", nil, "TrackBackAbout")

        class TrackBackAboutBase < Base
          attr_accessor :value
          add_need_initialize_variable("value")
          
          alias_method(:resource, :value)
          alias_method(:resource=, :value=)
          alias_method(:content, :value)
          alias_method(:content=, :value=)

          def have_required_values?
            @value
          end

          def to_feed(feed, current)
            if current.respond_to?(:trackback_abouts) and have_required_values?
              about = current.class::TrackBackAbout.new
              setup_values(about)
              setup_other_elements(about)
              current.trackback_abouts << about
            end
          end
        end
      end
    end

    class ItemsBase
      class ItemBase; include TrackBackModel; end
    end

    makers.each do |maker|
      maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
        class Items
          class Item
            class TrackBackAbouts < TrackBackAboutsBase
              class TrackBackAbout < TrackBackAboutBase
              end
            end
          end
        end
      EOC
    end
  end
end
PK     Y\ц2  2    rss/maker/feed.rbnu [        require "rss/maker/atom"

module RSS
  module Maker
    module Atom
      class Feed < RSSBase
        def initialize(feed_version="1.0")
          super
          @feed_type = "atom"
          @feed_subtype = "feed"
        end

        private
        def make_feed
          ::RSS::Atom::Feed.new(@version, @encoding, @standalone)
        end

        def setup_elements(feed)
          setup_channel(feed)
          setup_image(feed)
          setup_items(feed)
        end

        class Channel < ChannelBase
          def to_feed(feed)
            set_default_values do
              setup_values(feed)
              feed.dc_dates.clear
              setup_other_elements(feed)
              if image_favicon.about
                icon = feed.class::Icon.new
                icon.content = image_favicon.about
                feed.icon = icon
              end
              unless have_required_values?
                raise NotSetError.new("maker.channel",
                                      not_set_required_variables)
              end
            end
          end

          def have_required_values?
            super and
              (!authors.empty? or
               @maker.items.any? {|item| !item.authors.empty?})
          end

          private
          def required_variable_names
            %w(id updated)
          end

          def variables
            super + %w(id updated)
          end

          def variable_is_set?
            super or !authors.empty?
          end

          def not_set_required_variables
            vars = super
            if authors.empty? and
                @maker.items.all? {|item| item.author.to_s.empty?}
              vars << "author"
            end
            vars << "title" unless title {|t| t.have_required_values?}
            vars
          end

          def _set_default_values(&block)
            keep = {
              :id => id,
              :updated => updated,
            }
            self.id ||= about
            self.updated ||= dc_date
            super(&block)
          ensure
            self.id = keep[:id]
            self.updated = keep[:updated]
          end

          class SkipDays < SkipDaysBase
            def to_feed(*args)
            end

            class Day < DayBase
            end
          end

          class SkipHours < SkipHoursBase
            def to_feed(*args)
            end

            class Hour < HourBase
            end
          end

          class Cloud < CloudBase
            def to_feed(*args)
            end
          end

          class Categories < CategoriesBase
            class Category < CategoryBase
              include AtomCategory

              def self.not_set_name
                "maker.channel.category"
              end
            end
          end

          class Links < LinksBase
            class Link < LinkBase
              include AtomLink

              def self.not_set_name
                "maker.channel.link"
              end
            end
          end

          AtomPersons.def_atom_persons(self, "author", "maker.channel.author")
          AtomPersons.def_atom_persons(self, "contributor",
                                       "maker.channel.contributor")

          class Generator < GeneratorBase
            include AtomGenerator

            def self.not_set_name
              "maker.channel.generator"
            end
          end

          AtomTextConstruct.def_atom_text_construct(self, "rights",
                                                    "maker.channel.copyright",
                                                    "Copyright")
          AtomTextConstruct.def_atom_text_construct(self, "subtitle",
                                                    "maker.channel.description",
                                                    "Description")
          AtomTextConstruct.def_atom_text_construct(self, "title",
                                                    "maker.channel.title")
        end

        class Image < ImageBase
          def to_feed(feed)
            logo = feed.class::Logo.new
            class << logo
              alias_method(:url=, :content=)
            end
            set = setup_values(logo)
            class << logo
              remove_method(:url=)
            end
            if set
              feed.logo = logo
              set_parent(logo, feed)
              setup_other_elements(feed, logo)
            elsif variable_is_set?
              raise NotSetError.new("maker.image", not_set_required_variables)
            end
          end

          private
          def required_variable_names
            %w(url)
          end
        end

        class Items < ItemsBase
          def to_feed(feed)
            normalize.each do |item|
              item.to_feed(feed)
            end
            setup_other_elements(feed, feed.entries)
          end

          class Item < ItemBase
            def to_feed(feed)
              set_default_values do
                entry = feed.class::Entry.new
                set = setup_values(entry)
                setup_other_elements(feed, entry)
                if set
                  feed.entries << entry
                  set_parent(entry, feed)
                elsif variable_is_set?
                  raise NotSetError.new("maker.item", not_set_required_variables)
                end
              end
            end

            def have_required_values?
              set_default_values do
                super and title {|t| t.have_required_values?}
              end
            end

            private
            def required_variable_names
              %w(id updated)
            end

            def variables
              super + ["updated"]
            end

            def not_set_required_variables
              vars = super
              vars << "title" unless title {|t| t.have_required_values?}
              vars
            end

            def _set_default_values(&block)
              keep = {
                :id => id,
                :updated => updated,
              }
              self.id ||= link
              self.updated ||= dc_date
              super(&block)
            ensure
              self.id = keep[:id]
              self.updated = keep[:updated]
            end

            class Guid < GuidBase
              def to_feed(feed, current)
              end
            end

            class Enclosure < EnclosureBase
              def to_feed(feed, current)
              end
            end

            class Source < SourceBase
              def to_feed(feed, current)
                source = current.class::Source.new
                setup_values(source)
                current.source = source
                set_parent(source, current)
                setup_other_elements(feed, source)
                current.source = nil if source.to_s == "<source/>"
              end

              private
              def required_variable_names
                []
              end

              def variables
                super + ["updated"]
              end

              AtomPersons.def_atom_persons(self, "author",
                                           "maker.item.source.author")
              AtomPersons.def_atom_persons(self, "contributor",
                                           "maker.item.source.contributor")

              class Categories < CategoriesBase
                class Category < CategoryBase
                  include AtomCategory

                  def self.not_set_name
                    "maker.item.source.category"
                  end
                end
              end

              class Generator < GeneratorBase
                include AtomGenerator

                def self.not_set_name
                  "maker.item.source.generator"
                end
              end

              class Icon < IconBase
                def to_feed(feed, current)
                  icon = current.class::Icon.new
                  class << icon
                    alias_method(:url=, :content=)
                  end
                  set = setup_values(icon)
                  class << icon
                    remove_method(:url=)
                  end
                  if set
                    current.icon = icon
                    set_parent(icon, current)
                    setup_other_elements(feed, icon)
                  elsif variable_is_set?
                    raise NotSetError.new("maker.item.source.icon",
                                          not_set_required_variables)
                  end
                end

                private
                def required_variable_names
                  %w(url)
                end
              end

              class Links < LinksBase
                class Link < LinkBase
                  include AtomLink

                  def self.not_set_name
                    "maker.item.source.link"
                  end
                end
              end

              class Logo < LogoBase
                include AtomLogo

                def self.not_set_name
                  "maker.item.source.logo"
                end
              end

              maker_name_base = "maker.item.source."
              maker_name = "#{maker_name_base}rights"
              AtomTextConstruct.def_atom_text_construct(self, "rights",
                                                        maker_name)
              maker_name = "#{maker_name_base}subtitle"
              AtomTextConstruct.def_atom_text_construct(self, "subtitle",
                                                        maker_name)
              maker_name = "#{maker_name_base}title"
              AtomTextConstruct.def_atom_text_construct(self, "title",
                                                        maker_name)
            end

            class Categories < CategoriesBase
              class Category < CategoryBase
                include AtomCategory

                def self.not_set_name
                  "maker.item.category"
                end
              end
            end

            AtomPersons.def_atom_persons(self, "author", "maker.item.author")
            AtomPersons.def_atom_persons(self, "contributor",
                                         "maker.item.contributor")

            class Links < LinksBase
              class Link < LinkBase
                include AtomLink

                def self.not_set_name
                  "maker.item.link"
                end
              end
            end

            AtomTextConstruct.def_atom_text_construct(self, "rights",
                                                      "maker.item.rights")
            AtomTextConstruct.def_atom_text_construct(self, "summary",
                                                      "maker.item.description",
                                                      "Description")
            AtomTextConstruct.def_atom_text_construct(self, "title",
                                                      "maker.item.title")

            class Content < ContentBase
              def to_feed(feed, current)
                content = current.class::Content.new
                if setup_values(content)
                  content.src = nil if content.src and content.content
                  current.content = content
                  set_parent(content, current)
                  setup_other_elements(feed, content)
                elsif variable_is_set?
                  raise NotSetError.new("maker.item.content",
                                        not_set_required_variables)
                end
              end

              alias_method(:xml, :xml_content)

              private
              def required_variable_names
                if out_of_line?
                  %w(type)
                elsif xml_type?
                  %w(xml_content)
                else
                  %w(content)
                end
              end

              def variables
                if out_of_line?
                  super
                elsif xml_type?
                  super + %w(xml)
                else
                  super
                end
              end

              def xml_type?
                _type = type
                return false if _type.nil?
                _type == "xhtml" or
                  /(?:\+xml|\/xml)$/i =~ _type or
                  %w(text/xml-external-parsed-entity
                     application/xml-external-parsed-entity
                     application/xml-dtd).include?(_type.downcase)
              end
            end
          end
        end

        class Textinput < TextinputBase
        end
      end
    end

    add_maker("atom", "1.0", Atom::Feed)
    add_maker("atom:feed", "1.0", Atom::Feed)
    add_maker("atom1.0", "1.0", Atom::Feed)
    add_maker("atom1.0:feed", "1.0", Atom::Feed)
  end
end
PK     Y\%I{      rss/dublincore.rbnu [        require "rss/rss"

module RSS
  DC_PREFIX = 'dc'
  DC_URI = "http://purl.org/dc/elements/1.1/"

  module BaseDublinCoreModel
    def append_features(klass)
      super

      return if klass.instance_of?(Module)
      DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
        plural = plural_name || "#{name}s"
        full_name = "#{DC_PREFIX}_#{name}"
        full_plural_name = "#{DC_PREFIX}_#{plural}"
        klass_name = "DublinCore#{Utils.to_class_name(name)}"
        klass.install_must_call_validator(DC_PREFIX, DC_URI)
        klass.install_have_children_element(name, DC_URI, "*",
                                            full_name, full_plural_name)
        klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))
          remove_method :#{full_name}
          remove_method :#{full_name}=
          remove_method :set_#{full_name}

          def #{full_name}
            @#{full_name}.first and @#{full_name}.first.value
          end
          
          def #{full_name}=(new_value)
            @#{full_name}[0] = Utils.new_with_value_if_need(#{klass_name}, new_value)
          end
          alias set_#{full_name} #{full_name}=
        EOC
      end
      klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))
        if method_defined?(:date)
          alias date_without_#{DC_PREFIX}_date= date=

          def date=(value)
            self.date_without_#{DC_PREFIX}_date = value
            self.#{DC_PREFIX}_date = value
          end
        else
          alias date #{DC_PREFIX}_date
          alias date= #{DC_PREFIX}_date=
        end

        # For backward compatibility
        alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list
      EOC
    end
  end
  
  module DublinCoreModel

    extend BaseModel
    extend BaseDublinCoreModel

    TEXT_ELEMENTS = {
      "title" => nil,
      "description" => nil,
      "creator" => nil,
      "subject" => nil,
      "publisher" => nil,
      "contributor" => nil,
      "type" => nil,
      "format" => nil,
      "identifier" => nil,
      "source" => nil,
      "language" => nil,
      "relation" => nil,
      "coverage" => nil,
      "rights" => "rights_list"
    }

    DATE_ELEMENTS = {
      "date" => "w3cdtf",
    }
    
    ELEMENT_NAME_INFOS = DublinCoreModel::TEXT_ELEMENTS.to_a
    DublinCoreModel::DATE_ELEMENTS.each do |name, |
      ELEMENT_NAME_INFOS << [name, nil]
    end
    
    ELEMENTS = TEXT_ELEMENTS.keys + DATE_ELEMENTS.keys

    ELEMENTS.each do |name, plural_name|
      module_eval(<<-EOC, *get_file_and_line_from_caller(0))
        class DublinCore#{Utils.to_class_name(name)} < Element
          include RSS10
          
          content_setup

          class << self
            def required_prefix
              DC_PREFIX
            end
        
            def required_uri
              DC_URI
            end
          end

          @tag_name = #{name.dump}

          alias_method(:value, :content)
          alias_method(:value=, :content=)
          
          def initialize(*args)
            if Utils.element_initialize_arguments?(args)
              super
            else
              super()
              self.content = args[0]
            end
          end
      
          def full_name
            tag_name_with_prefix(DC_PREFIX)
          end

          def maker_target(target)
            target.new_#{name}
          end

          def setup_maker_attributes(#{name})
            #{name}.content = content
          end
        end
      EOC
    end

    DATE_ELEMENTS.each do |name, type|
      tag_name = "#{DC_PREFIX}:#{name}"
      module_eval(<<-EOC, *get_file_and_line_from_caller(0))
        class DublinCore#{Utils.to_class_name(name)} < Element
          remove_method(:content=)
          remove_method(:value=)

          date_writer("content", #{type.dump}, #{tag_name.dump})

          alias_method(:value=, :content=)
        end
      EOC
    end
  end

  # For backward compatibility
  DublincoreModel = DublinCoreModel

  DublinCoreModel::ELEMENTS.each do |name|
    class_name = Utils.to_class_name(name)
    BaseListener.install_class_name(DC_URI, name, "DublinCore#{class_name}")
  end

  DublinCoreModel::ELEMENTS.collect! {|name| "#{DC_PREFIX}_#{name}"}
end

require 'rss/dublincore/1.0'
require 'rss/dublincore/2.0'
require 'rss/dublincore/atom'
PK     Y\9'  '    rss/itunes.rbnu [        require 'rss/2.0'

module RSS
  ITUNES_PREFIX = 'itunes'
  ITUNES_URI = 'http://www.itunes.com/dtds/podcast-1.0.dtd'

  Rss.install_ns(ITUNES_PREFIX, ITUNES_URI)

  module ITunesModelUtils
    include Utils

    def def_class_accessor(klass, name, type, *args)
        normalized_name = name.gsub(/-/, "_")
      full_name = "#{ITUNES_PREFIX}_#{normalized_name}"
      klass_name = "ITunes#{Utils.to_class_name(normalized_name)}"

      case type
      when :element, :attribute
        klass::ELEMENTS << full_name
        def_element_class_accessor(klass, name, full_name, klass_name, *args)
      when :elements
        klass::ELEMENTS << full_name
        def_elements_class_accessor(klass, name, full_name, klass_name, *args)
      else
        klass.install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)
        klass.install_text_element(normalized_name, ITUNES_URI, "?",
                                   full_name, type, name)
      end
    end

    def def_element_class_accessor(klass, name, full_name, klass_name,
                                   recommended_attribute_name=nil)
      klass.install_have_child_element(name, ITUNES_PREFIX, "?", full_name)
    end

    def def_elements_class_accessor(klass, name, full_name, klass_name,
                                    plural_name, recommended_attribute_name=nil)
      full_plural_name = "#{ITUNES_PREFIX}_#{plural_name}"
      klass.install_have_children_element(name, ITUNES_PREFIX, "*",
                                          full_name, full_plural_name)
    end
  end

  module ITunesBaseModel
    extend ITunesModelUtils

    ELEMENTS = []

    ELEMENT_INFOS = [["author"],
                     ["block", :yes_other],
                     ["explicit", :yes_clean_other],
                     ["keywords", :csv],
                     ["subtitle"],
                     ["summary"]]
  end

  module ITunesChannelModel
    extend BaseModel
    extend ITunesModelUtils
    include ITunesBaseModel

    ELEMENTS = []

    class << self
      def append_features(klass)
        super

        return if klass.instance_of?(Module)
        ELEMENT_INFOS.each do |name, type, *additional_infos|
          def_class_accessor(klass, name, type, *additional_infos)
        end
      end
    end

    ELEMENT_INFOS = [
                     ["category", :elements, "categories", "text"],
                     ["image", :attribute, "href"],
                     ["owner", :element],
                     ["new-feed-url"],
                    ] + ITunesBaseModel::ELEMENT_INFOS

    class ITunesCategory < Element
      include RSS09

      @tag_name = "category"

      class << self
        def required_prefix
          ITUNES_PREFIX
        end

        def required_uri
          ITUNES_URI
        end
      end

      [
        ["text", "", true]
      ].each do |name, uri, required|
        install_get_attribute(name, uri, required)
      end

      ITunesCategory = self
      install_have_children_element("category", ITUNES_URI, "*",
                                    "#{ITUNES_PREFIX}_category",
                                    "#{ITUNES_PREFIX}_categories")

      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.text = args[0]
        end
      end

      def full_name
        tag_name_with_prefix(ITUNES_PREFIX)
      end

      private
      def maker_target(categories)
        if text or !itunes_categories.empty?
          categories.new_category
        else
          nil
        end
      end

      def setup_maker_attributes(category)
        category.text = text if text
      end

      def setup_maker_elements(category)
        super(category)
        itunes_categories.each do |sub_category|
          sub_category.setup_maker(category)
        end
      end
    end

    class ITunesImage < Element
      include RSS09

      @tag_name = "image"

      class << self
        def required_prefix
          ITUNES_PREFIX
        end

        def required_uri
          ITUNES_URI
        end
      end

      [
        ["href", "", true]
      ].each do |name, uri, required|
        install_get_attribute(name, uri, required)
      end

      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.href = args[0]
        end
      end

      def full_name
        tag_name_with_prefix(ITUNES_PREFIX)
      end

      private
      def maker_target(target)
        if href
          target.itunes_image {|image| image}
        else
          nil
        end
      end

      def setup_maker_attributes(image)
        image.href = href
      end
    end

    class ITunesOwner < Element
      include RSS09

      @tag_name = "owner"

      class << self
        def required_prefix
          ITUNES_PREFIX
        end

        def required_uri
          ITUNES_URI
        end
      end

      install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)
      [
        ["name"],
        ["email"],
      ].each do |name,|
        ITunesBaseModel::ELEMENT_INFOS << name
        install_text_element(name, ITUNES_URI, nil, "#{ITUNES_PREFIX}_#{name}")
      end

      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.itunes_name = args[0]
          self.itunes_email = args[1]
        end
      end

      def full_name
        tag_name_with_prefix(ITUNES_PREFIX)
      end

      private
      def maker_target(target)
        target.itunes_owner
      end

      def setup_maker_element(owner)
        super(owner)
        owner.itunes_name = itunes_name
        owner.itunes_email = itunes_email
      end
    end
  end

  module ITunesItemModel
    extend BaseModel
    extend ITunesModelUtils
    include ITunesBaseModel

    class << self
      def append_features(klass)
        super

        return if klass.instance_of?(Module)
        ELEMENT_INFOS.each do |name, type|
          def_class_accessor(klass, name, type)
        end
      end
    end

    ELEMENT_INFOS = ITunesBaseModel::ELEMENT_INFOS +
      [["duration", :element, "content"]]

    class ITunesDuration < Element
      include RSS09

      @tag_name = "duration"

      class << self
        def required_prefix
          ITUNES_PREFIX
        end

        def required_uri
          ITUNES_URI
        end

        def parse(duration, do_validate=true)
          if do_validate and /\A(?:
                                  \d?\d:[0-5]\d:[0-5]\d|
                                  [0-5]?\d:[0-5]\d
                                )\z/x !~ duration
            raise ArgumentError,
                    "must be one of HH:MM:SS, H:MM:SS, MM::SS, M:SS: " +
                    duration.inspect
          end

          components = duration.split(':')
          components[3..-1] = nil if components.size > 3

          components.unshift("00") until components.size == 3

          components.collect do |component|
            component.to_i
          end
        end

        def construct(hour, minute, second)
          components = [minute, second]
          if components.include?(nil)
            nil
          else
            components.unshift(hour) if hour and hour > 0
            components.collect do |component|
              "%02d" % component
            end.join(":")
          end
        end
      end

      content_setup
      alias_method(:value, :content)
      remove_method(:content=)

      attr_reader :hour, :minute, :second
      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          args = args[0] if args.size == 1 and args[0].is_a?(Array)
          if args.size == 1
            self.content = args[0]
          elsif args.size > 3
            raise ArgumentError,
                    "must be (do_validate, params), (content), " +
                    "(minute, second), ([minute, second]), "  +
                    "(hour, minute, second) or ([hour, minute, second]): " +
                    args.inspect
          else
            @second, @minute, @hour = args.reverse
            update_content
          end
        end
      end

      def content=(value)
        if value.nil?
          @content = nil
        elsif value.is_a?(self.class)
          self.content = value.content
        else
          begin
            @hour, @minute, @second = self.class.parse(value, @do_validate)
          rescue ArgumentError
            raise NotAvailableValueError.new(tag_name, value)
          end
          @content = value
        end
      end
      alias_method(:value=, :content=)

      def hour=(hour)
        @hour = @do_validate ? Integer(hour) : hour.to_i
        update_content
        hour
      end

      def minute=(minute)
        @minute = @do_validate ? Integer(minute) : minute.to_i
        update_content
        minute
      end

      def second=(second)
        @second = @do_validate ? Integer(second) : second.to_i
        update_content
        second
      end

      def full_name
        tag_name_with_prefix(ITUNES_PREFIX)
      end

      private
      def update_content
        @content = self.class.construct(hour, minute, second)
      end

      def maker_target(target)
        if @content
          target.itunes_duration {|duration| duration}
        else
          nil
        end
      end

      def setup_maker_element(duration)
        super(duration)
        duration.content = @content
      end
    end
  end

  class Rss
    class Channel
      include ITunesChannelModel
      class Item; include ITunesItemModel; end
    end
  end

  element_infos =
    ITunesChannelModel::ELEMENT_INFOS + ITunesItemModel::ELEMENT_INFOS
  element_infos.each do |name, type|
    case type
    when :element, :elements, :attribute
      class_name = Utils.to_class_name(name)
      BaseListener.install_class_name(ITUNES_URI, name, "ITunes#{class_name}")
    else
      accessor_base = "#{ITUNES_PREFIX}_#{name.gsub(/-/, '_')}"
      BaseListener.install_get_text_element(ITUNES_URI, name, accessor_base)
    end
  end
end
PK     Y\*>>:  :    rss/parser.rbnu [        require "forwardable"
require "open-uri"

require "rss/rss"
require "rss/xml"

module RSS

  class NotWellFormedError < Error
    attr_reader :line, :element

    # Create a new NotWellFormedError for an error at +line+
    # in +element+.  If a block is given the return value of
    # the block ends up in the error message.
    def initialize(line=nil, element=nil)
      message = "This is not well formed XML"
      if element or line
        message << "\nerror occurred"
        message << " in #{element}" if element
        message << " at about #{line} line" if line
      end
      message << "\n#{yield}" if block_given?
      super(message)
    end
  end

  class XMLParserNotFound < Error
    def initialize
      super("available XML parser was not found in " <<
            "#{AVAILABLE_PARSER_LIBRARIES.inspect}.")
    end
  end

  class NotValidXMLParser < Error
    def initialize(parser)
      super("#{parser} is not an available XML parser. " <<
            "Available XML parser"<<
            (AVAILABLE_PARSERS.size > 1 ? "s are ": " is ") <<
            "#{AVAILABLE_PARSERS.inspect}.")
    end
  end

  class NSError < InvalidRSSError
    attr_reader :tag, :prefix, :uri
    def initialize(tag, prefix, require_uri)
      @tag, @prefix, @uri = tag, prefix, require_uri
      super("prefix <#{prefix}> doesn't associate uri " <<
            "<#{require_uri}> in tag <#{tag}>")
    end
  end

  class Parser

    extend Forwardable

    class << self

      @@default_parser = nil

      def default_parser
        @@default_parser || AVAILABLE_PARSERS.first
      end

      # Set @@default_parser to new_value if it is one of the
      # available parsers. Else raise NotValidXMLParser error.
      def default_parser=(new_value)
        if AVAILABLE_PARSERS.include?(new_value)
          @@default_parser = new_value
        else
          raise NotValidXMLParser.new(new_value)
        end
      end

      def parse(rss, do_validate=true, ignore_unknown_element=true,
                parser_class=default_parser)
        parser = new(rss, parser_class)
        parser.do_validate = do_validate
        parser.ignore_unknown_element = ignore_unknown_element
        parser.parse
      end
    end

    def_delegators(:@parser, :parse, :rss,
                   :ignore_unknown_element,
                   :ignore_unknown_element=, :do_validate,
                   :do_validate=)

    def initialize(rss, parser_class=self.class.default_parser)
      @parser = parser_class.new(normalize_rss(rss))
    end

    private

    # Try to get the XML associated with +rss+.
    # Return +rss+ if it already looks like XML, or treat it as a URI,
    # or a file to get the XML,
    def normalize_rss(rss)
      return rss if maybe_xml?(rss)

      uri = to_uri(rss)
      
      if uri.respond_to?(:read)
        uri.read
      elsif !rss.tainted? and File.readable?(rss)
        File.open(rss) {|f| f.read}
      else
        rss
      end
    end

    # maybe_xml? tests if source is a string that looks like XML.
    def maybe_xml?(source)
      source.is_a?(String) and /</ =~ source
    end

    # Attempt to convert rss to a URI, but just return it if 
    # there's a ::URI::Error
    def to_uri(rss)
      return rss if rss.is_a?(::URI::Generic)

      begin
        ::URI.parse(rss)
      rescue ::URI::Error
        rss
      end
    end
  end

  class BaseParser

    class << self
      def raise_for_undefined_entity?
        listener.raise_for_undefined_entity?
      end
    end
    
    def initialize(rss)
      @listener = self.class.listener.new
      @rss = rss
    end

    def rss
      @listener.rss
    end

    def ignore_unknown_element
      @listener.ignore_unknown_element
    end

    def ignore_unknown_element=(new_value)
      @listener.ignore_unknown_element = new_value
    end

    def do_validate
      @listener.do_validate
    end

    def do_validate=(new_value)
      @listener.do_validate = new_value
    end

    def parse
      if @listener.rss.nil?
        _parse
      end
      @listener.rss
    end

  end

  class BaseListener

    extend Utils

    class << self

      @@accessor_bases = {}
      @@registered_uris = {}
      @@class_names = {}

      # return the setter for the uri, tag_name pair, or nil.
      def setter(uri, tag_name)
        _getter = getter(uri, tag_name)
        if _getter
          "#{_getter}="
        else
          nil
        end
      end

      def getter(uri, tag_name)
        (@@accessor_bases[uri] || {})[tag_name]
      end

      # return the tag_names for setters associated with uri
      def available_tags(uri)
        (@@accessor_bases[uri] || {}).keys
      end
      
      # register uri against this name.
      def register_uri(uri, name)
        @@registered_uris[name] ||= {}
        @@registered_uris[name][uri] = nil
      end
      
      # test if this uri is registered against this name
      def uri_registered?(uri, name)
        @@registered_uris[name].has_key?(uri)
      end

      # record class_name for the supplied uri and tag_name
      def install_class_name(uri, tag_name, class_name)
        @@class_names[uri] ||= {}
        @@class_names[uri][tag_name] = class_name
      end

      # retrieve class_name for the supplied uri and tag_name
      # If it doesn't exist, capitalize the tag_name
      def class_name(uri, tag_name)
        name = (@@class_names[uri] || {})[tag_name]
        return name if name

        tag_name = tag_name.gsub(/[_\-]([a-z]?)/) do
          $1.upcase
        end
        tag_name[0, 1].upcase + tag_name[1..-1]
      end

      def install_get_text_element(uri, name, accessor_base)
        install_accessor_base(uri, name, accessor_base)
        def_get_text_element(uri, name, *get_file_and_line_from_caller(1))
      end
      
      def raise_for_undefined_entity?
        true
      end
    
      private
      # set the accessor for the uri, tag_name pair
      def install_accessor_base(uri, tag_name, accessor_base)
        @@accessor_bases[uri] ||= {}
        @@accessor_bases[uri][tag_name] = accessor_base.chomp("=")
      end

      def def_get_text_element(uri, element_name, file, line)
        register_uri(uri, element_name)
        method_name = "start_#{element_name}"
        unless private_method_defined?(method_name)
          define_method(method_name) do |name, prefix, attrs, ns|
            uri = _ns(ns, prefix)
            if self.class.uri_registered?(uri, element_name)
              start_get_text_element(name, prefix, ns, uri)
            else
              start_else_element(name, prefix, attrs, ns)
            end
          end
          private(method_name)
        end
      end
    end
  end

  module ListenerMixin
    attr_reader :rss

    attr_accessor :ignore_unknown_element
    attr_accessor :do_validate

    def initialize
      @rss = nil
      @ignore_unknown_element = true
      @do_validate = true
      @ns_stack = [{"xml" => :xml}]
      @tag_stack = [[]]
      @text_stack = ['']
      @proc_stack = []
      @last_element = nil
      @version = @encoding = @standalone = nil
      @xml_stylesheets = []
      @xml_child_mode = false
      @xml_element = nil
      @last_xml_element = nil
    end
    
    # set instance vars for version, encoding, standalone
    def xmldecl(version, encoding, standalone)
      @version, @encoding, @standalone = version, encoding, standalone
    end

    def instruction(name, content)
      if name == "xml-stylesheet"
        params = parse_pi_content(content)
        if params.has_key?("href")
          @xml_stylesheets << XMLStyleSheet.new(params)
        end
      end
    end

    def tag_start(name, attributes)
      @text_stack.push('')

      ns = @ns_stack.last.dup
      attrs = {}
      attributes.each do |n, v|
        if /\Axmlns(?:\z|:)/ =~ n
          ns[$POSTMATCH] = v
        else
          attrs[n] = v
        end
      end
      @ns_stack.push(ns)

      prefix, local = split_name(name)
      @tag_stack.last.push([_ns(ns, prefix), local])
      @tag_stack.push([])
      if @xml_child_mode
        previous = @last_xml_element
        element_attrs = attributes.dup
        unless previous
          ns.each do |ns_prefix, value|
            next if ns_prefix == "xml"
            key = ns_prefix.empty? ? "xmlns" : "xmlns:#{ns_prefix}"
            element_attrs[key] ||= value
          end
        end
        next_element = XML::Element.new(local,
                                        prefix.empty? ? nil : prefix,
                                        _ns(ns, prefix),
                                        element_attrs)
        previous << next_element if previous
        @last_xml_element = next_element
        pr = Proc.new do |text, tags|
          if previous
            @last_xml_element = previous
          else
            @xml_element = @last_xml_element
            @last_xml_element = nil
          end
        end
        @proc_stack.push(pr)
      else
        if @rss.nil? and respond_to?("initial_start_#{local}", true)
          __send__("initial_start_#{local}", local, prefix, attrs, ns.dup)
        elsif respond_to?("start_#{local}", true)
          __send__("start_#{local}", local, prefix, attrs, ns.dup)
        else
          start_else_element(local, prefix, attrs, ns.dup)
        end
      end
    end

    def tag_end(name)
      if DEBUG
        p "end tag #{name}"
        p @tag_stack
      end
      text = @text_stack.pop
      tags = @tag_stack.pop
      pr = @proc_stack.pop
      pr.call(text, tags) unless pr.nil?
      @ns_stack.pop
    end

    def text(data)
      if @xml_child_mode
        @last_xml_element << data if @last_xml_element
      else
        @text_stack.last << data
      end
    end

    private
    def _ns(ns, prefix)
      ns.fetch(prefix, "")
    end

    CONTENT_PATTERN = /\s*([^=]+)=(["'])([^\2]+?)\2/
    # Extract the first name="value" pair from content.
    # Works with single quotes according to the constant
    # CONTENT_PATTERN. Return a Hash.
    def parse_pi_content(content)
      params = {}
      content.scan(CONTENT_PATTERN) do |name, quote, value|
        params[name] = value
      end
      params
    end

    def start_else_element(local, prefix, attrs, ns)
      class_name = self.class.class_name(_ns(ns, prefix), local)
      current_class = @last_element.class
      if class_name and
          (current_class.const_defined?(class_name) or
           current_class.constants.include?(class_name))
        next_class = current_class.const_get(class_name)
        start_have_something_element(local, prefix, attrs, ns, next_class)
      else
        if !@do_validate or @ignore_unknown_element
          @proc_stack.push(nil)
        else
          parent = "ROOT ELEMENT???"
          if current_class.tag_name
            parent = current_class.tag_name
          end
          raise NotExpectedTagError.new(local, _ns(ns, prefix), parent)
        end
      end
    end

    NAMESPLIT = /^(?:([\w:][-\w\d.]*):)?([\w:][-\w\d.]*)/
    def split_name(name)
      name =~ NAMESPLIT
      [$1 || '', $2]
    end

    def check_ns(tag_name, prefix, ns, require_uri)
      unless _ns(ns, prefix) == require_uri
        if @do_validate
          raise NSError.new(tag_name, prefix, require_uri)
        else
          # Force bind required URI with prefix
          @ns_stack.last[prefix] = require_uri
        end
      end
    end

    def start_get_text_element(tag_name, prefix, ns, required_uri)
      pr = Proc.new do |text, tags|
        setter = self.class.setter(required_uri, tag_name)
        if @last_element.respond_to?(setter)
          if @do_validate
            getter = self.class.getter(required_uri, tag_name)
            if @last_element.__send__(getter)
              raise TooMuchTagError.new(tag_name, @last_element.tag_name)
            end
          end
          @last_element.__send__(setter, text.to_s)
        else
          if @do_validate and !@ignore_unknown_element
            raise NotExpectedTagError.new(tag_name, _ns(ns, prefix),
                                          @last_element.tag_name)
          end
        end
      end
      @proc_stack.push(pr)
    end

    def start_have_something_element(tag_name, prefix, attrs, ns, klass)
      check_ns(tag_name, prefix, ns, klass.required_uri)
      attributes = collect_attributes(tag_name, prefix, attrs, ns, klass)
      @proc_stack.push(setup_next_element(tag_name, klass, attributes))
    end

    def collect_attributes(tag_name, prefix, attrs, ns, klass)
      attributes = {}
      klass.get_attributes.each do |a_name, a_uri, required, element_name|
        if a_uri.is_a?(String) or !a_uri.respond_to?(:include?)
          a_uri = [a_uri]
        end
        unless a_uri == [""]
          for prefix, uri in ns
            if a_uri.include?(uri)
              val = attrs["#{prefix}:#{a_name}"]
              break if val
            end
          end
        end
        if val.nil? and a_uri.include?("")
          val = attrs[a_name]
        end

        if @do_validate and required and val.nil?
          unless a_uri.include?("")
            for prefix, uri in ns
              if a_uri.include?(uri)
                a_name = "#{prefix}:#{a_name}"
              end
            end
          end
          raise MissingAttributeError.new(tag_name, a_name)
        end

        attributes[a_name] = val
      end
      attributes
    end

    def setup_next_element(tag_name, klass, attributes)
      previous = @last_element
      next_element = klass.new(@do_validate, attributes)
      previous.set_next_element(tag_name, next_element)
      @last_element = next_element
      @last_element.parent = previous if klass.need_parent?
      @xml_child_mode = @last_element.have_xml_content?

      Proc.new do |text, tags|
        p(@last_element.class) if DEBUG
        if @xml_child_mode
          @last_element.content = @xml_element.to_s
          xml_setter = @last_element.class.xml_setter
          @last_element.__send__(xml_setter, @xml_element)
          @xml_element = nil
          @xml_child_mode = false
        else
          if klass.have_content?
            if @last_element.need_base64_encode?
              text = Base64.decode64(text.lstrip)
            end
            @last_element.content = text
          end
        end
        if @do_validate
          @last_element.validate_for_stream(tags, @ignore_unknown_element)
        end
        @last_element = previous
      end
    end
  end

  unless const_defined? :AVAILABLE_PARSER_LIBRARIES
    AVAILABLE_PARSER_LIBRARIES = [
      ["rss/xmlparser", :XMLParserParser],
      ["rss/xmlscanner", :XMLScanParser],
      ["rss/rexmlparser", :REXMLParser],
    ]
  end

  AVAILABLE_PARSERS = []

  AVAILABLE_PARSER_LIBRARIES.each do |lib, parser|
    begin
      require lib
      AVAILABLE_PARSERS.push(const_get(parser))
    rescue LoadError
    end
  end

  if AVAILABLE_PARSERS.empty?
    raise XMLParserNotFound
  end
end
PK     Y\V
      rss/trackback.rbnu [        require 'rss/1.0'
require 'rss/2.0'

module RSS

  TRACKBACK_PREFIX = 'trackback'
  TRACKBACK_URI = 'http://madskills.com/public/xml/rss/module/trackback/'

  RDF.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI)
  Rss.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI)

  module TrackBackUtils
    private
    def trackback_validate(ignore_unknown_element, tags, uri)
      return if tags.nil?
      if tags.find {|tag| tag == "about"} and
          !tags.find {|tag| tag == "ping"}
        raise MissingTagError.new("#{TRACKBACK_PREFIX}:ping", tag_name)
      end
    end
  end

  module BaseTrackBackModel

    ELEMENTS = %w(ping about)
    
    def append_features(klass)
      super

      unless klass.class == Module
        klass.module_eval {include TrackBackUtils}

        klass.install_must_call_validator(TRACKBACK_PREFIX, TRACKBACK_URI)
        %w(ping).each do |name|
          var_name = "#{TRACKBACK_PREFIX}_#{name}"
          klass_name = "TrackBack#{Utils.to_class_name(name)}"
          klass.install_have_child_element(name, TRACKBACK_URI, "?", var_name)
          klass.module_eval(<<-EOC, __FILE__, __LINE__)
            remove_method :#{var_name}
            def #{var_name}
              @#{var_name} and @#{var_name}.value
            end

            remove_method :#{var_name}=
            def #{var_name}=(value)
              @#{var_name} = Utils.new_with_value_if_need(#{klass_name}, value)
            end
          EOC
        end
        
        [%w(about s)].each do |name, postfix|
          var_name = "#{TRACKBACK_PREFIX}_#{name}"
          klass_name = "TrackBack#{Utils.to_class_name(name)}"
          klass.install_have_children_element(name, TRACKBACK_URI, "*",
                                              var_name)
          klass.module_eval(<<-EOC, __FILE__, __LINE__)
            remove_method :#{var_name}
            def #{var_name}(*args)
              if args.empty?
                @#{var_name}.first and @#{var_name}.first.value
              else
                ret = @#{var_name}.__send__("[]", *args)
                if ret.is_a?(Array)
                  ret.collect {|x| x.value}
                else
                  ret.value
                end
              end
            end

            remove_method :#{var_name}=
            remove_method :set_#{var_name}
            def #{var_name}=(*args)
              if args.size == 1
                item = Utils.new_with_value_if_need(#{klass_name}, args[0])
                @#{var_name}.push(item)
              else
                new_val = args.last
                if new_val.is_a?(Array)
                  new_val = new_value.collect do |val|
                    Utils.new_with_value_if_need(#{klass_name}, val)
                  end
                else
                  new_val = Utils.new_with_value_if_need(#{klass_name}, new_val)
                end
                @#{var_name}.__send__("[]=", *(args[0..-2] + [new_val]))
              end
            end
            alias set_#{var_name} #{var_name}=
          EOC
        end
      end
    end
  end

  module TrackBackModel10
    extend BaseModel
    extend BaseTrackBackModel

    class TrackBackPing < Element
      include RSS10

      class << self

        def required_prefix
          TRACKBACK_PREFIX
        end
        
        def required_uri
          TRACKBACK_URI
        end

      end

      @tag_name = "ping"

      [
        ["resource", ::RSS::RDF::URI, true]
      ].each do |name, uri, required|
        install_get_attribute(name, uri, required, nil, nil,
                              "#{::RSS::RDF::PREFIX}:#{name}")
      end

      alias_method(:value, :resource)
      alias_method(:value=, :resource=)
      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.resource = args[0]
        end
      end

      def full_name
        tag_name_with_prefix(TRACKBACK_PREFIX)
      end
    end

    class TrackBackAbout < Element
      include RSS10

      class << self
        
        def required_prefix
          TRACKBACK_PREFIX
        end
        
        def required_uri
          TRACKBACK_URI
        end

      end
      
      @tag_name = "about"

      [
        ["resource", ::RSS::RDF::URI, true]
      ].each do |name, uri, required|
        install_get_attribute(name, uri, required, nil, nil,
                              "#{::RSS::RDF::PREFIX}:#{name}")
      end

      alias_method(:value, :resource)
      alias_method(:value=, :resource=)
      
      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.resource = args[0]
        end
      end

      def full_name
        tag_name_with_prefix(TRACKBACK_PREFIX)
      end

      private
      def maker_target(abouts)
        abouts.new_about
      end

      def setup_maker_attributes(about)
        about.resource = self.resource
      end
      
    end
  end

  module TrackBackModel20
    extend BaseModel
    extend BaseTrackBackModel

    class TrackBackPing < Element
      include RSS09

      @tag_name = "ping"
      
      content_setup

      class << self

        def required_prefix
          TRACKBACK_PREFIX
        end
        
        def required_uri
          TRACKBACK_URI
        end

      end
      
      alias_method(:value, :content)
      alias_method(:value=, :content=)

      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.content = args[0]
        end
      end
      
      def full_name
        tag_name_with_prefix(TRACKBACK_PREFIX)
      end
      
    end

    class TrackBackAbout < Element
      include RSS09

      @tag_name = "about"
      
      content_setup

      class << self
        
        def required_prefix
          TRACKBACK_PREFIX
        end
        
        def required_uri
          TRACKBACK_URI
        end

      end

      alias_method(:value, :content)
      alias_method(:value=, :content=)

      def initialize(*args)
        if Utils.element_initialize_arguments?(args)
          super
        else
          super()
          self.content = args[0]
        end
      end
      
      def full_name
        tag_name_with_prefix(TRACKBACK_PREFIX)
      end
      
    end
  end

  class RDF
    class Item; include TrackBackModel10; end
  end

  class Rss
    class Channel
      class Item; include TrackBackModel20; end
    end
  end

  BaseTrackBackModel::ELEMENTS.each do |name|
    class_name = Utils.to_class_name(name)
    BaseListener.install_class_name(TRACKBACK_URI, name,
                                    "TrackBack#{class_name}")
  end

  BaseTrackBackModel::ELEMENTS.collect! {|name| "#{TRACKBACK_PREFIX}_#{name}"}
end
PK     Y\#      rss/maker.rbnu [        require "rss/rss"

module RSS
  module Maker
    MAKERS = {}

    class << self
      def make(version, &block)
        m = maker(version)
        raise UnsupportedMakerVersionError.new(version) if m.nil?
        m[:maker].make(m[:version], &block)
      end

      def maker(version)
        MAKERS[version]
      end

      def add_maker(version, normalized_version, maker)
        MAKERS[version] = {:maker => maker, :version => normalized_version}
      end

      def versions
        MAKERS.keys.uniq.sort
      end

      def makers
        MAKERS.values.collect {|info| info[:maker]}.uniq
      end
    end
  end
end

require "rss/maker/1.0"
require "rss/maker/2.0"
require "rss/maker/feed"
require "rss/maker/entry"
require "rss/maker/content"
require "rss/maker/dublincore"
require "rss/maker/slash"
require "rss/maker/syndication"
require "rss/maker/taxonomy"
require "rss/maker/trackback"
require "rss/maker/image"
require "rss/maker/itunes"
PK     Y\>sq  q    rss/rexmlparser.rbnu [        require "rexml/document"
require "rexml/streamlistener"

/\A(\d+)\.(\d+)(?:\.\d+)+\z/ =~ REXML::Version
if ([$1.to_i, $2.to_i] <=> [2, 5]) < 0
  raise LoadError, "needs REXML 2.5 or later (#{REXML::Version})"
end

module RSS
  
  class REXMLParser < BaseParser

    class << self
      def listener
        REXMLListener
      end
    end
    
    private
    def _parse
      begin
        REXML::Document.parse_stream(@rss, @listener)
      rescue RuntimeError => e
        raise NotWellFormedError.new{e.message}
      rescue REXML::ParseException => e
        context = e.context
        line = context[0] if context
        raise NotWellFormedError.new(line){e.message}
      end
    end
    
  end
  
  class REXMLListener < BaseListener

    include REXML::StreamListener
    include ListenerMixin

    class << self
      def raise_for_undefined_entity?
        false
      end
    end
    
    def xmldecl(version, encoding, standalone)
      super(version, encoding, standalone == "yes")
      # Encoding is converted to UTF-8 when REXML parse XML.
      @encoding = 'UTF-8'
    end

    alias_method(:cdata, :text)
  end

end
PK     Y\x6&OS  S  	  resolv.rbnu [        require 'socket'
require 'fcntl'
require 'timeout'
require 'thread'

begin
  require 'securerandom'
rescue LoadError
end

# Resolv is a thread-aware DNS resolver library written in Ruby.  Resolv can
# handle multiple DNS requests concurrently without blocking.  The ruby
# interpreter.
#
# See also resolv-replace.rb to replace the libc resolver with # Resolv.
# 
# Resolv can look up various DNS resources using the DNS module directly.
# 
# Examples:
# 
#   p Resolv.getaddress "www.ruby-lang.org"
#   p Resolv.getname "210.251.121.214"
# 
#   Resolv::DNS.open do |dns|
#     ress = dns.getresources "www.ruby-lang.org", Resolv::DNS::Resource::IN::A
#     p ress.map { |r| r.address }
#     ress = dns.getresources "ruby-lang.org", Resolv::DNS::Resource::IN::MX
#     p ress.map { |r| [r.exchange.to_s, r.preference] }
#   end
# 
# 
# == Bugs
# 
# * NIS is not supported.
# * /etc/nsswitch.conf is not supported.

class Resolv

  ##
  # Looks up the first IP address for +name+.
  
  def self.getaddress(name)
    DefaultResolver.getaddress(name)
  end

  ##
  # Looks up all IP address for +name+.
  
  def self.getaddresses(name)
    DefaultResolver.getaddresses(name)
  end

  ##
  # Iterates over all IP addresses for +name+.

  def self.each_address(name, &block)
    DefaultResolver.each_address(name, &block)
  end

  ##
  # Looks up the hostname of +address+.

  def self.getname(address)
    DefaultResolver.getname(address)
  end

  ##
  # Looks up all hostnames for +address+.

  def self.getnames(address)
    DefaultResolver.getnames(address)
  end

  ##
  # Iterates over all hostnames for +address+.

  def self.each_name(address, &proc)
    DefaultResolver.each_name(address, &proc)
  end

  ##
  # Creates a new Resolv using +resolvers+.

  def initialize(resolvers=[Hosts.new, DNS.new])
    @resolvers = resolvers
  end

  ##
  # Looks up the first IP address for +name+.
  
  def getaddress(name)
    each_address(name) {|address| return address}
    raise ResolvError.new("no address for #{name}")
  end

  ##
  # Looks up all IP address for +name+.
  
  def getaddresses(name)
    ret = []
    each_address(name) {|address| ret << address}
    return ret
  end

  ##
  # Iterates over all IP addresses for +name+.

  def each_address(name)
    if AddressRegex =~ name
      yield name
      return
    end
    yielded = false
    @resolvers.each {|r|
      r.each_address(name) {|address|
        yield address.to_s
        yielded = true
      }
      return if yielded
    }
  end

  ##
  # Looks up the hostname of +address+.

  def getname(address)
    each_name(address) {|name| return name}
    raise ResolvError.new("no name for #{address}")
  end

  ##
  # Looks up all hostnames for +address+.

  def getnames(address)
    ret = []
    each_name(address) {|name| ret << name}
    return ret
  end

  ##
  # Iterates over all hostnames for +address+.

  def each_name(address)
    yielded = false
    @resolvers.each {|r|
      r.each_name(address) {|name|
        yield name.to_s
        yielded = true
      }
      return if yielded
    }
  end

  ##
  # Indicates a failure to resolve a name or address.

  class ResolvError < StandardError; end

  ##
  # Indicates a timeout resolving a name or address.

  class ResolvTimeout < TimeoutError; end

  ##
  # DNS::Hosts is a hostname resolver that uses the system hosts file.

  class Hosts
    if /mswin32|mingw|bccwin/ =~ RUBY_PLATFORM
      require 'win32/resolv'
      DefaultFileName = Win32::Resolv.get_hosts_path
    else
      DefaultFileName = '/etc/hosts'
    end

    ##
    # Creates a new DNS::Hosts, using +filename+ for its data source.

    def initialize(filename = DefaultFileName)
      @filename = filename
      @mutex = Mutex.new
      @initialized = nil
    end

    def lazy_initialize # :nodoc:
      @mutex.synchronize {
        unless @initialized
          @name2addr = {}
          @addr2name = {}
          open(@filename) {|f|
            f.each {|line|
              line.sub!(/#.*/, '')
              addr, hostname, *aliases = line.split(/\s+/)
              next unless addr
              addr.untaint
              hostname.untaint
              @addr2name[addr] = [] unless @addr2name.include? addr
              @addr2name[addr] << hostname
              @addr2name[addr] += aliases
              @name2addr[hostname] = [] unless @name2addr.include? hostname
              @name2addr[hostname] << addr
              aliases.each {|n|
                n.untaint
                @name2addr[n] = [] unless @name2addr.include? n
                @name2addr[n] << addr
              }
            }
          }
          @name2addr.each {|name, arr| arr.reverse!}
          @initialized = true
        end
      }
      self
    end

    ##
    # Gets the IP address of +name+ from the hosts file.

    def getaddress(name)
      each_address(name) {|address| return address}
      raise ResolvError.new("#{@filename} has no name: #{name}")
    end

    ##
    # Gets all IP addresses for +name+ from the hosts file.

    def getaddresses(name)
      ret = []
      each_address(name) {|address| ret << address}
      return ret
    end

    ##
    # Iterates over all IP addresses for +name+ retrieved from the hosts file.

    def each_address(name, &proc)
      lazy_initialize
      if @name2addr.include?(name)
        @name2addr[name].each(&proc)
      end
    end

    ##
    # Gets the hostname of +address+ from the hosts file.

    def getname(address)
      each_name(address) {|name| return name}
      raise ResolvError.new("#{@filename} has no address: #{address}")
    end

    ##
    # Gets all hostnames for +address+ from the hosts file.

    def getnames(address)
      ret = []
      each_name(address) {|name| ret << name}
      return ret
    end

    ##
    # Iterates over all hostnames for +address+ retrieved from the hosts file.

    def each_name(address, &proc)
      lazy_initialize
      if @addr2name.include?(address)
        @addr2name[address].each(&proc)
      end
    end
  end

  ##
  # Resolv::DNS is a DNS stub resolver.
  #
  # Information taken from the following places:
  #
  # * STD0013
  # * RFC 1035
  # * ftp://ftp.isi.edu/in-notes/iana/assignments/dns-parameters
  # * etc.

  class DNS

    ##
    # Default DNS Port

    Port = 53

    ##
    # Default DNS UDP packet size

    UDPSize = 512

    ##
    # Group of DNS resolver threads (obsolete)

    DNSThreadGroup = ThreadGroup.new

    ##
    # Creates a new DNS resolver.  See Resolv::DNS.new for argument details.
    #
    # Yields the created DNS resolver to the block, if given, otherwise
    # returns it.

    def self.open(*args)
      dns = new(*args)
      return dns unless block_given?
      begin
        yield dns
      ensure
        dns.close
      end
    end

    ##
    # Creates a new DNS resolver.
    #
    # +config_info+ can be:
    # 
    # nil:: Uses /etc/resolv.conf.
    # String:: Path to a file using /etc/resolv.conf's format.
    # Hash:: Must contain :nameserver, :search and :ndots keys.
    #
    # Example:
    #
    #   Resolv::DNS.new(:nameserver => ['210.251.121.21'],
    #                   :search => ['ruby-lang.org'],
    #                   :ndots => 1)

    def initialize(config_info=nil)
      @mutex = Mutex.new
      @config = Config.new(config_info)
      @initialized = nil
    end

    def lazy_initialize # :nodoc:
      @mutex.synchronize {
        unless @initialized
          @config.lazy_initialize
          @initialized = true
        end
      }
      self
    end

    ##
    # Closes the DNS resolver.

    def close
      @mutex.synchronize {
        if @initialized
          @initialized = false
        end
      }
    end

    ##
    # Gets the IP address of +name+ from the DNS resolver.
    #
    # +name+ can be a Resolv::DNS::Name or a String.  Retrieved address will
    # be a Resolv::IPv4 or Resolv::IPv6

    def getaddress(name)
      each_address(name) {|address| return address}
      raise ResolvError.new("DNS result has no information for #{name}")
    end

    ##
    # Gets all IP addresses for +name+ from the DNS resolver.
    #
    # +name+ can be a Resolv::DNS::Name or a String.  Retrieved addresses will
    # be a Resolv::IPv4 or Resolv::IPv6

    def getaddresses(name)
      ret = []
      each_address(name) {|address| ret << address}
      return ret
    end

    ##
    # Iterates over all IP addresses for +name+ retrieved from the DNS
    # resolver.
    #
    # +name+ can be a Resolv::DNS::Name or a String.  Retrieved addresses will
    # be a Resolv::IPv4 or Resolv::IPv6

    def each_address(name)
      each_resource(name, Resource::IN::A) {|resource| yield resource.address}
      each_resource(name, Resource::IN::AAAA) {|resource| yield resource.address}
    end

    ##
    # Gets the hostname for +address+ from the DNS resolver.
    #
    # +address+ must be a Resolv::IPv4, Resolv::IPv6 or a String.  Retrieved
    # name will be a Resolv::DNS::Name.

    def getname(address)
      each_name(address) {|name| return name}
      raise ResolvError.new("DNS result has no information for #{address}")
    end

    ##
    # Gets all hostnames for +address+ from the DNS resolver.
    #
    # +address+ must be a Resolv::IPv4, Resolv::IPv6 or a String.  Retrieved
    # names will be Resolv::DNS::Name instances.

    def getnames(address)
      ret = []
      each_name(address) {|name| ret << name}
      return ret
    end

    ##
    # Iterates over all hostnames for +address+ retrieved from the DNS
    # resolver.
    #
    # +address+ must be a Resolv::IPv4, Resolv::IPv6 or a String.  Retrieved
    # names will be Resolv::DNS::Name instances.

    def each_name(address)
      case address
      when Name
        ptr = address
      when IPv4::Regex
        ptr = IPv4.create(address).to_name
      when IPv6::Regex
        ptr = IPv6.create(address).to_name
      else
        raise ResolvError.new("cannot interpret as address: #{address}")
      end
      each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name}
    end

    ##
    # Look up the +typeclass+ DNS resource of +name+.
    #
    # +name+ must be a Resolv::DNS::Name or a String.
    #
    # +typeclass+ should be one of the following:
    #
    # * Resolv::DNS::Resource::IN::A
    # * Resolv::DNS::Resource::IN::AAAA
    # * Resolv::DNS::Resource::IN::ANY
    # * Resolv::DNS::Resource::IN::CNAME
    # * Resolv::DNS::Resource::IN::HINFO
    # * Resolv::DNS::Resource::IN::MINFO
    # * Resolv::DNS::Resource::IN::MX
    # * Resolv::DNS::Resource::IN::NS
    # * Resolv::DNS::Resource::IN::PTR
    # * Resolv::DNS::Resource::IN::SOA
    # * Resolv::DNS::Resource::IN::TXT
    # * Resolv::DNS::Resource::IN::WKS
    #
    # Returned resource is represented as a Resolv::DNS::Resource instance,
    # i.e. Resolv::DNS::Resource::IN::A.

    def getresource(name, typeclass)
      each_resource(name, typeclass) {|resource| return resource}
      raise ResolvError.new("DNS result has no information for #{name}")
    end

    ##
    # Looks up all +typeclass+ DNS resources for +name+.  See #getresource for
    # argument details.
  
    def getresources(name, typeclass)
      ret = []
      each_resource(name, typeclass) {|resource| ret << resource}
      return ret
    end

    ##
    # Iterates over all +typeclass+ DNS resources for +name+.  See
    # #getresource for argument details.
  
    def each_resource(name, typeclass, &proc)
      lazy_initialize
      requester = make_requester
      senders = {}
      begin
        @config.resolv(name) {|candidate, tout, nameserver|
          msg = Message.new
          msg.rd = 1
          msg.add_question(candidate, typeclass)
          unless sender = senders[[candidate, nameserver]]
            sender = senders[[candidate, nameserver]] =
              requester.sender(msg, candidate, nameserver)
          end
          reply, reply_name = requester.request(sender, tout)
          case reply.rcode
          when RCode::NoError
            extract_resources(reply, reply_name, typeclass, &proc)
            return
          when RCode::NXDomain
            raise Config::NXDomain.new(reply_name.to_s)
          else
            raise Config::OtherResolvError.new(reply_name.to_s)
          end
        }
      ensure
        requester.close
      end
    end

    def make_requester # :nodoc:
      nameserver_port = @config.nameserver_port
      if nameserver_port.length == 1
        Requester::ConnectedUDP.new(*nameserver_port[0])
      else
        Requester::UnconnectedUDP.new(*nameserver_port)
      end
    end

    def extract_resources(msg, name, typeclass) # :nodoc:
      if typeclass < Resource::ANY
        n0 = Name.create(name)
        msg.each_answer {|n, ttl, data|
          yield data if n0 == n
        }
      end
      yielded = false
      n0 = Name.create(name)
      msg.each_answer {|n, ttl, data|
        if n0 == n
          case data
          when typeclass
            yield data
            yielded = true
          when Resource::CNAME
            n0 = data.name
          end
        end
      }
      return if yielded
      msg.each_answer {|n, ttl, data|
        if n0 == n
          case data
          when typeclass
            yield data
          end
        end
      }
    end

    if defined? SecureRandom
      def self.random(arg) # :nodoc:
        begin
          SecureRandom.random_number(arg)
        rescue NotImplementedError
          rand(arg)
        end
      end
    else
      def self.random(arg) # :nodoc:
        rand(arg)
      end
    end


    def self.rangerand(range) # :nodoc:
      base = range.begin
      len = range.end - range.begin
      if !range.exclude_end?
        len += 1
      end
      base + random(len)
    end

    RequestID = {}
    RequestIDMutex = Mutex.new

    def self.allocate_request_id(host, port) # :nodoc:
      id = nil
      RequestIDMutex.synchronize {
        h = (RequestID[[host, port]] ||= {})
        begin
          id = rangerand(0x0000..0xffff)
        end while h[id] 
        h[id] = true
      }
      id
    end

    def self.free_request_id(host, port, id) # :nodoc:
      RequestIDMutex.synchronize {
        key = [host, port]
        if h = RequestID[key]
          h.delete id
          if h.empty?
            RequestID.delete key
          end
        end
      }
    end

    def self.bind_random_port(udpsock, bind_host="0.0.0.0") # :nodoc:
      begin
        port = rangerand(1024..65535)
        udpsock.bind(bind_host, port)
      rescue Errno::EADDRINUSE
        retry
      end
    end

    class Requester # :nodoc:
      def initialize
        @senders = {}
        @socks = nil
      end

      def request(sender, tout)
        timelimit = Time.now + tout
        sender.send
        while true
          now = Time.now
          timeout = timelimit - now
          if timeout <= 0
            raise ResolvTimeout
          end
          select_result = IO.select(@socks, nil, nil, timeout)
          if !select_result
            raise ResolvTimeout
          end
          reply, from = recv_reply(select_result[0])
          begin
            msg = Message.decode(reply)
          rescue DecodeError
            next # broken DNS message ignored
          end
          if s = @senders[[from,msg.id]]
            break
          else
            # unexpected DNS message ignored
          end
        end
        return msg, s.data
      end

      def close
        socks = @socks
        @socks = nil
        if socks
          socks.each {|sock| sock.close }
        end
      end

      class Sender # :nodoc:
        def initialize(msg, data, sock)
          @msg = msg
          @data = data
          @sock = sock
        end
      end

      class UnconnectedUDP < Requester # :nodoc:
        def initialize(*nameserver_port)
          super()
          @nameserver_port = nameserver_port
          @socks_hash = {}
          @socks = []
          nameserver_port.each {|host, port|
            if host.index(':')
              bind_host = "::"
              af = Socket::AF_INET6
            else
              bind_host = "0.0.0.0"
              af = Socket::AF_INET
            end
            next if @socks_hash[bind_host]
            sock = UDPSocket.new(af)
            sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
            DNS.bind_random_port(sock, bind_host)
            @socks << sock
            @socks_hash[bind_host] = sock
          }
        end

        def recv_reply(readable_socks)
          reply, from = readable_socks[0].recvfrom(UDPSize)
          return reply, [from[3],from[1]]
        end

        def sender(msg, data, host, port=Port)
          service = [host, port]
          id = DNS.allocate_request_id(host, port)
          request = msg.encode
          request[0,2] = [id].pack('n')
          sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"]
          return @senders[[service, id]] =
            Sender.new(request, data, sock, host, port)
        end

        def close
          super
          @senders.each_key {|service, id|
            DNS.free_request_id(service[0], service[1], id)
          }
        end

        class Sender < Requester::Sender # :nodoc:
          def initialize(msg, data, sock, host, port)
            super(msg, data, sock)
            @host = host
            @port = port
          end
          attr_reader :data

          def send
            @sock.send(@msg, 0, @host, @port)
          end
        end
      end

      class ConnectedUDP < Requester # :nodoc:
        def initialize(host, port=Port)
          super()
          @host = host
          @port = port
          is_ipv6 = host.index(':')
          sock = UDPSocket.new(is_ipv6 ? Socket::AF_INET6 : Socket::AF_INET)
          @socks = [sock]
          sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
          DNS.bind_random_port(sock, is_ipv6 ? "::" : "0.0.0.0")
          sock.connect(host, port)
        end

        def recv_reply(readable_socks)
          reply = readable_socks[0].recv(UDPSize)
          return reply, nil
        end

        def sender(msg, data, host=@host, port=@port)
          unless host == @host && port == @port
            raise RequestError.new("host/port don't match: #{host}:#{port}")
          end
          id = DNS.allocate_request_id(@host, @port)
          request = msg.encode
          request[0,2] = [id].pack('n')
          return @senders[[nil,id]] = Sender.new(request, data, @socks[0])
        end

        def close
          super
          @senders.each_key {|from, id|
            DNS.free_request_id(@host, @port, id)
          }
        end

        class Sender < Requester::Sender # :nodoc:
          def send
            @sock.send(@msg, 0)
          end
          attr_reader :data
        end
      end

      class TCP < Requester # :nodoc:
        def initialize(host, port=Port)
          super()
          @host = host
          @port = port
          sock = TCPSocket.new(@host, @port)
          @socks = [sock]
          sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
          @senders = {}
        end

        def recv_reply(readable_socks)
          len = readable_socks[0].read(2).unpack('n')[0]
          reply = @socks[0].read(len)
          return reply, nil
        end

        def sender(msg, data, host=@host, port=@port)
          unless host == @host && port == @port
            raise RequestError.new("host/port don't match: #{host}:#{port}")
          end
          id = DNS.allocate_request_id(@host, @port)
          request = msg.encode
          request[0,2] = [request.length, id].pack('nn')
          return @senders[[nil,id]] = Sender.new(request, data, @socks[0])
        end

        class Sender < Requester::Sender # :nodoc:
          def send
            @sock.print(@msg)
            @sock.flush
          end
          attr_reader :data
        end

        def close
          super
          @senders.each_key {|from,id|
            DNS.free_request_id(@host, @port, id)
          }
        end
      end

      ##
      # Indicates a problem with the DNS request.

      class RequestError < StandardError
      end
    end

    class Config # :nodoc:
      def initialize(config_info=nil)
        @mutex = Mutex.new
        @config_info = config_info
        @initialized = nil
      end

      def Config.parse_resolv_conf(filename)
        nameserver = []
        search = nil
        ndots = 1
        open(filename) {|f|
          f.each {|line|
            line.sub!(/[#;].*/, '')
            keyword, *args = line.split(/\s+/)
            args.each { |arg|
              arg.untaint
            }
            next unless keyword
            case keyword
            when 'nameserver'
              nameserver += args
            when 'domain'
              next if args.empty?
              search = [args[0]]
            when 'search'
              next if args.empty?
              search = args
            when 'options'
              args.each {|arg|
                case arg
                when /\Andots:(\d+)\z/
                  ndots = $1.to_i
                end
              }
            end
          }
        }
        return { :nameserver => nameserver, :search => search, :ndots => ndots }
      end

      def Config.default_config_hash(filename="/etc/resolv.conf")
        if File.exist? filename
          config_hash = Config.parse_resolv_conf(filename)
        else
          if /mswin32|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM
            require 'win32/resolv'
            search, nameserver = Win32::Resolv.get_resolv_info
            config_hash = {}
            config_hash[:nameserver] = nameserver if nameserver
            config_hash[:search] = [search].flatten if search
          end
        end
        config_hash
      end

      def lazy_initialize
        @mutex.synchronize {
          unless @initialized
            @nameserver = []
            @search = nil
            @ndots = 1
            case @config_info
            when nil
              config_hash = Config.default_config_hash
            when String
              config_hash = Config.parse_resolv_conf(@config_info)
            when Hash
              config_hash = @config_info.dup
              if String === config_hash[:nameserver]
                config_hash[:nameserver] = [config_hash[:nameserver]]
              end
              if String === config_hash[:search]
                config_hash[:search] = [config_hash[:search]]
              end
            else
              raise ArgumentError.new("invalid resolv configuration: #{@config_info.inspect}")
            end
            @nameserver = config_hash[:nameserver] if config_hash.include? :nameserver
            @search = config_hash[:search] if config_hash.include? :search
            @ndots = config_hash[:ndots] if config_hash.include? :ndots

            @nameserver = ['0.0.0.0'] if @nameserver.empty?
            if @search
              @search = @search.map {|arg| Label.split(arg) }
            else
              hostname = Socket.gethostname
              if /\./ =~ hostname
                @search = [Label.split($')]
              else
                @search = [[]]
              end
            end

            if !@nameserver.kind_of?(Array) ||
               !@nameserver.all? {|ns| String === ns }
              raise ArgumentError.new("invalid nameserver config: #{@nameserver.inspect}")
            end

            if !@search.kind_of?(Array) ||
               !@search.all? {|ls| ls.all? {|l| Label::Str === l } }
              raise ArgumentError.new("invalid search config: #{@search.inspect}")
            end

            if !@ndots.kind_of?(Integer)
              raise ArgumentError.new("invalid ndots config: #{@ndots.inspect}")
            end

            @initialized = true
          end
        }
        self
      end

      def single?
        lazy_initialize
        if @nameserver.length == 1
          return @nameserver[0]
        else
          return nil
        end
      end

      def nameserver_port
        lazy_initialize
        @nameserver_port ||= @nameserver.map {|i| [i, Port] }
        @nameserver_port
      end

      def generate_candidates(name)
        candidates = nil
        name = Name.create(name)
        if name.absolute?
          candidates = [name]
        else
          if @ndots <= name.length - 1
            candidates = [Name.new(name.to_a)]
          else
            candidates = []
          end
          candidates.concat(@search.map {|domain| Name.new(name.to_a + domain)})
        end
        return candidates
      end

      InitialTimeout = 5

      def generate_timeouts
        ts = [InitialTimeout]
        ts << ts[-1] * 2 / @nameserver.length
        ts << ts[-1] * 2
        ts << ts[-1] * 2
        return ts
      end

      def resolv(name)
        candidates = generate_candidates(name)
        timeouts = generate_timeouts
        begin
          candidates.each {|candidate|
            begin
              timeouts.each {|tout|
                @nameserver.each {|nameserver|
                  begin
                    yield candidate, tout, nameserver
                  rescue ResolvTimeout
                  end
                }
              }
              raise ResolvError.new("DNS resolv timeout: #{name}")
            rescue NXDomain
            end
          }
        rescue ResolvError
        end
      end

      ##
      # Indicates no such domain was found.

      class NXDomain < ResolvError
      end

      ##
      # Indicates some other unhandled resolver error was encountered.

      class OtherResolvError < ResolvError
      end
    end

    module OpCode # :nodoc:
      Query = 0
      IQuery = 1
      Status = 2
      Notify = 4
      Update = 5
    end

    module RCode # :nodoc:
      NoError = 0
      FormErr = 1
      ServFail = 2
      NXDomain = 3
      NotImp = 4
      Refused = 5
      YXDomain = 6
      YXRRSet = 7
      NXRRSet = 8
      NotAuth = 9
      NotZone = 10
      BADVERS = 16
      BADSIG = 16
      BADKEY = 17
      BADTIME = 18
      BADMODE = 19
      BADNAME = 20
      BADALG = 21
    end

    ##
    # Indicates that the DNS response was unable to be decoded.

    class DecodeError < StandardError
    end

    ##
    # Indicates that the DNS request was unable to be encoded.

    class EncodeError < StandardError
    end

    module Label # :nodoc:
      def self.split(arg)
        labels = []
        arg.scan(/[^\.]+/) {labels << Str.new($&)}
        return labels
      end

      class Str # :nodoc:
        def initialize(string)
          @string = string
          @downcase = string.downcase
        end
        attr_reader :string, :downcase

        def to_s
          return @string
        end

        def inspect
          return "#<#{self.class} #{self.to_s}>"
        end

        def ==(other)
          return @downcase == other.downcase
        end

        def eql?(other)
          return self == other
        end

        def hash
          return @downcase.hash
        end
      end
    end

    ##
    # A representation of a DNS name.

    class Name
      
      ##
      # Creates a new DNS name from +arg+.  +arg+ can be:
      #
      # Name:: returns +arg+.
      # String:: Creates a new Name.

      def self.create(arg)
        case arg
        when Name
          return arg
        when String
          return Name.new(Label.split(arg), /\.\z/ =~ arg ? true : false)
        else
          raise ArgumentError.new("cannot interpret as DNS name: #{arg.inspect}")
        end
      end

      def initialize(labels, absolute=true) # :nodoc:
        @labels = labels
        @absolute = absolute
      end

      def inspect # :nodoc:
        "#<#{self.class}: #{self.to_s}#{@absolute ? '.' : ''}>"
      end

      ##
      # True if this name is absolute.

      def absolute?
        return @absolute
      end

      def ==(other) # :nodoc:
        return false unless Name === other
        return @labels.join == other.to_a.join && @absolute == other.absolute?
      end

      alias eql? == # :nodoc:

      ##
      # Returns true if +other+ is a subdomain.
      #
      # Example:
      #
      #   domain = Resolv::DNS::Name.create("y.z")
      #   p Resolv::DNS::Name.create("w.x.y.z").subdomain_of?(domain) #=> true
      #   p Resolv::DNS::Name.create("x.y.z").subdomain_of?(domain) #=> true
      #   p Resolv::DNS::Name.create("y.z").subdomain_of?(domain) #=> false
      #   p Resolv::DNS::Name.create("z").subdomain_of?(domain) #=> false
      #   p Resolv::DNS::Name.create("x.y.z.").subdomain_of?(domain) #=> false
      #   p Resolv::DNS::Name.create("w.z").subdomain_of?(domain) #=> false
      #

      def subdomain_of?(other)
        raise ArgumentError, "not a domain name: #{other.inspect}" unless Name === other
        return false if @absolute != other.absolute?
        other_len = other.length
        return false if @labels.length <= other_len
        return @labels[-other_len, other_len] == other.to_a
      end

      def hash # :nodoc:
        return @labels.hash ^ @absolute.hash
      end

      def to_a # :nodoc:
        return @labels
      end

      def length # :nodoc:
        return @labels.length
      end

      def [](i) # :nodoc:
        return @labels[i]
      end

      ##
      # returns the domain name as a string.
      #
      # The domain name doesn't have a trailing dot even if the name object is
      # absolute.
      #
      # Example:
      #
      #   p Resolv::DNS::Name.create("x.y.z.").to_s #=> "x.y.z"
      #   p Resolv::DNS::Name.create("x.y.z").to_s #=> "x.y.z"

      def to_s
        return @labels.join('.')
      end
    end

    class Message # :nodoc:
      @@identifier = -1

      def initialize(id = (@@identifier += 1) & 0xffff)
        @id = id
        @qr = 0
        @opcode = 0
        @aa = 0
        @tc = 0
        @rd = 0 # recursion desired
        @ra = 0 # recursion available
        @rcode = 0
        @question = []
        @answer = []
        @authority = []
        @additional = []
      end

      attr_accessor :id, :qr, :opcode, :aa, :tc, :rd, :ra, :rcode
      attr_reader :question, :answer, :authority, :additional

      def ==(other)
        return @id == other.id &&
               @qr == other.qr &&
               @opcode == other.opcode &&
               @aa == other.aa &&
               @tc == other.tc &&
               @rd == other.rd &&
               @ra == other.ra &&
               @rcode == other.rcode &&
               @question == other.question &&
               @answer == other.answer &&
               @authority == other.authority &&
               @additional == other.additional
      end

      def add_question(name, typeclass)
        @question << [Name.create(name), typeclass]
      end

      def each_question
        @question.each {|name, typeclass|
          yield name, typeclass
        }
      end

      def add_answer(name, ttl, data)
        @answer << [Name.create(name), ttl, data]
      end

      def each_answer
        @answer.each {|name, ttl, data|
          yield name, ttl, data
        }
      end

      def add_authority(name, ttl, data)
        @authority << [Name.create(name), ttl, data]
      end

      def each_authority
        @authority.each {|name, ttl, data|
          yield name, ttl, data
        }
      end

      def add_additional(name, ttl, data)
        @additional << [Name.create(name), ttl, data]
      end

      def each_additional
        @additional.each {|name, ttl, data|
          yield name, ttl, data
        }
      end

      def each_resource
        each_answer {|name, ttl, data| yield name, ttl, data}
        each_authority {|name, ttl, data| yield name, ttl, data}
        each_additional {|name, ttl, data| yield name, ttl, data}
      end

      def encode
        return MessageEncoder.new {|msg|
          msg.put_pack('nnnnnn',
            @id,
            (@qr & 1) << 15 |
            (@opcode & 15) << 11 |
            (@aa & 1) << 10 |
            (@tc & 1) << 9 |
            (@rd & 1) << 8 |
            (@ra & 1) << 7 |
            (@rcode & 15),
            @question.length,
            @answer.length,
            @authority.length,
            @additional.length)
          @question.each {|q|
            name, typeclass = q
            msg.put_name(name)
            msg.put_pack('nn', typeclass::TypeValue, typeclass::ClassValue)
          }
          [@answer, @authority, @additional].each {|rr|
            rr.each {|r|
              name, ttl, data = r
              msg.put_name(name)
              msg.put_pack('nnN', data.class::TypeValue, data.class::ClassValue, ttl)
              msg.put_length16 {data.encode_rdata(msg)}
            }
          }
        }.to_s
      end

      class MessageEncoder # :nodoc:
        def initialize
          @data = ''
          @names = {}
          yield self
        end

        def to_s
          return @data
        end

        def put_bytes(d)
          @data << d
        end

        def put_pack(template, *d)
          @data << d.pack(template)
        end

        def put_length16
          length_index = @data.length
          @data << "\0\0"
          data_start = @data.length
          yield
          data_end = @data.length
          @data[length_index, 2] = [data_end - data_start].pack("n")
        end

        def put_string(d)
          self.put_pack("C", d.length)
          @data << d
        end

        def put_string_list(ds)
          ds.each {|d|
            self.put_string(d)
          }
        end

        def put_name(d)
          put_labels(d.to_a)
        end

        def put_labels(d)
          d.each_index {|i|
            domain = d[i..-1]
            if idx = @names[domain]
              self.put_pack("n", 0xc000 | idx)
              return
            else
              @names[domain] = @data.length
              self.put_label(d[i])
            end
          }
          @data << "\0"
        end

        def put_label(d)
          self.put_string(d.to_s)
        end
      end

      def Message.decode(m)
        o = Message.new(0)
        MessageDecoder.new(m) {|msg|
          id, flag, qdcount, ancount, nscount, arcount =
            msg.get_unpack('nnnnnn')
          o.id = id
          o.qr = (flag >> 15) & 1
          o.opcode = (flag >> 11) & 15
          o.aa = (flag >> 10) & 1
          o.tc = (flag >> 9) & 1
          o.rd = (flag >> 8) & 1
          o.ra = (flag >> 7) & 1
          o.rcode = flag & 15
          (1..qdcount).each {
            name, typeclass = msg.get_question
            o.add_question(name, typeclass)
          }
          (1..ancount).each {
            name, ttl, data = msg.get_rr
            o.add_answer(name, ttl, data)
          }
          (1..nscount).each {
            name, ttl, data = msg.get_rr
            o.add_authority(name, ttl, data)
          }
          (1..arcount).each {
            name, ttl, data = msg.get_rr
            o.add_additional(name, ttl, data)
          }
        }
        return o
      end

      class MessageDecoder # :nodoc:
        def initialize(data)
          @data = data
          @index = 0
          @limit = data.length
          yield self
        end

        def get_length16
          len, = self.get_unpack('n')
          save_limit = @limit
          @limit = @index + len
          d = yield(len)
          if @index < @limit
            raise DecodeError.new("junk exists")
          elsif @limit < @index
            raise DecodeError.new("limit exceeded")
          end
          @limit = save_limit
          return d
        end

        def get_bytes(len = @limit - @index)
          d = @data[@index, len]
          @index += len
          return d
        end

        def get_unpack(template)
          len = 0
          template.each_byte {|byte|
            case byte
            when ?c, ?C
              len += 1
            when ?n
              len += 2
            when ?N
              len += 4
            else
              raise StandardError.new("unsupported template: '#{byte.chr}' in '#{template}'")
            end
          }
          raise DecodeError.new("limit exceeded") if @limit < @index + len
          arr = @data.unpack("@#{@index}#{template}")
          @index += len
          return arr
        end

        def get_string
          len = @data[@index]
          raise DecodeError.new("limit exceeded") if @limit < @index + 1 + len
          d = @data[@index + 1, len]
          @index += 1 + len
          return d
        end

        def get_string_list
          strings = []
          while @index < @limit
            strings << self.get_string
          end
          strings
        end

        def get_name
          return Name.new(self.get_labels)
        end

        def get_labels(limit=nil)
          limit = @index if !limit || @index < limit
          d = []
          while true
            case @data[@index]
            when 0
              @index += 1
              return d
            when 192..255
              idx = self.get_unpack('n')[0] & 0x3fff
              if limit <= idx
                raise DecodeError.new("non-backward name pointer")
              end
              save_index = @index
              @index = idx
              d += self.get_labels(limit)
              @index = save_index
              return d
            else
              d << self.get_label
            end
          end
          return d
        end

        def get_label
          return Label::Str.new(self.get_string)
        end

        def get_question
          name = self.get_name
          type, klass = self.get_unpack("nn")
          return name, Resource.get_class(type, klass)
        end

        def get_rr
          name = self.get_name
          type, klass, ttl = self.get_unpack('nnN')
          typeclass = Resource.get_class(type, klass)
          return name, ttl, self.get_length16 {typeclass.decode_rdata(self)}
        end
      end
    end

    ##
    # A DNS query abstract class.

    class Query
      def encode_rdata(msg) # :nodoc:
        raise EncodeError.new("#{self.class} is query.") 
      end

      def self.decode_rdata(msg) # :nodoc:
        raise DecodeError.new("#{self.class} is query.") 
      end
    end

    ##
    # A DNS resource abstract class.

    class Resource < Query

      ##
      # Remaining Time To Live for this Resource.

      attr_reader :ttl

      ClassHash = {} # :nodoc:

      def encode_rdata(msg) # :nodoc:
        raise NotImplementedError.new
      end

      def self.decode_rdata(msg) # :nodoc:
        raise NotImplementedError.new
      end

      def ==(other) # :nodoc:
        return self.class == other.class &&
          self.instance_variables == other.instance_variables &&
          self.instance_variables.collect {|name| self.instance_eval name} ==
            other.instance_variables.collect {|name| other.instance_eval name}
      end

      def eql?(other) # :nodoc:
        return self == other
      end

      def hash # :nodoc:
        h = 0
        self.instance_variables.each {|name|
          h ^= self.instance_eval("#{name}.hash")
        }
        return h
      end

      def self.get_class(type_value, class_value) # :nodoc:
        return ClassHash[[type_value, class_value]] ||
               Generic.create(type_value, class_value)
      end

      ##
      # A generic resource abstract class.

      class Generic < Resource

        ##
        # Creates a new generic resource.

        def initialize(data)
          @data = data
        end

        ##
        # Data for this generic resource.

        attr_reader :data

        def encode_rdata(msg) # :nodoc:
          msg.put_bytes(data)
        end

        def self.decode_rdata(msg) # :nodoc:
          return self.new(msg.get_bytes)
        end

        def self.create(type_value, class_value) # :nodoc:
          c = Class.new(Generic)
          c.const_set(:TypeValue, type_value)
          c.const_set(:ClassValue, class_value)
          Generic.const_set("Type#{type_value}_Class#{class_value}", c)
          ClassHash[[type_value, class_value]] = c
          return c
        end
      end

      ##
      # Domain Name resource abstract class.

      class DomainName < Resource

        ##
        # Creates a new DomainName from +name+.

        def initialize(name)
          @name = name
        end

        ##
        # The name of this DomainName.

        attr_reader :name

        def encode_rdata(msg) # :nodoc:
          msg.put_name(@name)
        end

        def self.decode_rdata(msg) # :nodoc:
          return self.new(msg.get_name)
        end
      end

      # Standard (class generic) RRs

      ClassValue = nil # :nodoc:

      ##
      # An authoritative name server.

      class NS < DomainName
        TypeValue = 2 # :nodoc:
      end

      ##
      # The canonical name for an alias.

      class CNAME < DomainName
        TypeValue = 5 # :nodoc:
      end

      ##
      # Start Of Authority resource.

      class SOA < Resource

        TypeValue = 6 # :nodoc:

        ##
        # Creates a new SOA record.  See the attr documentation for the
        # details of each argument.

        def initialize(mname, rname, serial, refresh, retry_, expire, minimum)
          @mname = mname
          @rname = rname
          @serial = serial
          @refresh = refresh
          @retry = retry_
          @expire = expire
          @minimum = minimum
        end

        ##
        # Name of the host where the master zone file for this zone resides.

        attr_reader :mname

        ##
        # The person responsible for this domain name.

        attr_reader :rname

        ##
        # The version number of the zone file.

        attr_reader :serial

        ##
        # How often, in seconds, a secondary name server is to check for
        # updates from the primary name server.

        attr_reader :refresh

        ##
        # How often, in seconds, a secondary name server is to retry after a
        # failure to check for a refresh.

        attr_reader :retry

        ##
        # Time in seconds that a secondary name server is to use the data
        # before refreshing from the primary name server.

        attr_reader :expire

        ##
        # The minimum number of seconds to be used for TTL values in RRs.

        attr_reader :minimum

        def encode_rdata(msg) # :nodoc:
          msg.put_name(@mname)
          msg.put_name(@rname)
          msg.put_pack('NNNNN', @serial, @refresh, @retry, @expire, @minimum)
        end

        def self.decode_rdata(msg) # :nodoc:
          mname = msg.get_name
          rname = msg.get_name
          serial, refresh, retry_, expire, minimum = msg.get_unpack('NNNNN')
          return self.new(
            mname, rname, serial, refresh, retry_, expire, minimum)
        end
      end

      ##
      # A Pointer to another DNS name.

      class PTR < DomainName
        TypeValue = 12 # :nodoc:
      end

      ##
      # Host Information resource.

      class HINFO < Resource

        TypeValue = 13 # :nodoc:

        ##
        # Creates a new HINFO running +os+ on +cpu+.

        def initialize(cpu, os)
          @cpu = cpu
          @os = os
        end

        ##
        # CPU architecture for this resource.

        attr_reader :cpu

        ##
        # Operating system for this resource.

        attr_reader :os

        def encode_rdata(msg) # :nodoc:
          msg.put_string(@cpu)
          msg.put_string(@os)
        end

        def self.decode_rdata(msg) # :nodoc:
          cpu = msg.get_string
          os = msg.get_string
          return self.new(cpu, os)
        end
      end

      ##
      # Mailing list or mailbox information.

      class MINFO < Resource

        TypeValue = 14 # :nodoc:

        def initialize(rmailbx, emailbx)
          @rmailbx = rmailbx
          @emailbx = emailbx
        end

        ##
        # Domain name responsible for this mail list or mailbox.

        attr_reader :rmailbx

        ##
        # Mailbox to use for error messages related to the mail list or mailbox.

        attr_reader :emailbx

        def encode_rdata(msg) # :nodoc:
          msg.put_name(@rmailbx)
          msg.put_name(@emailbx)
        end

        def self.decode_rdata(msg) # :nodoc:
          rmailbx = msg.get_string
          emailbx = msg.get_string
          return self.new(rmailbx, emailbx)
        end
      end

      ##
      # Mail Exchanger resource.

      class MX < Resource

        TypeValue= 15 # :nodoc:

        ##
        # Creates a new MX record with +preference+, accepting mail at
        # +exchange+.

        def initialize(preference, exchange)
          @preference = preference
          @exchange = exchange
        end

        ##
        # The preference for this MX.

        attr_reader :preference

        ##
        # The host of this MX.

        attr_reader :exchange

        def encode_rdata(msg) # :nodoc:
          msg.put_pack('n', @preference)
          msg.put_name(@exchange)
        end

        def self.decode_rdata(msg) # :nodoc:
          preference, = msg.get_unpack('n')
          exchange = msg.get_name
          return self.new(preference, exchange)
        end
      end

      ##
      # Unstructured text resource.

      class TXT < Resource

        TypeValue = 16 # :nodoc:

        def initialize(first_string, *rest_strings)
          @strings = [first_string, *rest_strings]
        end

        ##
        # Returns an Array of Strings for this TXT record.

        attr_reader :strings

        ##
        # Returns the first string from +strings+.

        def data
          @strings[0]
        end

        def encode_rdata(msg) # :nodoc:
          msg.put_string_list(@strings)
        end

        def self.decode_rdata(msg) # :nodoc:
          strings = msg.get_string_list
          return self.new(*strings)
        end
      end

      ##
      # A Query type requesting any RR.

      class ANY < Query
        TypeValue = 255 # :nodoc:
      end

      ClassInsensitiveTypes = [ # :nodoc:
        NS, CNAME, SOA, PTR, HINFO, MINFO, MX, TXT, ANY
      ]

      ##
      # module IN contains ARPA Internet specific RRs.

      module IN

        ClassValue = 1 # :nodoc:

        ClassInsensitiveTypes.each {|s|
          c = Class.new(s)
          c.const_set(:TypeValue, s::TypeValue)
          c.const_set(:ClassValue, ClassValue)
          ClassHash[[s::TypeValue, ClassValue]] = c
          self.const_set(s.name.sub(/.*::/, ''), c)
        }

        ##
        # IPv4 Address resource

        class A < Resource
          TypeValue = 1
          ClassValue = IN::ClassValue
          ClassHash[[TypeValue, ClassValue]] = self # :nodoc:

          ##
          # Creates a new A for +address+.

          def initialize(address)
            @address = IPv4.create(address)
          end

          ##
          # The Resolv::IPv4 address for this A.

          attr_reader :address

          def encode_rdata(msg) # :nodoc:
            msg.put_bytes(@address.address)
          end

          def self.decode_rdata(msg) # :nodoc:
            return self.new(IPv4.new(msg.get_bytes(4)))
          end
        end

        ##
        # Well Known Service resource.

        class WKS < Resource
          TypeValue = 11
          ClassValue = IN::ClassValue
          ClassHash[[TypeValue, ClassValue]] = self # :nodoc:

          def initialize(address, protocol, bitmap)
            @address = IPv4.create(address)
            @protocol = protocol
            @bitmap = bitmap
          end

          ##
          # The host these services run on.

          attr_reader :address

          ##
          # IP protocol number for these services.

          attr_reader :protocol

          ##
          # A bit map of enabled services on this host.
          #
          # If protocol is 6 (TCP) then the 26th bit corresponds to the SMTP
          # service (port 25).  If this bit is set, then an SMTP server should
          # be listening on TCP port 25; if zero, SMTP service is not
          # supported.

          attr_reader :bitmap

          def encode_rdata(msg) # :nodoc:
            msg.put_bytes(@address.address)
            msg.put_pack("n", @protocol)
            msg.put_bytes(@bitmap)
          end

          def self.decode_rdata(msg) # :nodoc:
            address = IPv4.new(msg.get_bytes(4))
            protocol, = msg.get_unpack("n")
            bitmap = msg.get_bytes
            return self.new(address, protocol, bitmap)
          end
        end

        ##
        # An IPv6 address record.

        class AAAA < Resource
          TypeValue = 28
          ClassValue = IN::ClassValue
          ClassHash[[TypeValue, ClassValue]] = self # :nodoc:

          ##
          # Creates a new AAAA for +address+.

          def initialize(address)
            @address = IPv6.create(address)
          end
          
          ##
          # The Resolv::IPv6 address for this AAAA.

          attr_reader :address

          def encode_rdata(msg) # :nodoc:
            msg.put_bytes(@address.address)
          end

          def self.decode_rdata(msg) # :nodoc:
            return self.new(IPv6.new(msg.get_bytes(16)))
          end
        end

        ##
        # SRV resource record defined in RFC 2782
        # 
        # These records identify the hostname and port that a service is
        # available at.

        class SRV < Resource
          TypeValue = 33
          ClassValue = IN::ClassValue
          ClassHash[[TypeValue, ClassValue]] = self # :nodoc:

          # Create a SRV resource record.
          #
          # See the documentation for #priority, #weight, #port and #target
          # for +priority+, +weight+, +port and +target+ respectively.

          def initialize(priority, weight, port, target)
            @priority = priority.to_int
            @weight = weight.to_int
            @port = port.to_int
            @target = Name.create(target)
          end

          # The priority of this target host.
          #
          # A client MUST attempt to contact the target host with the
          # lowest-numbered priority it can reach; target hosts with the same
          # priority SHOULD be tried in an order defined by the weight field.
          # The range is 0-65535.  Note that it is not widely implemented and
          # should be set to zero.

          attr_reader :priority

          # A server selection mechanism.
          #
          # The weight field specifies a relative weight for entries with the
          # same priority. Larger weights SHOULD be given a proportionately
          # higher probability of being selected. The range of this number is
          # 0-65535.  Domain administrators SHOULD use Weight 0 when there
          # isn't any server selection to do, to make the RR easier to read
          # for humans (less noisy). Note that it is not widely implemented
          # and should be set to zero.

          attr_reader :weight

          # The port on this target host of this service.
          #
          # The range is 0-65535.

          attr_reader :port

          # The domain name of the target host.
          #
          # A target of "." means that the service is decidedly not available
          # at this domain.

          attr_reader :target

          def encode_rdata(msg) # :nodoc:
            msg.put_pack("n", @priority)
            msg.put_pack("n", @weight)
            msg.put_pack("n", @port)
            msg.put_name(@target)
          end

          def self.decode_rdata(msg) # :nodoc:
            priority, = msg.get_unpack("n")
            weight,   = msg.get_unpack("n")
            port,     = msg.get_unpack("n")
            target    = msg.get_name
            return self.new(priority, weight, port, target)
          end
        end
      end
    end
  end

  ##
  # A Resolv::DNS IPv4 address.

  class IPv4

    ##
    # Regular expression IPv4 addresses must match.

    Regex256 = /0
               |1(?:[0-9][0-9]?)?
               |2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
               |[3-9][0-9]?/x
    Regex = /\A(#{Regex256})\.(#{Regex256})\.(#{Regex256})\.(#{Regex256})\z/

    def self.create(arg)
      case arg
      when IPv4
        return arg
      when Regex
        if (0..255) === (a = $1.to_i) &&
           (0..255) === (b = $2.to_i) &&
           (0..255) === (c = $3.to_i) &&
           (0..255) === (d = $4.to_i)
          return self.new([a, b, c, d].pack("CCCC"))
        else
          raise ArgumentError.new("IPv4 address with invalid value: " + arg)
        end
      else
        raise ArgumentError.new("cannot interpret as IPv4 address: #{arg.inspect}")
      end
    end

    def initialize(address) # :nodoc:
      unless address.kind_of?(String) && address.length == 4
        raise ArgumentError.new('IPv4 address must be 4 bytes')
      end
      @address = address
    end

    ##
    # A String representation of this IPv4 address.

    ##
    # The raw IPv4 address as a String.

    attr_reader :address

    def to_s # :nodoc:
      return sprintf("%d.%d.%d.%d", *@address.unpack("CCCC"))
    end

    def inspect # :nodoc:
      return "#<#{self.class} #{self.to_s}>"
    end

    ##
    # Turns this IPv4 address into a Resolv::DNS::Name.

    def to_name
      return DNS::Name.create(
        '%d.%d.%d.%d.in-addr.arpa.' % @address.unpack('CCCC').reverse)
    end

    def ==(other) # :nodoc:
      return @address == other.address
    end

    def eql?(other) # :nodoc:
      return self == other
    end

    def hash # :nodoc:
      return @address.hash
    end
  end

  ##
  # A Resolv::DNS IPv6 address.

  class IPv6

    ##
    # IPv6 address format a:b:c:d:e:f:g:h
    Regex_8Hex = /\A
      (?:[0-9A-Fa-f]{1,4}:){7}
         [0-9A-Fa-f]{1,4}
      \z/x

    ##
    # Compressed IPv6 address format a::b

    Regex_CompressedHex = /\A
      ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
      ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)
      \z/x

    ##
    # IPv4 mapped IPv6 address format a:b:c:d:e:f:w.x.y.z

    Regex_6Hex4Dec = /\A
      ((?:[0-9A-Fa-f]{1,4}:){6,6})
      (\d+)\.(\d+)\.(\d+)\.(\d+)
      \z/x

    ##
    # Compressed IPv4 mapped IPv6 address format a::b:w.x.y.z

    Regex_CompressedHex4Dec = /\A
      ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
      ((?:[0-9A-Fa-f]{1,4}:)*)
      (\d+)\.(\d+)\.(\d+)\.(\d+)
      \z/x

    ##
    # A composite IPv6 address Regexp.

    Regex = /
      (?:#{Regex_8Hex}) |
      (?:#{Regex_CompressedHex}) |
      (?:#{Regex_6Hex4Dec}) |
      (?:#{Regex_CompressedHex4Dec})/x

    ##
    # Creates a new IPv6 address from +arg+ which may be:
    #
    # IPv6:: returns +arg+.
    # String:: +arg+ must match one of the IPv6::Regex* constants

    def self.create(arg)
      case arg
      when IPv6
        return arg
      when String
        address = ''
        if Regex_8Hex =~ arg
          arg.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
        elsif Regex_CompressedHex =~ arg
          prefix = $1
          suffix = $2
          a1 = ''
          a2 = ''
          prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
          suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
          omitlen = 16 - a1.length - a2.length
          address << a1 << "\0" * omitlen << a2
        elsif Regex_6Hex4Dec =~ arg
          prefix, a, b, c, d = $1, $2.to_i, $3.to_i, $4.to_i, $5.to_i
          if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
            prefix.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
            address << [a, b, c, d].pack('CCCC')
          else
            raise ArgumentError.new("not numeric IPv6 address: " + arg)
          end
        elsif Regex_CompressedHex4Dec =~ arg
          prefix, suffix, a, b, c, d = $1, $2, $3.to_i, $4.to_i, $5.to_i, $6.to_i
          if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
            a1 = ''
            a2 = ''
            prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
            suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
            omitlen = 12 - a1.length - a2.length
            address << a1 << "\0" * omitlen << a2 << [a, b, c, d].pack('CCCC')
          else
            raise ArgumentError.new("not numeric IPv6 address: " + arg)
          end
        else
          raise ArgumentError.new("not numeric IPv6 address: " + arg)
        end
        return IPv6.new(address)
      else
        raise ArgumentError.new("cannot interpret as IPv6 address: #{arg.inspect}")
      end
    end

    def initialize(address) # :nodoc:
      unless address.kind_of?(String) && address.length == 16
        raise ArgumentError.new('IPv6 address must be 16 bytes')
      end
      @address = address
    end

    ##
    # The raw IPv6 address as a String.

    attr_reader :address

    def to_s # :nodoc:
      address = sprintf("%X:%X:%X:%X:%X:%X:%X:%X", *@address.unpack("nnnnnnnn"))
      unless address.sub!(/(^|:)0(:0)+(:|$)/, '::')
        address.sub!(/(^|:)0(:|$)/, '::')
      end
      return address
    end

    def inspect # :nodoc:
      return "#<#{self.class} #{self.to_s}>"
    end

    ##
    # Turns this IPv6 address into a Resolv::DNS::Name.
    #--
    # ip6.arpa should be searched too. [RFC3152]

    def to_name
      return DNS::Name.new(
        @address.unpack("H32")[0].split(//).reverse + ['ip6', 'arpa'])
    end

    def ==(other) # :nodoc:
      return @address == other.address
    end

    def eql?(other) # :nodoc:
      return self == other
    end

    def hash # :nodoc:
      return @address.hash
    end
  end

  ##
  # Default resolver to use for Resolv class methods.

  DefaultResolver = self.new

  ##
  # Address Regexp to use for matching IP addresses.

  AddressRegex = /(?:#{IPv4::Regex})|(?:#{IPv6::Regex})/

end

PK     Y\E      securerandom.rbnu [        # = Secure random number generator interface.
#
# This library is an interface for secure random number generator which is
# suitable for generating session key in HTTP cookies, etc.
#
# It supports following secure random number generators.
#
# * openssl
# * /dev/urandom
#
# == Example
#
# # random hexadecimal string.
# p SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"
# p SecureRandom.hex(10) #=> "92b15d6c8dc4beb5f559"
# p SecureRandom.hex(11) #=> "6aca1b5c58e4863e6b81b8"
# p SecureRandom.hex(12) #=> "94b2fff3e7fd9b9c391a2306"
# p SecureRandom.hex(13) #=> "39b290146bea6ce975c37cfc23"
# ...
#
# # random base64 string.
# p SecureRandom.base64(10) #=> "EcmTPZwWRAozdA=="
# p SecureRandom.base64(10) #=> "9b0nsevdwNuM/w=="
# p SecureRandom.base64(10) #=> "KO1nIU+p9DKxGg=="
# p SecureRandom.base64(11) #=> "l7XEiFja+8EKEtY="
# p SecureRandom.base64(12) #=> "7kJSM/MzBJI+75j8"
# p SecureRandom.base64(13) #=> "vKLJ0tXBHqQOuIcSIg=="
# ...
#
# # random binary string.
# p SecureRandom.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
# p SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"
# ...

begin
  require 'openssl'
rescue LoadError
end

module SecureRandom
  # SecureRandom.random_bytes generates a random binary string.
  #
  # The argument n specifies the length of the result string.
  #
  # If n is not specified, 16 is assumed.
  # It may be larger in future.
  #
  # If secure random number generator is not available,
  # NotImplementedError is raised.
  def self.random_bytes(n=nil)
    n ||= 16
    if defined? OpenSSL::Random
      @pid = 0 if !defined?(@pid)
      pid = $$
      if @pid != pid
        now = Time.now
        ary = [now.to_i, now.usec, @pid, pid]
        OpenSSL::Random.seed(ary.join('.'))
        @pid = pid
      end
      return OpenSSL::Random.random_bytes(n)
    end
    if !defined?(@has_urandom) || @has_urandom
      @has_urandom = false
      flags = File::RDONLY
      flags |= File::NONBLOCK if defined? File::NONBLOCK
      flags |= File::NOCTTY if defined? File::NOCTTY
      flags |= File::NOFOLLOW if defined? File::NOFOLLOW
      begin
        File.open("/dev/urandom", flags) {|f|
          unless f.stat.chardev?
            raise Errno::ENOENT
          end
          @has_urandom = true
          ret = f.readpartial(n)
          if ret.length != n
            raise NotImplementedError, "Unexpected partial read from random device"
          end
          return ret
        }
      rescue Errno::ENOENT
        raise NotImplementedError, "No random device"
      end
    end
    raise NotImplementedError, "No random device"
  end

  # SecureRandom.hex generates a random hex string.
  #
  # The argument n specifies the length of the random length.
  # The length of the result string is twice of n.
  #
  # If n is not specified, 16 is assumed.
  # It may be larger in future.
  #
  # If secure random number generator is not available,
  # NotImplementedError is raised.
  def self.hex(n=nil)
    random_bytes(n).unpack("H*")[0]
  end

  # SecureRandom.base64 generates a random base64 string.
  #
  # The argument n specifies the length of the random length.
  # The length of the result string is about 4/3 of n.
  #
  # If n is not specified, 16 is assumed.
  # It may be larger in future.
  #
  # If secure random number generator is not available,
  # NotImplementedError is raised.
  def self.base64(n=nil)
    [random_bytes(n)].pack("m*").delete("\n")
  end

  # SecureRandom.random_number generates a random number.
  #
  # If an positive integer is given as n,
  # SecureRandom.random_number returns an integer:
  # 0 <= SecureRandom.random_number(n) < n.
  #
  # If 0 is given or an argument is not given,
  # SecureRandom.random_number returns an float:
  # 0.0 <= SecureRandom.random_number() < 1.0.
  def self.random_number(n=0)
    if 0 < n
      hex = n.to_s(16)
      hex = '0' + hex if (hex.length & 1) == 1
      bin = [hex].pack("H*")
      mask = bin[0]
      mask |= mask >> 1
      mask |= mask >> 2
      mask |= mask >> 4
      begin
        rnd = SecureRandom.random_bytes(bin.length)
        rnd[0] = (rnd[0] & mask).chr
      end until rnd < bin
      rnd.unpack("H*")[0].hex
    else
      # assumption: Float::MANT_DIG <= 64
      i64 = SecureRandom.random_bytes(8).unpack("Q")[0]
      Math.ldexp(i64 >> (64-Float::MANT_DIG), -Float::MANT_DIG)
    end
  end
end
PK     Y\G      io/nonblock.rbnu [        require "fcntl"
class IO
  def nonblock?
    (fcntl(Fcntl::F_GETFL) & File::NONBLOCK) != 0
  end

  def nonblock=(nb)
    f = fcntl(Fcntl::F_GETFL)
    if nb
      f |= File::NONBLOCK
    else
      f &= ~File::NONBLOCK
    end
    fcntl(Fcntl::F_SETFL, f)
  end

  def nonblock(nb = true)
    nb, self.nonblock = nonblock?, nb
    yield
  ensure
    self.nonblock = nb
  end
end if defined?(Fcntl::F_GETFL)
PK     Y\WR    
  gserver.rbnu [        #
# Copyright (C) 2001 John W. Small All Rights Reserved
#
# Author::        John W. Small
# Documentation:: Gavin Sinclair
# Licence::       Freeware.
#
# See the class GServer for documentation.
#

require "socket"
require "thread"

#
# GServer implements a generic server, featuring thread pool management,
# simple logging, and multi-server management.  See HttpServer in 
# <tt>xmlrpc/httpserver.rb</tt> in the Ruby standard library for an example of
# GServer in action.
#
# Any kind of application-level server can be implemented using this class.
# It accepts multiple simultaneous connections from clients, up to an optional
# maximum number.  Several _services_ (i.e. one service per TCP port) can be
# run simultaneously, and stopped at any time through the class method
# <tt>GServer.stop(port)</tt>.  All the threading issues are handled, saving
# you the effort.  All events are optionally logged, but you can provide your
# own event handlers if you wish.
#
# === Example
#
# Using GServer is simple.  Below we implement a simple time server, run it,
# query it, and shut it down.  Try this code in +irb+:
#
#   require 'gserver'
#
#   #
#   # A server that returns the time in seconds since 1970.
#   # 
#   class TimeServer < GServer
#     def initialize(port=10001, *args)
#       super(port, *args)
#     end
#     def serve(io)
#       io.puts(Time.now.to_i)
#     end
#   end
#
#   # Run the server with logging enabled (it's a separate thread).
#   server = TimeServer.new
#   server.audit = true                  # Turn logging on.
#   server.start 
#
#   # *** Now point your browser to http://localhost:10001 to see it working ***
#
#   # See if it's still running. 
#   GServer.in_service?(10001)           # -> true
#   server.stopped?                      # -> false
#
#   # Shut the server down gracefully.
#   server.shutdown
#   
#   # Alternatively, stop it immediately.
#   GServer.stop(10001)
#   # or, of course, "server.stop".
#
# All the business of accepting connections and exception handling is taken
# care of.  All we have to do is implement the method that actually serves the
# client.
#
# === Advanced
#
# As the example above shows, the way to use GServer is to subclass it to
# create a specific server, overriding the +serve+ method.  You can override
# other methods as well if you wish, perhaps to collect statistics, or emit
# more detailed logging.
#
#   connecting
#   disconnecting
#   starting
#   stopping
#
# The above methods are only called if auditing is enabled.
#
# You can also override +log+ and +error+ if, for example, you wish to use a
# more sophisticated logging system.
#
class GServer

  DEFAULT_HOST = "127.0.0.1"

  def serve(io)
  end

  @@services = {}   # Hash of opened ports, i.e. services
  @@servicesMutex = Mutex.new

  def GServer.stop(port, host = DEFAULT_HOST)
    @@servicesMutex.synchronize {
      @@services[host][port].stop
    }
  end

  def GServer.in_service?(port, host = DEFAULT_HOST)
    @@services.has_key?(host) and
      @@services[host].has_key?(port)
  end

  def stop
    @connectionsMutex.synchronize  {
      if @tcpServerThread
        @tcpServerThread.raise "stop"
      end
    }
  end

  def stopped?
    @tcpServerThread == nil
  end

  def shutdown
    @shutdown = true
  end

  def connections
    @connections.size
  end

  def join
    @tcpServerThread.join if @tcpServerThread
  end

  attr_reader :port, :host, :maxConnections
  attr_accessor :stdlog, :audit, :debug

  def connecting(client)
    addr = client.peeraddr
    log("#{self.class.to_s} #{@host}:#{@port} client:#{addr[1]} " +
        "#{addr[2]}<#{addr[3]}> connect")
    true
  end

  def disconnecting(clientPort)
    log("#{self.class.to_s} #{@host}:#{@port} " +
      "client:#{clientPort} disconnect")
  end

  protected :connecting, :disconnecting

  def starting()
    log("#{self.class.to_s} #{@host}:#{@port} start")
  end

  def stopping()
    log("#{self.class.to_s} #{@host}:#{@port} stop")
  end

  protected :starting, :stopping

  def error(detail)
    log(detail.backtrace.join("\n"))
  end

  def log(msg)
    if @stdlog
      @stdlog.puts("[#{Time.new.ctime}] %s" % msg)
      @stdlog.flush
    end
  end

  protected :error, :log

  def initialize(port, host = DEFAULT_HOST, maxConnections = 4,
    stdlog = $stderr, audit = false, debug = false)
    @tcpServerThread = nil
    @port = port
    @host = host
    @maxConnections = maxConnections
    @connections = []
    @connectionsMutex = Mutex.new
    @connectionsCV = ConditionVariable.new
    @stdlog = stdlog
    @audit = audit
    @debug = debug
  end

  def start(maxConnections = -1)
    raise "running" if !stopped?
    @shutdown = false
    @maxConnections = maxConnections if maxConnections > 0
    @@servicesMutex.synchronize  {
      if GServer.in_service?(@port,@host)
        raise "Port already in use: #{host}:#{@port}!"
      end
      @tcpServer = TCPServer.new(@host,@port)
      @port = @tcpServer.addr[1]
      @@services[@host] = {} unless @@services.has_key?(@host)
      @@services[@host][@port] = self;
    }
    @tcpServerThread = Thread.new {
      begin
        starting if @audit
        while !@shutdown
          @connectionsMutex.synchronize  {
             while @connections.size >= @maxConnections
               @connectionsCV.wait(@connectionsMutex)
             end
          }
          client = @tcpServer.accept
          @connections << Thread.new(client)  { |myClient|
            begin
              myPort = myClient.peeraddr[1]
              serve(myClient) if !@audit or connecting(myClient)
            rescue => detail
              error(detail) if @debug
            ensure
              begin
                myClient.close
              rescue
              end
              @connectionsMutex.synchronize {
                @connections.delete(Thread.current)
                @connectionsCV.signal
              }
              disconnecting(myPort) if @audit
            end
          }
        end
      rescue => detail
        error(detail) if @debug
      ensure
        begin
          @tcpServer.close
        rescue
        end
        if @shutdown
          @connectionsMutex.synchronize  {
             while @connections.size > 0
               @connectionsCV.wait(@connectionsMutex)
             end
          }
        else
          @connections.each { |c| c.raise "stop" }
        end
        @tcpServerThread = nil
        @@servicesMutex.synchronize  {
          @@services[@host].delete(@port)
        }
        stopping if @audit
      end
    }
    self
  end

end
PK     Y\XZF  ZF  	  logger.rbnu [        # logger.rb - simple logging utility
# Copyright (C) 2000-2003, 2005  NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>.

require 'monitor'

# Simple logging utility.
#
# Author:: NAKAMURA, Hiroshi  <nakahiro@sarion.co.jp>
# Documentation:: NAKAMURA, Hiroshi and Gavin Sinclair
# License::
#   You can redistribute it and/or modify it under the same terms of Ruby's
#   license; either the dual license version in 2003, or any later version.
# Revision:: $Id: logger.rb 31806 2011-05-30 02:08:57Z nahi $
#
# == Description
#
# The Logger class provides a simple but sophisticated logging utility that
# anyone can use because it's included in the Ruby 1.8.x standard library.
#
# The HOWTOs below give a code-based overview of Logger's usage, but the basic
# concept is as follows.  You create a Logger object (output to a file or
# elsewhere), and use it to log messages.  The messages will have varying
# levels (+info+, +error+, etc), reflecting their varying importance.  The
# levels, and their meanings, are:
#
# +FATAL+:: an unhandleable error that results in a program crash
# +ERROR+:: a handleable error condition
# +WARN+::  a warning
# +INFO+::  generic (useful) information about system operation
# +DEBUG+:: low-level information for developers
#
# So each message has a level, and the Logger itself has a level, which acts
# as a filter, so you can control the amount of information emitted from the
# logger without having to remove actual messages.
#
# For instance, in a production system, you may have your logger(s) set to
# +INFO+ (or +WARN+ if you don't want the log files growing large with
# repetitive information).  When you are developing it, though, you probably
# want to know about the program's internal state, and would set them to
# +DEBUG+.
#
# === Example
#
# A simple example demonstrates the above explanation:
#
#   log = Logger.new(STDOUT)
#   log.level = Logger::WARN
#
#   log.debug("Created logger")
#   log.info("Program started")
#   log.warn("Nothing to do!")
#
#   begin
#     File.each_line(path) do |line|
#       unless line =~ /^(\w+) = (.*)$/
#         log.error("Line in wrong format: #{line}")
#       end
#     end
#   rescue => err
#     log.fatal("Caught exception; exiting")
#     log.fatal(err)
#   end
#
# Because the Logger's level is set to +WARN+, only the warning, error, and
# fatal messages are recorded.  The debug and info messages are silently
# discarded.
#
# === Features
#
# There are several interesting features that Logger provides, like
# auto-rolling of log files, setting the format of log messages, and
# specifying a program name in conjunction with the message.  The next section
# shows you how to achieve these things.
#
#
# == HOWTOs
#
# === How to create a logger
#
# The options below give you various choices, in more or less increasing
# complexity.
#
# 1. Create a logger which logs messages to STDERR/STDOUT.
#
#      logger = Logger.new(STDERR)
#      logger = Logger.new(STDOUT)
#
# 2. Create a logger for the file which has the specified name.
#
#      logger = Logger.new('logfile.log')
#
# 3. Create a logger for the specified file.
#
#      file = File.open('foo.log', File::WRONLY | File::APPEND)
#      # To create new (and to remove old) logfile, add File::CREAT like;
#      #   file = open('foo.log', File::WRONLY | File::APPEND | File::CREAT)
#      logger = Logger.new(file)
#
# 4. Create a logger which ages logfile once it reaches a certain size.  Leave
#    10 "old log files" and each file is about 1,024,000 bytes.
#
#      logger = Logger.new('foo.log', 10, 1024000)
#
# 5. Create a logger which ages logfile daily/weekly/monthly.
#
#      logger = Logger.new('foo.log', 'daily')
#      logger = Logger.new('foo.log', 'weekly')
#      logger = Logger.new('foo.log', 'monthly')
#
# === How to log a message
#
# Notice the different methods (+fatal+, +error+, +info+) being used to log
# messages of various levels.  Other methods in this family are +warn+ and
# +debug+.  +add+ is used below to log a message of an arbitrary (perhaps
# dynamic) level.
#
# 1. Message in block.
#
#      logger.fatal { "Argument 'foo' not given." }
#
# 2. Message as a string.
#
#      logger.error "Argument #{ @foo } mismatch."
#
# 3. With progname.
#
#      logger.info('initialize') { "Initializing..." }
#
# 4. With severity.
#
#      logger.add(Logger::FATAL) { 'Fatal error!' }
#
# === How to close a logger
#
#      logger.close
#
# === Setting severity threshold
#
# 1. Original interface.
#
#      logger.sev_threshold = Logger::WARN
#
# 2. Log4r (somewhat) compatible interface.
#
#      logger.level = Logger::INFO
#      
#      DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
#
#
# == Format
#
# Log messages are rendered in the output stream in a certain format.  The
# default format and a sample are shown below:
#
# Log format:
#   SeverityID, [Date Time mSec #pid] SeverityLabel -- ProgName: message
#
# Log sample:
#   I, [Wed Mar 03 02:34:24 JST 1999 895701 #19074]  INFO -- Main: info.
#
# You may change the date and time format in this manner:
#
#   logger.datetime_format = "%Y-%m-%d %H:%M:%S"
#         # e.g. "2004-01-03 00:54:26"
#
# There is currently no supported way to change the overall format, but you may
# have some luck hacking the Format constant.
#


class Logger
  VERSION = "1.2.6"
  ProgName = "#{File.basename(__FILE__)}/#{VERSION}"

  class Error < RuntimeError; end
  class ShiftingError < Error; end

  # Logging severity.
  module Severity
    DEBUG = 0
    INFO = 1
    WARN = 2
    ERROR = 3
    FATAL = 4
    UNKNOWN = 5
  end
  include Severity

  # Logging severity threshold (e.g. <tt>Logger::INFO</tt>).
  attr_accessor :level

  # Logging program name.
  attr_accessor :progname

  # Logging date-time format (string passed to +strftime+).
  def datetime_format=(datetime_format)
    @default_formatter.datetime_format = datetime_format
  end

  def datetime_format
    @default_formatter.datetime_format
  end

  # Logging formatter.  formatter#call is invoked with 4 arguments; severity,
  # time, progname and msg for each log.  Bear in mind that time is a Time and
  # msg is an Object that user passed and it could not be a String.  It is
  # expected to return a logdev#write-able Object.  Default formatter is used
  # when no formatter is set.
  attr_accessor :formatter

  alias sev_threshold level
  alias sev_threshold= level=

  # Returns +true+ iff the current severity level allows for the printing of
  # +DEBUG+ messages.
  def debug?; @level <= DEBUG; end

  # Returns +true+ iff the current severity level allows for the printing of
  # +INFO+ messages.
  def info?; @level <= INFO; end

  # Returns +true+ iff the current severity level allows for the printing of
  # +WARN+ messages.
  def warn?; @level <= WARN; end

  # Returns +true+ iff the current severity level allows for the printing of
  # +ERROR+ messages.
  def error?; @level <= ERROR; end

  # Returns +true+ iff the current severity level allows for the printing of
  # +FATAL+ messages.
  def fatal?; @level <= FATAL; end

  #
  # === Synopsis
  #
  #   Logger.new(name, shift_age = 7, shift_size = 1048576)
  #   Logger.new(name, shift_age = 'weekly')
  #
  # === Args
  #
  # +logdev+::
  #   The log device.  This is a filename (String) or IO object (typically
  #   +STDOUT+, +STDERR+, or an open file).
  # +shift_age+::
  #   Number of old log files to keep, *or* frequency of rotation (+daily+,
  #   +weekly+ or +monthly+).
  # +shift_size+::
  #   Maximum logfile size (only applies when +shift_age+ is a number).
  #
  # === Description
  #
  # Create an instance.
  #
  def initialize(logdev, shift_age = 0, shift_size = 1048576)
    @progname = nil
    @level = DEBUG
    @default_formatter = Formatter.new
    @formatter = nil
    @logdev = nil
    if logdev
      @logdev = LogDevice.new(logdev, :shift_age => shift_age,
        :shift_size => shift_size)
    end
  end

  #
  # === Synopsis
  #
  #   Logger#add(severity, message = nil, progname = nil) { ... }
  #
  # === Args
  #
  # +severity+::
  #   Severity.  Constants are defined in Logger namespace: +DEBUG+, +INFO+,
  #   +WARN+, +ERROR+, +FATAL+, or +UNKNOWN+.
  # +message+::
  #   The log message.  A String or Exception.
  # +progname+::
  #   Program name string.  Can be omitted.  Treated as a message if no +message+ and
  #   +block+ are given.
  # +block+::
  #   Can be omitted.  Called to get a message string if +message+ is nil.
  #
  # === Return
  #
  # +true+ if successful, +false+ otherwise.
  #
  # When the given severity is not high enough (for this particular logger), log
  # no message, and return +true+.
  #
  # === Description
  #
  # Log a message if the given severity is high enough.  This is the generic
  # logging method.  Users will be more inclined to use #debug, #info, #warn,
  # #error, and #fatal.
  #
  # <b>Message format</b>: +message+ can be any object, but it has to be
  # converted to a String in order to log it.  Generally, +inspect+ is used
  # if the given object is not a String.
  # A special case is an +Exception+ object, which will be printed in detail,
  # including message, class, and backtrace.  See #msg2str for the
  # implementation if required.
  #
  # === Bugs
  #
  # * Logfile is not locked.
  # * Append open does not need to lock file.
  # * But on the OS which supports multi I/O, records possibly be mixed.
  #
  def add(severity, message = nil, progname = nil, &block)
    severity ||= UNKNOWN
    if @logdev.nil? or severity < @level
      return true
    end
    progname ||= @progname
    if message.nil?
      if block_given?
	message = yield
      else
	message = progname
	progname = @progname
      end
    end
    @logdev.write(
      format_message(format_severity(severity), Time.now, progname, message))
    true
  end
  alias log add

  #
  # Dump given message to the log device without any formatting.  If no log
  # device exists, return +nil+.
  #
  def <<(msg)
    unless @logdev.nil?
      @logdev.write(msg)
    end
  end

  #
  # Log a +DEBUG+ message.
  #
  # See #info for more information.
  #
  def debug(progname = nil, &block)
    add(DEBUG, nil, progname, &block)
  end

  #
  # Log an +INFO+ message.
  #
  # The message can come either from the +progname+ argument or the +block+.  If
  # both are provided, then the +block+ is used as the message, and +progname+
  # is used as the program name.
  #
  # === Examples
  #
  #   logger.info("MainApp") { "Received connection from #{ip}" }
  #   # ...
  #   logger.info "Waiting for input from user"
  #   # ...
  #   logger.info { "User typed #{input}" }
  #
  # You'll probably stick to the second form above, unless you want to provide a
  # program name (which you can do with <tt>Logger#progname=</tt> as well).
  #
  # === Return
  #
  # See #add.
  #
  def info(progname = nil, &block)
    add(INFO, nil, progname, &block)
  end

  #
  # Log a +WARN+ message.
  #
  # See #info for more information.
  #
  def warn(progname = nil, &block)
    add(WARN, nil, progname, &block)
  end

  #
  # Log an +ERROR+ message.
  #
  # See #info for more information.
  #
  def error(progname = nil, &block)
    add(ERROR, nil, progname, &block)
  end

  #
  # Log a +FATAL+ message.
  #
  # See #info for more information.
  #
  def fatal(progname = nil, &block)
    add(FATAL, nil, progname, &block)
  end

  #
  # Log an +UNKNOWN+ message.  This will be printed no matter what the logger
  # level.
  #
  # See #info for more information.
  #
  def unknown(progname = nil, &block)
    add(UNKNOWN, nil, progname, &block)
  end

  #
  # Close the logging device.
  #
  def close
    @logdev.close if @logdev
  end

private

  # Severity label for logging. (max 5 char)
  SEV_LABEL = %w(DEBUG INFO WARN ERROR FATAL ANY)

  def format_severity(severity)
    SEV_LABEL[severity] || 'ANY'
  end

  def format_message(severity, datetime, progname, msg)
    (@formatter || @default_formatter).call(severity, datetime, progname, msg)
  end


  class Formatter
    Format = "%s, [%s#%d] %5s -- %s: %s\n"

    attr_accessor :datetime_format

    def initialize
      @datetime_format = nil
    end

    def call(severity, time, progname, msg)
      Format % [severity[0..0], format_datetime(time), $$, severity, progname,
        msg2str(msg)]
    end

  private

    def format_datetime(time)
      if @datetime_format.nil?
        time.strftime("%Y-%m-%dT%H:%M:%S.") << "%06d " % time.usec
      else
        time.strftime(@datetime_format)
      end
    end

    def msg2str(msg)
      case msg
      when ::String
        msg
      when ::Exception
        "#{ msg.message } (#{ msg.class })\n" <<
          (msg.backtrace || []).join("\n")
      else
        msg.inspect
      end
    end
  end


  class LogDevice
    attr_reader :dev
    attr_reader :filename

    class LogDeviceMutex
      include MonitorMixin
    end

    def initialize(log = nil, opt = {})
      @dev = @filename = @shift_age = @shift_size = nil
      @mutex = LogDeviceMutex.new
      if log.respond_to?(:write) and log.respond_to?(:close)
	@dev = log
      else
	@dev = open_logfile(log)
	@dev.sync = true
	@filename = log
	@shift_age = opt[:shift_age] || 7
	@shift_size = opt[:shift_size] || 1048576
      end
    end

    def write(message)
      @mutex.synchronize do
        if @shift_age and @dev.respond_to?(:stat)
          begin
            check_shift_log
          rescue
            raise Logger::ShiftingError.new("Shifting failed. #{$!}")
          end
        end
        @dev.write(message)
      end
    end

    def close
      @mutex.synchronize do
        @dev.close
      end
    end

  private

    def open_logfile(filename)
      if (FileTest.exist?(filename))
     	open(filename, (File::WRONLY | File::APPEND))
      else
       	create_logfile(filename)
      end
    end

    def create_logfile(filename)
      logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT))
      logdev.sync = true
      add_log_header(logdev)
      logdev
    end

    def add_log_header(file)
      file.write(
     	"# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]
    )
    end

    SiD = 24 * 60 * 60

    def check_shift_log
      if @shift_age.is_a?(Integer)
        # Note: always returns false if '0'.
        if @filename && (@shift_age > 0) && (@dev.stat.size > @shift_size)
          shift_log_age
        end
      else
        now = Time.now
        if @dev.stat.mtime <= previous_period_end(now)
          shift_log_period(now)
        end
      end
    end

    def shift_log_age
      (@shift_age-3).downto(0) do |i|
        if FileTest.exist?("#{@filename}.#{i}")
          File.rename("#{@filename}.#{i}", "#{@filename}.#{i+1}")
        end
      end
      @dev.close
      File.rename("#{@filename}", "#{@filename}.0")
      @dev = create_logfile(@filename)
      return true
    end

    def shift_log_period(now)
      postfix = previous_period_end(now).strftime("%Y%m%d")	# YYYYMMDD
      age_file = "#{@filename}.#{postfix}"
      if FileTest.exist?(age_file)
        raise RuntimeError.new("'#{ age_file }' already exists.")
      end
      @dev.close
      File.rename("#{@filename}", age_file)
      @dev = create_logfile(@filename)
      return true
    end

    def previous_period_end(now)
      case @shift_age
      when /^daily$/
        eod(now - 1 * SiD)
      when /^weekly$/
        eod(now - ((now.wday + 1) * SiD))
      when /^monthly$/
        eod(now - now.mday * SiD)
      else
        now
      end
    end

    def eod(t)
      Time.mktime(t.year, t.month, t.mday, 23, 59, 59)
    end
  end


  #
  # == Description
  #
  # Application -- Add logging support to your application.
  #
  # == Usage
  #
  # 1. Define your application class as a sub-class of this class.
  # 2. Override 'run' method in your class to do many things.
  # 3. Instantiate it and invoke 'start'.
  #
  # == Example
  #
  #   class FooApp < Application
  #     def initialize(foo_app, application_specific, arguments)
  #       super('FooApp') # Name of the application.
  #     end
  #
  #     def run
  #       ...
  #       log(WARN, 'warning', 'my_method1')
  #       ...
  #       @log.error('my_method2') { 'Error!' }
  #       ...
  #     end
  #   end
  #
  #   status = FooApp.new(....).start
  #
  class Application
    include Logger::Severity

    attr_reader :appname
    attr_reader :logdev

    #
    # == Synopsis
    #
    #   Application.new(appname = '')
    #
    # == Args
    #
    # +appname+:: Name of the application.
    #
    # == Description
    #
    # Create an instance.  Log device is +STDERR+ by default.  This can be
    # changed with #set_log.
    #
    def initialize(appname = nil)
      @appname = appname
      @log = Logger.new(STDERR)
      @log.progname = @appname
      @level = @log.level
    end

    #
    # Start the application.  Return the status code.
    #
    def start
      status = -1
      begin
	log(INFO, "Start of #{ @appname }.")
	status = run
      rescue
	log(FATAL, "Detected an exception. Stopping ... #{$!} (#{$!.class})\n" << $@.join("\n"))
      ensure
	log(INFO, "End of #{ @appname }. (status: #{ status.to_s })")
      end
      status
    end

    #
    # Sets the log device for this application.  See the class Logger for an
    # explanation of the arguments.
    #
    def set_log(logdev, shift_age = 0, shift_size = 1024000)
      @log = Logger.new(logdev, shift_age, shift_size)
      @log.progname = @appname
      @log.level = @level
    end

    def log=(logdev)
      set_log(logdev)
    end

    #
    # Set the logging threshold, just like <tt>Logger#level=</tt>.
    #
    def level=(level)
      @level = level
      @log.level = @level
    end

    #
    # See Logger#add.  This application's +appname+ is used.
    #
    def log(severity, message = nil, &block)
      @log.add(severity, message, @appname, &block) if @log
    end

  private

    def run
      raise RuntimeError.new('Method run must be defined in the derived class.')
    end
  end
end
PK     Y\r FO   O     singleton.rbnu [        # The Singleton module implements the Singleton pattern.
#
# Usage:
#    class Klass
#       include Singleton
#       # ...
#    end
#
# *  this ensures that only one instance of Klass lets call it
#    ``the instance'' can be created.
#
#    a,b  = Klass.instance, Klass.instance
#    a == b   # => true
#    a.new    #  NoMethodError - new is private ...
#
# *  ``The instance'' is created at instantiation time, in other
#    words the first call of Klass.instance(), thus
#
#      class OtherKlass
#        include Singleton
#        # ...
#      end
#      ObjectSpace.each_object(OtherKlass){} # => 0.
#
# *  This behavior is preserved under inheritance and cloning.
#
#
#
# This is achieved by marking
# *  Klass.new and Klass.allocate - as private
#
# Providing (or modifying) the class methods
# *  Klass.inherited(sub_klass) and Klass.clone()  -
#    to ensure that the Singleton pattern is properly
#    inherited and cloned.
#
# *  Klass.instance()  -  returning ``the instance''. After a
#    successful self modifying (normally the first) call the
#    method body is a simple:
#
#       def Klass.instance()
#         return @__instance__
#       end
#
# *  Klass._load(str)  -  calling Klass.instance()
#
# *  Klass._instantiate?()  -  returning ``the instance'' or
#    nil. This hook method puts a second (or nth) thread calling
#    Klass.instance() on a waiting loop. The return value
#    signifies the successful completion or premature termination
#    of the first, or more generally, current "instantiation thread".
#
#
# The instance method of Singleton are
# * clone and dup - raising TypeErrors to prevent cloning or duping
#
# *  _dump(depth) - returning the empty string.  Marshalling strips
#    by default all state information, e.g. instance variables and
#    taint state, from ``the instance''.  Providing custom _load(str)
#    and _dump(depth) hooks allows the (partially) resurrections of
#    a previous state of ``the instance''.



module Singleton
  #  disable build-in copying methods
  def clone
    raise TypeError, "can't clone instance of singleton #{self.class}"
  end
  def dup
    raise TypeError, "can't dup instance of singleton #{self.class}"
  end

  #  default marshalling strategy
  def _dump(depth=-1)
    ''
  end
end


class << Singleton
  #  Method body of first instance call.
  FirstInstanceCall = proc do
    #  @__instance__ takes on one of the following values
    #  * nil     -  before and after a failed creation
    #  * false  -  during creation
    #  * sub_class instance  -  after a successful creation
    #  the form makes up for the lack of returns in progs
    Thread.critical = true
    if  @__instance__.nil?
      @__instance__  = false
      Thread.critical = false
      begin
        @__instance__ = new
      ensure
        if @__instance__
          class <<self
            remove_method :instance
            def instance; @__instance__ end
          end
        else
          @__instance__ = nil #  failed instance creation
        end
      end
    elsif  _instantiate?()
      Thread.critical = false
    else
      @__instance__  = false
      Thread.critical = false
      begin
        @__instance__ = new
      ensure
        if @__instance__
          class <<self
            remove_method :instance
            def instance; @__instance__ end
          end
        else
          @__instance__ = nil
        end
      end
    end
    @__instance__
  end

  module SingletonClassMethods
    # properly clone the Singleton pattern - did you know
    # that duping doesn't copy class methods?
    def clone
      Singleton.__init__(super)
    end

    def _load(str)
      instance
    end

    private

    #  ensure that the Singleton pattern is properly inherited
    def inherited(sub_klass)
      super
      Singleton.__init__(sub_klass)
    end

    # waiting-loop hook
    def _instantiate?()
      while false.equal?(@__instance__)
        Thread.critical = false
        sleep(0.08)   # timeout
        Thread.critical = true
      end
      @__instance__
    end
  end

  def __init__(klass)
    klass.instance_eval { @__instance__ = nil }
    class << klass
      define_method(:instance,FirstInstanceCall)
    end
    klass
  end

  private
  #  extending an object with Singleton is a bad idea
  undef_method :extend_object

  def append_features(mod)
    #  help out people counting on transitive mixins
    unless mod.instance_of?(Class)
      raise TypeError, "Inclusion of the OO-Singleton module in module #{mod}"
    end
    super
  end

  def included(klass)
    super
    klass.private_class_method  :new, :allocate
    klass.extend SingletonClassMethods
    Singleton.__init__(klass)
  end
end



if __FILE__ == $0

def num_of_instances(klass)
    "#{ObjectSpace.each_object(klass){}} #{klass} instance(s)"
end

# The basic and most important example.

class SomeSingletonClass
  include Singleton
end
puts "There are #{num_of_instances(SomeSingletonClass)}"

a = SomeSingletonClass.instance
b = SomeSingletonClass.instance # a and b are same object
puts "basic test is #{a == b}"

begin
  SomeSingletonClass.new
rescue  NoMethodError => mes
  puts mes
end



puts "\nThreaded example with exception and customized #_instantiate?() hook"; p
Thread.abort_on_exception = false

class Ups < SomeSingletonClass
  def initialize
    self.class.__sleep
    puts "initialize called by thread ##{Thread.current[:i]}"
  end
end

class << Ups
  def _instantiate?
    @enter.push Thread.current[:i]
    while false.equal?(@__instance__)
      Thread.critical = false
      sleep 0.08
      Thread.critical = true
    end
    @leave.push Thread.current[:i]
    @__instance__
  end

  def __sleep
    sleep(rand(0.08))
  end

  def new
    begin
      __sleep
      raise  "boom - thread ##{Thread.current[:i]} failed to create instance"
    ensure
      # simple flip-flop
      class << self
        remove_method :new
      end
    end
  end

  def instantiate_all
    @enter = []
    @leave = []
    1.upto(9) {|i|
      Thread.new {
        begin
          Thread.current[:i] = i
          __sleep
          instance
        rescue RuntimeError => mes
          puts mes
        end
      }
    }
    puts "Before there were #{num_of_instances(self)}"
    sleep 3
    puts "Now there is #{num_of_instances(self)}"
    puts "#{@enter.join '; '} was the order of threads entering the waiting loop"
    puts "#{@leave.join '; '} was the order of threads leaving the waiting loop"
  end
end


Ups.instantiate_all
# results in message like
# Before there were 0 Ups instance(s)
# boom - thread #6 failed to create instance
# initialize called by thread #3
# Now there is 1 Ups instance(s)
# 3; 2; 1; 8; 4; 7; 5 was the order of threads entering the waiting loop
# 3; 2; 1; 7; 4; 8; 5 was the order of threads leaving the waiting loop


puts "\nLets see if class level cloning really works"
Yup = Ups.clone
def Yup.new
  begin
    __sleep
    raise  "boom - thread ##{Thread.current[:i]} failed to create instance"
  ensure
    # simple flip-flop
    class << self
      remove_method :new
    end
  end
end
Yup.instantiate_all


puts "\n\n","Customized marshalling"
class A
  include Singleton
  attr_accessor :persist, :die
  def _dump(depth)
    # this strips the @die information from the instance
    Marshal.dump(@persist,depth)
  end
end

def A._load(str)
  instance.persist = Marshal.load(str)
  instance
end

a = A.instance
a.persist = ["persist"]
a.die = "die"
a.taint

stored_state = Marshal.dump(a)
# change state
a.persist = nil
a.die = nil
b = Marshal.load(stored_state)
p a == b  #  => true
p a.persist  #  => ["persist"]
p a.die      #  => nil


puts "\n\nSingleton with overridden default #inherited() hook"
class Up
end
def Up.inherited(sub_klass)
  puts "#{sub_klass} subclasses #{self}"
end


class Middle < Up
  include Singleton
end

class Down < Middle; end

puts  "and basic \"Down test\" is #{Down.instance == Down.instance}\n
Various exceptions"

begin
  module AModule
    include Singleton
  end
rescue TypeError => mes
  puts mes  #=> Inclusion of the OO-Singleton module in module AModule
end

begin
  'aString'.extend Singleton
rescue NoMethodError => mes
  puts mes  #=> undefined method `extend_object' for Singleton:Module
end

end
PK     Y\/7lO  O    parsedate.rbnu [        #
# = parsedate.rb: Parses dates
#
# Author:: Tadayoshi Funaba
# Documentation:: Konrad Meyer
#
# ParseDate munches on a date and turns it into an array of values.
#

#
# ParseDate converts a date into an array of values.
# For example:
#
#   require 'parsedate'
#
#   ParseDate.parsedate "Tuesday, July 6th, 2007, 18:35:20 UTC"
#   # => [2007, 7, 6, 18, 35, 20, "UTC", 2]
#
# The order is of the form [year, month, day of month, hour, minute, second,
# timezone, day of the week].

require 'date/format'

module ParseDate
  #
  # Parse a string representation of a date into values.
  # For example:
  #
  #   require 'parsedate'
  #
  #   ParseDate.parsedate "Tuesday, July 5th, 2007, 18:35:20 UTC"
  #   # => [2007, 7, 5, 18, 35, 20, "UTC", 2]
  #
  # The order is of the form [year, month, day of month, hour, minute,
  # second, timezone, day of week].
  #
  # ParseDate.parsedate can also take a second argument, +comp+, which
  # is a boolean telling the method to compensate for dates with years
  # expressed as two digits. Example:
  #
  #   require 'parsedate'
  #
  #   ParseDate.parsedate "Mon Dec 25 00 06:53:24 UTC", true
  #   # => [2000, 12, 25, 6, 53, 24, "UTC", 1]
  #
  def parsedate(str, comp=false)
    Date._parse(str, comp).
      values_at(:year, :mon, :mday, :hour, :min, :sec, :zone, :wday)
  end

  module_function :parsedate

end
PK     Y\
    
  monitor.rbnu [        =begin

= monitor.rb

Copyright (C) 2001  Shugo Maeda <shugo@ruby-lang.org>

This library is distributed under the terms of the Ruby license.
You can freely distribute/modify this library.

== example

This is a simple example.

  require 'monitor.rb'
  
  buf = []
  buf.extend(MonitorMixin)
  empty_cond = buf.new_cond
  
  # consumer
  Thread.start do
    loop do
      buf.synchronize do
        empty_cond.wait_while { buf.empty? }
        print buf.shift
      end
    end
  end
  
  # producer
  while line = ARGF.gets
    buf.synchronize do
      buf.push(line)
      empty_cond.signal
    end
  end

The consumer thread waits for the producer thread to push a line
to buf while buf.empty?, and the producer thread (main thread)
reads a line from ARGF and push it to buf, then call
empty_cond.signal.

=end
  

#
# Adds monitor functionality to an arbitrary object by mixing the module with
# +include+.  For example:
#
#    require 'monitor.rb'
#    
#    buf = []
#    buf.extend(MonitorMixin)
#    empty_cond = buf.new_cond
#    
#    # consumer
#    Thread.start do
#      loop do
#        buf.synchronize do
#          empty_cond.wait_while { buf.empty? }
#          print buf.shift
#        end
#      end
#    end
#    
#    # producer
#    while line = ARGF.gets
#      buf.synchronize do
#        buf.push(line)
#        empty_cond.signal
#      end
#    end
# 
# The consumer thread waits for the producer thread to push a line
# to buf while buf.empty?, and the producer thread (main thread)
# reads a line from ARGF and push it to buf, then call
# empty_cond.signal.
#
module MonitorMixin
  #
  # FIXME: This isn't documented in Nutshell.
  #
  # Since MonitorMixin.new_cond returns a ConditionVariable, and the example
  # above calls while_wait and signal, this class should be documented.
  #
  class ConditionVariable
    class Timeout < Exception; end
    
    # Create a new timer with the argument timeout, and add the
    # current thread to the list of waiters.  Then the thread is
    # stopped.  It will be resumed when a corresponding #signal 
    # occurs.
    def wait(timeout = nil)
      @monitor.instance_eval {mon_check_owner()}
      timer = create_timer(timeout)
      
      Thread.critical = true
      count = @monitor.instance_eval {mon_exit_for_cond()}
      @waiters.push(Thread.current)

      begin
	Thread.stop
        return true
      rescue Timeout
        return false
      ensure
	Thread.critical = true
	begin
	  if timer && timer.alive?
	    Thread.kill(timer)
	  end
	  if @waiters.include?(Thread.current)  # interrupted?
	    @waiters.delete(Thread.current)
	  end
	  @monitor.instance_eval {mon_enter_for_cond(count)}
	ensure
	  Thread.critical = false
	end
      end
    end
    

    # call #wait while the supplied block returns +true+.
    def wait_while
      while yield
	wait
      end
    end
    
    # call #wait until the supplied block returns +true+.
    def wait_until
      until yield
	wait
      end
    end
    
    # Wake up and run the next waiter
    def signal
      @monitor.instance_eval {mon_check_owner()}
      Thread.critical = true
      t = @waiters.shift
      t.wakeup if t
      Thread.critical = false
      Thread.pass
    end
    
    # Wake up all the waiters.
    def broadcast
      @monitor.instance_eval {mon_check_owner()}
      Thread.critical = true
      for t in @waiters
	t.wakeup
      end
      @waiters.clear
      Thread.critical = false
      Thread.pass
    end
    
    def count_waiters
      return @waiters.length
    end
    
    private

    def initialize(monitor)
      @monitor = monitor
      @waiters = []
    end

    def create_timer(timeout)
      if timeout
	waiter = Thread.current
	return Thread.start {
	  Thread.pass
	  sleep(timeout)
	  Thread.critical = true
	  waiter.raise(Timeout.new)
	}
      else
        return nil
      end
    end
  end
  
  def self.extend_object(obj)
    super(obj)
    obj.instance_eval {mon_initialize()}
  end
  
  #
  # Attempts to enter exclusive section.  Returns +false+ if lock fails.
  #
  def mon_try_enter
    result = false
    Thread.critical = true
    if @mon_owner.nil?
      @mon_owner = Thread.current
    end
    if @mon_owner == Thread.current
      @mon_count += 1
      result = true
    end
    Thread.critical = false
    return result
  end
  # For backward compatibility
  alias try_mon_enter mon_try_enter

  #
  # Enters exclusive section.
  #
  def mon_enter
    Thread.critical = true
    mon_acquire(@mon_entering_queue)
    @mon_count += 1
  ensure
    Thread.critical = false
  end
  
  #
  # Leaves exclusive section.
  #
  def mon_exit
    mon_check_owner
    Thread.critical = true
    @mon_count -= 1
    if @mon_count == 0
      mon_release
    end
    Thread.critical = false
    Thread.pass
  end

  #
  # Enters exclusive section and executes the block.  Leaves the exclusive
  # section automatically when the block exits.  See example under
  # +MonitorMixin+.
  #
  def mon_synchronize
    mon_enter
    begin
      yield
    ensure
      mon_exit
    end
  end
  alias synchronize mon_synchronize
  
  #
  # FIXME: This isn't documented in Nutshell.
  # 
  # Create a new condition variable for this monitor.
  # This facilitates control of the monitor with #signal and #wait.
  #
  def new_cond
    return ConditionVariable.new(self)
  end

  private

  def initialize(*args)
    super
    mon_initialize
  end

  # called by initialize method to set defaults for instance variables.
  def mon_initialize
    @mon_owner = nil
    @mon_count = 0
    @mon_entering_queue = []
    @mon_waiting_queue = []
  end

  # Throw a ThreadError exception if the current thread
  # does't own the monitor
  def mon_check_owner
    if @mon_owner != Thread.current
      raise ThreadError, "current thread not owner"
    end
  end

  def mon_acquire(queue)
    while @mon_owner && @mon_owner != Thread.current
      queue.push(Thread.current)
      Thread.stop
      Thread.critical = true
    end
    @mon_owner = Thread.current
  end

  # mon_release requires Thread.critical == true
  def mon_release
    @mon_owner = nil
    while t = @mon_waiting_queue.shift || @mon_entering_queue.shift
      if t.alive?
        t.wakeup
        return
      end
    end
  end

  def mon_enter_for_cond(count)
    mon_acquire(@mon_waiting_queue)
    @mon_count = count
  end

  def mon_exit_for_cond
    count = @mon_count
    @mon_count = 0
    return count
  ensure
    mon_release
  end
end

# Monitors provide means of mutual exclusion for Thread programming.
# A critical region is created by means of the synchronize method,
# which takes a block.
# The condition variables (created with #new_cond) may be used 
# to control the execution of a monitor with #signal and #wait.
#
# the Monitor class wraps MonitorMixin, and provides aliases
#  alias try_enter try_mon_enter
#  alias enter mon_enter
#  alias exit mon_exit
# to access its methods more concisely.
class Monitor
  include MonitorMixin
  alias try_enter try_mon_enter
  alias enter mon_enter
  alias exit mon_exit
end


# Documentation comments:
#  - All documentation comes from Nutshell.
#  - MonitorMixin.new_cond appears in the example, but is not documented in
#    Nutshell.
#  - All the internals (internal modules Accessible and Initializable, class
#    ConditionVariable) appear in RDoc.  It might be good to hide them, by
#    making them private, or marking them :nodoc:, etc.
#  - The entire example from the RD section at the top is replicated in the RDoc
#    comment for MonitorMixin.  Does the RD section need to remain?
#  - RDoc doesn't recognise aliases, so we have mon_synchronize documented, but
#    not synchronize.
#  - mon_owner is in Nutshell, but appears as an accessor in a separate module
#    here, so is hard/impossible to RDoc.  Some other useful accessors
#    (mon_count and some queue stuff) are also in this module, and don't appear
#    directly in the RDoc output.
#  - in short, it may be worth changing the code layout in this file to make the
#    documentation easier

# Local variables:
# mode: Ruby
# tab-width: 8
# End:
PK     Y\1P7  7    parsearg.rbnu [        #
#		parsearg.rb - parse arguments
#			$Release Version: $
#			$Revision: 11708 $
#			$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#			by Yasuo OHBA(SHL Japan Inc. Technology Dept.)
#
# --
#
#	
#

warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: parsearg is deprecated after Ruby 1.8.1; use optparse instead"

$RCS_ID=%q$Header$

require "getopts"

def printUsageAndExit()
  if $USAGE
    eval($USAGE)
  end
  exit()
end

def setParenthesis(ex, opt, c)
  if opt != ""
    ex = sprintf("%s$OPT_%s%s", ex, opt, c)
  else
    ex = sprintf("%s%s", ex, c)
  end
  return ex
end

def setOrAnd(ex, opt, c)
  if opt != ""
    ex = sprintf("%s$OPT_%s %s%s ", ex, opt, c, c)
  else
    ex = sprintf("%s %s%s ", ex, c, c)
  end
  return ex
end

def setExpression(ex, opt, op)
  if !op
    ex = sprintf("%s$OPT_%s", ex, opt)
    return ex
  end
  case op.chr
  when "(", ")"
    ex = setParenthesis(ex, opt, op.chr)
  when "|", "&"
    ex = setOrAnd(ex, opt, op.chr)
  else
    return nil
  end
  return ex
end

# parseArgs is obsolete.  Use OptionParser instead.

def parseArgs(argc, nopt, single_opts, *opts)
  if (noOptions = getopts(single_opts, *opts)) == nil
    printUsageAndExit()
  end
  if nopt
    ex = nil
    pos = 0
    for o in nopt.split(/[()|&]/)
      pos += o.length
      ex = setExpression(ex, o, nopt[pos])
      pos += 1
    end
    begin
      if !eval(ex)
	printUsageAndExit()
      end
    rescue
      print "Format Error!! : \"" + nopt + "\"\t[parseArgs]\n"
      exit!(-1)
    end
  end
  if ARGV.length < argc
    printUsageAndExit()
  end
  return noOptions
end
PK     Y\$ū      x86_64-linux/defines.hnu [        /************************************************

  defines.h -

  $Author: knu $
  $Date: 2008-05-19 00:02:36 +0900 (Mon, 19 May 2008) $
  created at: Wed May 18 00:21:44 JST 1994

************************************************/
#ifndef DEFINES_H
#define DEFINES_H

#define RUBY

#ifdef __cplusplus
# ifndef  HAVE_PROTOTYPES
#  define HAVE_PROTOTYPES 1
# endif
# ifndef  HAVE_STDARG_PROTOTYPES
#  define HAVE_STDARG_PROTOTYPES 1
# endif
#endif

#undef _
#ifdef HAVE_PROTOTYPES
# define _(args) args
#else
# define _(args) ()
#endif

#undef __
#ifdef HAVE_STDARG_PROTOTYPES
# define __(args) args
#else
# define __(args) ()
#endif

#ifdef __cplusplus
#define ANYARGS ...
#else
#define ANYARGS
#endif

#define xmalloc ruby_xmalloc
#define xcalloc ruby_xcalloc
#define xrealloc ruby_xrealloc
#define xfree ruby_xfree

void *xmalloc _((long));
void *xcalloc _((long,long));
void *xrealloc _((void*,long));
void xfree _((void*));

#if SIZEOF_LONG_LONG > 0
# define LONG_LONG long long
#elif SIZEOF___INT64 > 0
# define HAVE_LONG_LONG 1
# define LONG_LONG __int64
# undef SIZEOF_LONG_LONG
# define SIZEOF_LONG_LONG SIZEOF___INT64
#endif

#if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
# define BDIGIT unsigned int
# define SIZEOF_BDIGITS SIZEOF_INT
# define BDIGIT_DBL unsigned LONG_LONG
# define BDIGIT_DBL_SIGNED LONG_LONG
#elif SIZEOF_INT*2 <= SIZEOF_LONG
# define BDIGIT unsigned int
# define SIZEOF_BDIGITS SIZEOF_INT
# define BDIGIT_DBL unsigned long
# define BDIGIT_DBL_SIGNED long
#elif SIZEOF_SHORT*2 <= SIZEOF_LONG
# define BDIGIT unsigned short
# define SIZEOF_BDIGITS SIZEOF_SHORT
# define BDIGIT_DBL unsigned long
# define BDIGIT_DBL_SIGNED long
#else
# define BDIGIT unsigned short
# define SIZEOF_BDIGITS (SIZEOF_LONG/2)
# define BDIGIT_DBL unsigned long
# define BDIGIT_DBL_SIGNED long
#endif

#ifdef __CYGWIN__
#undef _WIN32
#endif

#if defined(MSDOS) || defined(_WIN32) || defined(__human68k__) || defined(__EMX__)
#define DOSISH 1
#ifndef _WIN32_WCE
# define DOSISH_DRIVE_LETTER
#endif
#endif

/* define RUBY_USE_EUC/SJIS for default kanji-code */
#ifndef DEFAULT_KCODE
#if defined(DOSISH) || defined(__CYGWIN__) || defined(__MACOS__) || defined(OS2)
#define DEFAULT_KCODE KCODE_SJIS
#else
#define DEFAULT_KCODE KCODE_EUC
#endif
#endif

#if defined(__NeXT__) || defined(__APPLE__)
/* Do not trust WORDS_BIGENDIAN from configure since -arch compiler flag may
   result in a different endian.  Instead trust __BIG_ENDIAN__ and
   __LITTLE_ENDIAN__ which are set correctly by -arch. */
#undef WORDS_BIGENDIAN
#ifdef __BIG_ENDIAN__
#define WORDS_BIGENDIAN
#endif
#endif

#ifdef __NeXT__
/* NextStep, OpenStep, Rhapsody */
#ifndef S_IRUSR
#define S_IRUSR 0000400        /* read permission, owner */
#endif
#ifndef S_IRGRP
#define S_IRGRP 0000040        /* read permission, group */
#endif
#ifndef S_IROTH
#define S_IROTH 0000004        /* read permission, other */
#endif
#ifndef S_IWUSR
#define S_IWUSR 0000200        /* write permission, owner */
#endif
#ifndef S_IWGRP
#define S_IWGRP 0000020        /* write permission, group */
#endif
#ifndef S_IWOTH
#define S_IWOTH 0000002        /* write permission, other */
#endif
#ifndef S_IXUSR
#define S_IXUSR 0000100        /* execute/search permission, owner */
#endif
#ifndef S_IXGRP
#define S_IXGRP 0000010        /* execute/search permission, group */
#endif
#ifndef S_IXOTH
#define S_IXOTH 0000001        /* execute/search permission, other */
#endif
#ifndef S_IRWXU
#define S_IRWXU 0000700        /* read, write, execute permissions, owner */
#endif
#ifndef S_IRWXG
#define S_IRWXG 0000070        /* read, write, execute permissions, group */
#endif
#ifndef S_IRWXO
#define S_IRWXO 0000007        /* read, write, execute permissions, other */
#endif
#ifndef S_ISBLK
#define S_ISBLK(mode)  (((mode) & (0170000)) == (0060000))
#endif
#ifndef S_ISCHR
#define S_ISCHR(mode)  (((mode) & (0170000)) == (0020000))
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode)  (((mode) & (0170000)) == (0040000))
#endif
#ifndef S_ISFIFO
#define S_ISFIFO(mode) (((mode) & (0170000)) == (0010000))
#endif
#ifndef S_ISREG
#define S_ISREG(mode)  (((mode) & (0170000)) == (0100000))
#endif
#ifndef __APPLE__
/* NextStep, OpenStep (but not Rhapsody) */
#ifndef GETPGRP_VOID
#define GETPGRP_VOID 1
#endif
#ifndef WNOHANG
#define WNOHANG 01
#endif
#ifndef WUNTRACED
#define WUNTRACED 02
#endif
#ifndef X_OK
#define X_OK 1
#endif
#endif /* __APPLE__ */
#endif /* NeXT */

#ifdef _WIN32
#include "win32/win32.h"
#endif

#if defined(__VMS)
#include "vms.h"
#endif

#if defined(__BEOS__)
#include <net/socket.h> /* intern.h needs fd_set definition */
#endif

#ifdef RUBY_EXPORT
#undef RUBY_EXTERN
#endif

#ifndef RUBY_EXTERN
#define RUBY_EXTERN extern
#endif

#ifndef EXTERN
#define EXTERN RUBY_EXTERN	/* deprecated */
#endif

#ifndef RUBY_MBCHAR_MAXSIZE
#define RUBY_MBCHAR_MAXSIZE INT_MAX
        /* MB_CUR_MAX will not work well in C locale */
#endif

#if defined(sparc) || defined(__sparc__)
static inline void
flush_register_windows(void)
{
    asm
#ifdef __GNUC__
	volatile
#endif
# if defined(__sparc_v9__) || defined(__sparcv9) || defined(__arch64__)
	("flushw")
# else
	("ta  0x03")
# endif /* trap always to flush register windows if we are on a Sparc system */
	;
}
#  define FLUSH_REGISTER_WINDOWS flush_register_windows()
#elif defined(__ia64)
void *rb_ia64_bsp(void);
void rb_ia64_flushrs(void);
#  define FLUSH_REGISTER_WINDOWS rb_ia64_flushrs()
#else
#  define FLUSH_REGISTER_WINDOWS ((void)0)
#endif

#if defined(DOSISH)
#define PATH_SEP ";"
#elif defined(riscos)
#define PATH_SEP ","
#else
#define PATH_SEP ":"
#endif
#define PATH_SEP_CHAR PATH_SEP[0]

#if defined(__human68k__)
#define PATH_ENV "path"
#else
#define PATH_ENV "PATH"
#endif

#if defined(DOSISH) && !defined(__human68k__) && !defined(__EMX__)
#define ENV_IGNORECASE
#endif

#ifndef CASEFOLD_FILESYSTEM
# if defined DOSISH || defined __VMS
#   define CASEFOLD_FILESYSTEM 1
# else
#   define CASEFOLD_FILESYSTEM 0
# endif
#endif

#ifndef DLEXT_MAXLEN
#define DLEXT_MAXLEN 4
#endif

#ifndef RUBY_PLATFORM
#define RUBY_PLATFORM "unknown-unknown"
#endif

#endif
PK     Y\)      x86_64-linux/util.hnu [        /**********************************************************************

  util.h -

  $Author: shyouhei $
  $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
  created at: Thu Mar  9 11:55:53 JST 1995

  Copyright (C) 1993-2003 Yukihiro Matsumoto

**********************************************************************/

#ifndef UTIL_H
#define UTIL_H

#ifndef _
#ifdef __cplusplus
# ifndef  HAVE_PROTOTYPES
#  define HAVE_PROTOTYPES 1
# endif
# ifndef  HAVE_STDARG_PROTOTYPES
#  define HAVE_STDARG_PROTOTYPES 1
# endif
#endif
#ifdef HAVE_PROTOTYPES
# define _(args) args
#else
# define _(args) ()
#endif
#ifdef HAVE_STDARG_PROTOTYPES
# define __(args) args
#else
# define __(args) ()
#endif
#endif

#define scan_oct ruby_scan_oct
unsigned long scan_oct _((const char*, int, int*));
#define scan_hex ruby_scan_hex
unsigned long scan_hex _((const char*, int, int*));

#if defined(MSDOS) || defined(__CYGWIN32__) || defined(_WIN32)
void ruby_add_suffix();
#endif

void ruby_qsort _((void*, const int, const int, int (*)(), void*));
#define qsort(b,n,s,c,d) ruby_qsort(b,n,s,c,d)

void ruby_setenv _((const char*, const char*));
void ruby_unsetenv _((const char*));
#undef setenv
#undef unsetenv
#define setenv(name,val) ruby_setenv(name,val)
#define unsetenv(name,val) ruby_unsetenv(name);

char *ruby_strdup _((const char*));
#undef strdup
#define strdup(s) ruby_strdup(s)

char *ruby_getcwd _((void));
#define my_getcwd() ruby_getcwd()

double ruby_strtod _((const char*, char **));
#undef strtod
#define strtod(s,e) ruby_strtod(s,e)

#endif /* UTIL_H */
PK     Y\kkP8W  W    x86_64-linux/ruby.hnu [        /**********************************************************************

  ruby.h -

  $Author: shyouhei $
  created at: Thu Jun 10 14:26:32 JST 1993

  Copyright (C) 1993-2003 Yukihiro Matsumoto
  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
  Copyright (C) 2000  Information-technology Promotion Agency, Japan

**********************************************************************/

#ifndef RUBY_H
#define RUBY_H

#if defined(__cplusplus)
extern "C" {
#if 0
} /* satisfy cc-mode */
#endif
#endif

#include "config.h"
#ifdef RUBY_EXTCONF_H
#include RUBY_EXTCONF_H
#endif

#define NORETURN_STYLE_NEW 1
#ifndef NORETURN
# define NORETURN(x) x
#endif
#ifndef NOINLINE
# define NOINLINE(x) x
#endif

#include "defines.h"

#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif

#ifdef HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif

#ifdef HAVE_INTRINSICS_H
# include <intrinsics.h>
#endif

#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif

#include <stddef.h>
#include <stdio.h>

/* need to include <ctype.h> to use these macros */
#ifndef ISPRINT
#define ISASCII(c) isascii((int)(unsigned char)(c))
#undef ISPRINT
#define ISPRINT(c) (ISASCII(c) && isprint((int)(unsigned char)(c)))
#define ISSPACE(c) (ISASCII(c) && isspace((int)(unsigned char)(c)))
#define ISUPPER(c) (ISASCII(c) && isupper((int)(unsigned char)(c)))
#define ISLOWER(c) (ISASCII(c) && islower((int)(unsigned char)(c)))
#define ISALNUM(c) (ISASCII(c) && isalnum((int)(unsigned char)(c)))
#define ISALPHA(c) (ISASCII(c) && isalpha((int)(unsigned char)(c)))
#define ISDIGIT(c) (ISASCII(c) && isdigit((int)(unsigned char)(c)))
#define ISXDIGIT(c) (ISASCII(c) && isxdigit((int)(unsigned char)(c)))
#endif

#if defined(HAVE_ALLOCA_H)
#include <alloca.h>
#else
#  ifdef _AIX
#pragma alloca
#  endif
#endif

#if defined(__VMS)
# pragma builtins
# define alloca __alloca
#endif

#if SIZEOF_LONG != SIZEOF_VOIDP
# error ---->> ruby requires sizeof(void*) == sizeof(long) to be compiled. <<----
#else
typedef unsigned long VALUE;
typedef unsigned long ID;
#endif

#ifdef __STDC__
# include <limits.h>
#else
# ifndef LONG_MAX
#  ifdef HAVE_LIMITS_H
#   include <limits.h>
#  else
    /* assuming 32bit(2's compliment) long */
#   define LONG_MAX 2147483647
#  endif
# endif
# ifndef LONG_MIN
#  define LONG_MIN (-LONG_MAX-1)
# endif
# ifndef CHAR_BIT
#  define CHAR_BIT 8
# endif
#endif

#ifdef HAVE_LONG_LONG
# ifndef LLONG_MAX
#  ifdef LONG_LONG_MAX
#   define LLONG_MAX  LONG_LONG_MAX
#  else
#   ifdef _I64_MAX
#    define LLONG_MAX _I64_MAX
#   else
    /* assuming 64bit(2's complement) long long */
#    define LLONG_MAX 9223372036854775807LL
#   endif
#  endif
# endif
# ifndef LLONG_MIN
#  ifdef LONG_LONG_MIN
#   define LLONG_MIN  LONG_LONG_MIN
#  else
#   ifdef _I64_MIN
#    define LLONG_MIN _I64_MIN
#   else
#    define LLONG_MIN (-LLONG_MAX-1)
#   endif
#  endif
# endif
#endif

#define FIXNUM_MAX (LONG_MAX>>1)
#define FIXNUM_MIN RSHIFT((long)LONG_MIN,1)

#define FIXNUM_FLAG 0x01
#define INT2FIX(i) ((VALUE)(((long)(i))<<1 | FIXNUM_FLAG))
#define LONG2FIX(i) INT2FIX(i)
#define rb_fix_new(v) INT2FIX(v)
VALUE rb_int2inum _((long));
#define INT2NUM(v) rb_int2inum(v)
#define LONG2NUM(v) INT2NUM(v)
#define rb_int_new(v) rb_int2inum(v)
VALUE rb_uint2inum _((unsigned long));
#define UINT2NUM(v) rb_uint2inum(v)
#define ULONG2NUM(v) UINT2NUM(v)
#define rb_uint_new(v) rb_uint2inum(v)

#ifdef HAVE_LONG_LONG
VALUE rb_ll2inum _((LONG_LONG));
#define LL2NUM(v) rb_ll2inum(v)
VALUE rb_ull2inum _((unsigned LONG_LONG));
#define ULL2NUM(v) rb_ull2inum(v)
#endif

#if SIZEOF_OFF_T > SIZEOF_LONG && defined(HAVE_LONG_LONG)
# define OFFT2NUM(v) LL2NUM(v)
#elif SIZEOF_OFF_T == SIZEOF_LONG
# define OFFT2NUM(v) LONG2NUM(v)
#else
# define OFFT2NUM(v) INT2NUM(v)
#endif

#define FIX2LONG(x) RSHIFT((long)x,1)
#define FIX2ULONG(x) (((unsigned long)(x))>>1)
#define FIXNUM_P(f) (((long)(f))&FIXNUM_FLAG)
#define POSFIXABLE(f) ((f) < FIXNUM_MAX+1)
#define NEGFIXABLE(f) ((f) >= FIXNUM_MIN)
#define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f))

#define IMMEDIATE_MASK 0x03
#define IMMEDIATE_P(x) ((VALUE)(x) & IMMEDIATE_MASK)

#define SYMBOL_FLAG 0x0e
#define SYMBOL_P(x) (((VALUE)(x)&0xff)==SYMBOL_FLAG)
#define ID2SYM(x) ((VALUE)(((long)(x))<<8|SYMBOL_FLAG))
#define SYM2ID(x) RSHIFT((unsigned long)x,8)

/* special contants - i.e. non-zero and non-fixnum constants */
#define Qfalse ((VALUE)0)
#define Qtrue  ((VALUE)2)
#define Qnil   ((VALUE)4)
#define Qundef ((VALUE)6)	/* undefined value for placeholder */

#define RTEST(v) (((VALUE)(v) & ~Qnil) != 0)
#define NIL_P(v) ((VALUE)(v) == Qnil)

#define CLASS_OF(v) rb_class_of((VALUE)(v))

#define T_NONE   0x00

#define T_NIL    0x01
#define T_OBJECT 0x02
#define T_CLASS  0x03
#define T_ICLASS 0x04
#define T_MODULE 0x05
#define T_FLOAT  0x06
#define T_STRING 0x07
#define T_REGEXP 0x08
#define T_ARRAY  0x09
#define T_FIXNUM 0x0a
#define T_HASH   0x0b
#define T_STRUCT 0x0c
#define T_BIGNUM 0x0d
#define T_FILE   0x0e

#define T_TRUE   0x20
#define T_FALSE  0x21
#define T_DATA   0x22
#define T_MATCH  0x23
#define T_SYMBOL 0x24

#define T_BLKTAG 0x3b
#define T_UNDEF  0x3c
#define T_VARMAP 0x3d
#define T_SCOPE  0x3e
#define T_NODE   0x3f

#define T_MASK   0x3f

#define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK)

#define TYPE(x) rb_type((VALUE)(x))

#ifdef __GNUC__
#define RB_GC_GUARD_PTR(ptr) \
    __extension__ ({volatile VALUE *rb_gc_guarded_ptr = (ptr); rb_gc_guarded_ptr;})
#else
#define RB_GC_GUARD_PTR(ptr) (volatile VALUE *)(ptr)
#endif
#define RB_GC_GUARD(v) (*RB_GC_GUARD_PTR(&(v)))

void rb_check_type _((VALUE,int));
#define Check_Type(v,t) rb_check_type((VALUE)(v),t)

VALUE rb_str_to_str _((VALUE));
VALUE rb_string_value _((volatile VALUE*));
char *rb_string_value_ptr _((volatile VALUE*));
char *rb_string_value_cstr _((volatile VALUE*));

#define StringValue(v) rb_string_value(&(v))
#define StringValuePtr(v) rb_string_value_ptr(&(v))
#define StringValueCStr(v) rb_string_value_cstr(&(v))

void rb_check_safe_obj _((VALUE));
void rb_check_safe_str _((VALUE));
#define SafeStringValue(v) do {\
    StringValue(v);\
    rb_check_safe_obj(v);\
} while (0)
/* obsolete macro - use SafeStringValue(v) */
#define Check_SafeStr(v) rb_check_safe_str((VALUE)(v))

void rb_secure _((int));
RUBY_EXTERN int ruby_safe_level;
#define rb_safe_level() (ruby_safe_level)
void rb_set_safe_level _((int));
void rb_secure_update _((VALUE));

long rb_num2long _((VALUE));
unsigned long rb_num2ulong _((VALUE));
#define NUM2LONG(x) (FIXNUM_P(x)?FIX2LONG(x):rb_num2long((VALUE)x))
#define NUM2ULONG(x) rb_num2ulong((VALUE)x)
#if SIZEOF_INT < SIZEOF_LONG
long rb_num2int _((VALUE));
#define NUM2INT(x) (FIXNUM_P(x)?FIX2INT(x):rb_num2int((VALUE)x))
long rb_fix2int _((VALUE));
#define FIX2INT(x) rb_fix2int((VALUE)x)
unsigned long rb_num2uint _((VALUE));
#define NUM2UINT(x) rb_num2uint(x)
unsigned long rb_fix2uint _((VALUE));
#define FIX2UINT(x) rb_fix2uint(x)
#else
#define NUM2INT(x) ((int)NUM2LONG(x))
#define NUM2UINT(x) ((unsigned int)NUM2ULONG(x))
#define FIX2INT(x) ((int)FIX2LONG(x))
#define FIX2UINT(x) ((unsigned int)FIX2ULONG(x))
#endif

#ifdef HAVE_LONG_LONG
LONG_LONG rb_num2ll _((VALUE));
unsigned LONG_LONG rb_num2ull _((VALUE));
# define NUM2LL(x) (FIXNUM_P(x)?FIX2LONG(x):rb_num2ll((VALUE)x))
# define NUM2ULL(x) rb_num2ull((VALUE)x)
#endif

#if defined(HAVE_LONG_LONG) && SIZEOF_OFF_T > SIZEOF_LONG
# define NUM2OFFT(x) ((off_t)NUM2LL(x))
#else
# define NUM2OFFT(x) NUM2LONG(x)
#endif

double rb_num2dbl _((VALUE));
#define NUM2DBL(x) rb_num2dbl((VALUE)(x))

/* obsolete API - use StringValue() */
char *rb_str2cstr _((VALUE,long*));
/* obsolete API - use StringValuePtr() */
#define STR2CSTR(x) rb_str2cstr((VALUE)(x),0)

#define NUM2CHR(x) (((TYPE(x) == T_STRING)&&(RSTRING(x)->len>=1))?\
                     RSTRING(x)->ptr[0]:(char)(NUM2INT(x)&0xff))
#define CHR2FIX(x) INT2FIX((long)((x)&0xff))

VALUE rb_newobj _((void));
#define NEWOBJ(obj,type) type *obj = (type*)rb_newobj()
#define OBJSETUP(obj,c,t) do {\
    RBASIC(obj)->flags = (t);\
    RBASIC(obj)->klass = (c);\
    if (rb_safe_level() >= 3) FL_SET(obj, FL_TAINT);\
} while (0)
#define CLONESETUP(clone,obj) do {\
    OBJSETUP(clone,rb_singleton_class_clone((VALUE)obj),RBASIC(obj)->flags);\
    rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);\
    if (FL_TEST(obj, FL_EXIVAR)) rb_copy_generic_ivar((VALUE)clone,(VALUE)obj);\
} while (0)
#define DUPSETUP(dup,obj) do {\
    OBJSETUP(dup,rb_obj_class(obj),(RBASIC(obj)->flags)&(T_MASK|FL_EXIVAR|FL_TAINT));\
    if (FL_TEST(obj, FL_EXIVAR)) rb_copy_generic_ivar((VALUE)dup,(VALUE)obj);\
} while (0)

struct RBasic {
    unsigned long flags;
    VALUE klass;
};

struct RObject {
    struct RBasic basic;
    struct st_table *iv_tbl;
};

struct RClass {
    struct RBasic basic;
    struct st_table *iv_tbl;
    struct st_table *m_tbl;
    VALUE super;
};
#define RCLASS_IV_TBL(c) (RCLASS(c)->iv_tbl)
#define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
#define RCLASS_SUPER(c) (RCLASS(c)->super)
#define RMODULE_IV_TBL(m) RCLASS_IV_TBL(m)
#define RMODULE_M_TBL(m) RCLASS_M_TBL(m)
#define RMODULE_SUPER(m) RCLASS_SUPER(m)

struct RFloat {
    struct RBasic basic;
    double value;
};
#define RFLOAT_VALUE(v) (RFLOAT(v)->value)

#define ELTS_SHARED FL_USER2

struct RString {
    struct RBasic basic;
    long len;
    char *ptr;
    union {
	long capa;
	VALUE shared;
    } aux;
};
#define RSTRING_PTR(s) (RSTRING(s)->ptr)
#define RSTRING_LEN(s) (RSTRING(s)->len)
#define RSTRING_END(s) (RSTRING_PTR(s)+RSTRING_LEN(s))

struct RArray {
    struct RBasic basic;
    long len;
    union {
	long capa;
	VALUE shared;
    } aux;
    VALUE *ptr;
};
#define RARRAY_PTR(s) (RARRAY(s)->ptr)
#define RARRAY_LEN(s) (RARRAY(s)->len)

struct RRegexp {
    struct RBasic basic;
    struct re_pattern_buffer *ptr;
    long len;
    char *str;
};
#define RREGEXP_SRC_PTR(r) (RREGEXP(r)->src)
#define RREGEXP_SRC_LEN(r) (RREGEXP(r)->len)

struct RHash {
    struct RBasic basic;
    struct st_table *tbl;
    int iter_lev;
    VALUE ifnone;
};
#define RHASH_TBL(h) (RHASH(h)->tbl)
#define RHASH_ITER_LEV(h) (RHASH(h)->iter_lev)
#define RHASH_IFNONE(h) (RHASH(h)->ifnone)
#define RHASH_SIZE(h) (RHASH(h)->tbl->num_entries)
#define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0)

struct RFile {
    struct RBasic basic;
    struct rb_io_t *fptr;
};

struct RData {
    struct RBasic basic;
    void (*dmark) _((void*));
    void (*dfree) _((void*));
    void *data;
};

#define DATA_PTR(dta) (RDATA(dta)->data)

/*
#define RUBY_DATA_FUNC(func) ((void (*)_((void*)))func)
*/
typedef void (*RUBY_DATA_FUNC) _((void*));

VALUE rb_data_object_alloc _((VALUE,void*,RUBY_DATA_FUNC,RUBY_DATA_FUNC));

#define Data_Wrap_Struct(klass,mark,free,sval)\
    rb_data_object_alloc(klass,sval,(RUBY_DATA_FUNC)mark,(RUBY_DATA_FUNC)free)

#define Data_Make_Struct(klass,type,mark,free,sval) (\
    sval = ALLOC(type),\
    memset(sval, 0, sizeof(type)),\
    Data_Wrap_Struct(klass,mark,free,sval)\
)

#define Data_Get_Struct(obj,type,sval) do {\
    Check_Type(obj, T_DATA); \
    sval = (type*)DATA_PTR(obj);\
} while (0)

struct RStruct {
    struct RBasic basic;
    long len;
    VALUE *ptr;
};
#define RSTRUCT_LEN(st) (RSTRUCT(st)->len)
#define RSTRUCT_PTR(st) (RSTRUCT(st)->ptr)

struct RBignum {
    struct RBasic basic;
    char sign;
    long len;
    void *digits;
};
#define RBIGNUM_SIGN(b)       (RBIGNUM(b)->sign)
#define RBIGNUM_SET_SIGN(b,s) (RBIGNUM(b)->sign = (s))
#define RBIGNUM_POSITIVE_P(b) RBIGNUM_SIGN(b)
#define RBIGNUM_NEGATIVE_P(b) (!RBIGNUM_SIGN(b))
#define RBIGNUM_LEN(b)        (RBIGNUM(b)->len)
#define RBIGNUM_DIGITS(b)     (RBIGNUM(b)->digits)

#define R_CAST(st)   (struct st*)
#define RBASIC(obj)  (R_CAST(RBasic)(obj))
#define ROBJECT(obj) (R_CAST(RObject)(obj))
#define RCLASS(obj)  (R_CAST(RClass)(obj))
#define RMODULE(obj) RCLASS(obj)
#define RFLOAT(obj)  (R_CAST(RFloat)(obj))
#define RSTRING(obj) (R_CAST(RString)(obj))
#define RREGEXP(obj) (R_CAST(RRegexp)(obj))
#define RARRAY(obj)  (R_CAST(RArray)(obj))
#define RHASH(obj)   (R_CAST(RHash)(obj))
#define RDATA(obj)   (R_CAST(RData)(obj))
#define RSTRUCT(obj) (R_CAST(RStruct)(obj))
#define RBIGNUM(obj) (R_CAST(RBignum)(obj))
#define RFILE(obj)   (R_CAST(RFile)(obj))

#define FL_SINGLETON FL_USER0
#define FL_MARK      (1<<6)
#define FL_FINALIZE  (1<<7)
#define FL_TAINT     (1<<8)
#define FL_EXIVAR    (1<<9)
#define FL_FREEZE    (1<<10)

#define FL_USHIFT    11

#define FL_USER0     (1<<(FL_USHIFT+0))
#define FL_USER1     (1<<(FL_USHIFT+1))
#define FL_USER2     (1<<(FL_USHIFT+2))
#define FL_USER3     (1<<(FL_USHIFT+3))
#define FL_USER4     (1<<(FL_USHIFT+4))
#define FL_USER5     (1<<(FL_USHIFT+5))
#define FL_USER6     (1<<(FL_USHIFT+6))
#define FL_USER7     (1<<(FL_USHIFT+7))

#define FL_UMASK  (0xff<<FL_USHIFT)

#define SPECIAL_CONST_P(x) (IMMEDIATE_P(x) || !RTEST(x))

#define FL_ABLE(x) (!SPECIAL_CONST_P(x))
#define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0)
#define FL_SET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags |= (f);} while (0)
#define FL_UNSET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags &= ~(f);} while (0)
#define FL_REVERSE(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags ^= (f);} while (0)

#define OBJ_TAINTED(x) FL_TEST((x), FL_TAINT)
#define OBJ_TAINT(x) FL_SET((x), FL_TAINT)
#define OBJ_INFECT(x,s) do {if (FL_ABLE(x) && FL_ABLE(s)) RBASIC(x)->flags |= RBASIC(s)->flags & FL_TAINT;} while (0)

#define OBJ_FROZEN(x) FL_TEST((x), FL_FREEZE)
#define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE)

#define ALLOC_N(type,n) (type*)xmalloc(sizeof(type)*(n))
#define ALLOC(type) (type*)xmalloc(sizeof(type))
#define REALLOC_N(var,type,n) (var)=(type*)xrealloc((char*)(var),sizeof(type)*(n))

#define ALLOCA_N(type,n) (type*)alloca(sizeof(type)*(n))

#define MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n))
#define MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n))
#define MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n))
#define MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(n))

void rb_obj_infect _((VALUE,VALUE));

typedef int ruby_glob_func(const char*,VALUE);
void rb_glob _((const char*,void(*)(const char*,VALUE),VALUE));
void rb_globi _((const char*,void(*)(const char*,VALUE),VALUE));
int ruby_brace_expand _((const char*,int,ruby_glob_func*,VALUE));
int ruby_brace_glob _((const char*,int,ruby_glob_func*,VALUE));

VALUE rb_define_class _((const char*,VALUE));
VALUE rb_define_module _((const char*));
VALUE rb_define_class_under _((VALUE, const char*, VALUE));
VALUE rb_define_module_under _((VALUE, const char*));

void rb_include_module _((VALUE,VALUE));
void rb_extend_object _((VALUE,VALUE));

void rb_define_variable _((const char*,VALUE*));
void rb_define_virtual_variable _((const char*,VALUE(*)(ANYARGS),void(*)(ANYARGS)));
void rb_define_hooked_variable _((const char*,VALUE*,VALUE(*)(ANYARGS),void(*)(ANYARGS)));
int ruby_glob _((const char*,int,int(*)(const char*,VALUE),VALUE));
int ruby_globi _((const char*,int,int(*)(const char*,VALUE),VALUE));
void rb_define_readonly_variable _((const char*,VALUE*));
void rb_define_const _((VALUE,const char*,VALUE));
void rb_define_global_const _((const char*,VALUE));

#define RUBY_METHOD_FUNC(func) ((VALUE (*)(ANYARGS))func)
void rb_define_method _((VALUE,const char*,VALUE(*)(ANYARGS),int));
void rb_define_module_function _((VALUE,const char*,VALUE(*)(ANYARGS),int));
void rb_define_global_function _((const char*,VALUE(*)(ANYARGS),int));

void rb_undef_method _((VALUE,const char*));
void rb_define_alias _((VALUE,const char*,const char*));
void rb_define_attr _((VALUE,const char*,int,int));

void rb_global_variable _((VALUE*));
void rb_gc_register_address _((VALUE*));
void rb_gc_unregister_address _((VALUE*));

ID rb_intern _((const char*));
const char *rb_id2name _((ID));
ID rb_to_id _((VALUE));

const char *rb_class2name _((VALUE));
const char *rb_obj_classname _((VALUE));

void rb_p _((VALUE));

VALUE rb_eval_string _((const char*));
VALUE rb_eval_string_protect _((const char*, int*));
VALUE rb_eval_string_wrap _((const char*, int*));
VALUE rb_funcall __((VALUE, ID, int, ...));
VALUE rb_funcall2 _((VALUE, ID, int, const VALUE*));
VALUE rb_funcall3 _((VALUE, ID, int, const VALUE*));
int rb_scan_args __((int, const VALUE*, const char*, ...));
VALUE rb_call_super _((int, const VALUE*));

VALUE rb_gv_set _((const char*, VALUE));
VALUE rb_gv_get _((const char*));
VALUE rb_iv_get _((VALUE, const char*));
VALUE rb_iv_set _((VALUE, const char*, VALUE));

VALUE rb_equal _((VALUE,VALUE));

RUBY_EXTERN VALUE ruby_verbose, ruby_debug;

NORETURN(void rb_raise __((VALUE, const char*, ...)));
NORETURN(void rb_fatal __((const char*, ...)));
NORETURN(void rb_bug __((const char*, ...)));
NORETURN(void rb_sys_fail _((const char*)));
NORETURN(void rb_iter_break _((void)));
NORETURN(void rb_exit _((int)));
NORETURN(void rb_notimplement _((void)));

void rb_warning __((const char*, ...));		/* reports if `-w' specified */
void rb_sys_warning __((const char*, ...));	/* reports if `-w' specified */
void rb_warn __((const char*, ...));		/* reports always */

typedef VALUE rb_block_call_func _((VALUE, VALUE));

VALUE rb_each _((VALUE));
VALUE rb_yield _((VALUE));
VALUE rb_yield_values __((int n, ...));
VALUE rb_yield_splat _((VALUE));
int rb_block_given_p _((void));
void rb_need_block _((void));
VALUE rb_iterate _((VALUE(*)(VALUE),VALUE,VALUE(*)(ANYARGS),VALUE));
VALUE rb_rescue _((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE));
VALUE rb_rescue2 __((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE,...));
VALUE rb_ensure _((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE));
VALUE rb_catch _((const char*,VALUE(*)(ANYARGS),VALUE));
NORETURN(void rb_throw _((const char*,VALUE)));

VALUE rb_require _((const char*));

#ifdef __ia64
void ruby_init_stack(VALUE*, void*);
#define RUBY_INIT_STACK \
    VALUE variable_in_this_stack_frame; \
    ruby_init_stack(&variable_in_this_stack_frame, rb_ia64_bsp());
#else
void ruby_init_stack(VALUE*);
#define RUBY_INIT_STACK \
    VALUE variable_in_this_stack_frame; \
    ruby_init_stack(&variable_in_this_stack_frame);
#endif
void ruby_init _((void));
void ruby_options _((int, char**));
NORETURN(void ruby_run _((void)));

RUBY_EXTERN VALUE rb_mKernel;
RUBY_EXTERN VALUE rb_mComparable;
RUBY_EXTERN VALUE rb_mEnumerable;
RUBY_EXTERN VALUE rb_mPrecision;
RUBY_EXTERN VALUE rb_mErrno;
RUBY_EXTERN VALUE rb_mFileTest;
RUBY_EXTERN VALUE rb_mGC;
RUBY_EXTERN VALUE rb_mMath;
RUBY_EXTERN VALUE rb_mProcess;

RUBY_EXTERN VALUE rb_cObject;
RUBY_EXTERN VALUE rb_cArray;
RUBY_EXTERN VALUE rb_cBignum;
RUBY_EXTERN VALUE rb_cBinding;
RUBY_EXTERN VALUE rb_cClass;
RUBY_EXTERN VALUE rb_cCont;
RUBY_EXTERN VALUE rb_cDir;
RUBY_EXTERN VALUE rb_cData;
RUBY_EXTERN VALUE rb_cEnumerator;
RUBY_EXTERN VALUE rb_cFalseClass;
RUBY_EXTERN VALUE rb_cFile;
RUBY_EXTERN VALUE rb_cFixnum;
RUBY_EXTERN VALUE rb_cFloat;
RUBY_EXTERN VALUE rb_cHash;
RUBY_EXTERN VALUE rb_cInteger;
RUBY_EXTERN VALUE rb_cIO;
RUBY_EXTERN VALUE rb_cMatch;
RUBY_EXTERN VALUE rb_cMethod;
RUBY_EXTERN VALUE rb_cModule;
RUBY_EXTERN VALUE rb_cNameErrorMesg;
RUBY_EXTERN VALUE rb_cNilClass;
RUBY_EXTERN VALUE rb_cNumeric;
RUBY_EXTERN VALUE rb_cProc;
RUBY_EXTERN VALUE rb_cRange;
RUBY_EXTERN VALUE rb_cRegexp;
RUBY_EXTERN VALUE rb_cStat;
RUBY_EXTERN VALUE rb_cString;
RUBY_EXTERN VALUE rb_cStruct;
RUBY_EXTERN VALUE rb_cSymbol;
RUBY_EXTERN VALUE rb_cThread;
RUBY_EXTERN VALUE rb_cTime;
RUBY_EXTERN VALUE rb_cTrueClass;
RUBY_EXTERN VALUE rb_cUnboundMethod;

RUBY_EXTERN VALUE rb_eException;
RUBY_EXTERN VALUE rb_eStandardError;
RUBY_EXTERN VALUE rb_eSystemExit;
RUBY_EXTERN VALUE rb_eInterrupt;
RUBY_EXTERN VALUE rb_eSignal;
RUBY_EXTERN VALUE rb_eFatal;
RUBY_EXTERN VALUE rb_eArgError;
RUBY_EXTERN VALUE rb_eEOFError;
RUBY_EXTERN VALUE rb_eIndexError;
RUBY_EXTERN VALUE rb_eStopIteration;
RUBY_EXTERN VALUE rb_eRangeError;
RUBY_EXTERN VALUE rb_eIOError;
RUBY_EXTERN VALUE rb_eRuntimeError;
RUBY_EXTERN VALUE rb_eSecurityError;
RUBY_EXTERN VALUE rb_eSystemCallError;
RUBY_EXTERN VALUE rb_eThreadError;
RUBY_EXTERN VALUE rb_eTypeError;
RUBY_EXTERN VALUE rb_eZeroDivError;
RUBY_EXTERN VALUE rb_eNotImpError;
RUBY_EXTERN VALUE rb_eNoMemError;
RUBY_EXTERN VALUE rb_eNoMethodError;
RUBY_EXTERN VALUE rb_eFloatDomainError;
RUBY_EXTERN VALUE rb_eLocalJumpError;
RUBY_EXTERN VALUE rb_eSysStackError;
RUBY_EXTERN VALUE rb_eRegexpError;

RUBY_EXTERN VALUE rb_eScriptError;
RUBY_EXTERN VALUE rb_eNameError;
RUBY_EXTERN VALUE rb_eSyntaxError;
RUBY_EXTERN VALUE rb_eLoadError;

RUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr;
RUBY_EXTERN VALUE ruby_errinfo;

static inline VALUE
#if defined(HAVE_PROTOTYPES)
rb_class_of(VALUE obj)
#else
rb_class_of(obj)
    VALUE obj;
#endif
{
    if (FIXNUM_P(obj)) return rb_cFixnum;
    if (obj == Qnil) return rb_cNilClass;
    if (obj == Qfalse) return rb_cFalseClass;
    if (obj == Qtrue) return rb_cTrueClass;
    if (SYMBOL_P(obj)) return rb_cSymbol;

    return RBASIC(obj)->klass;
}

static inline int
#if defined(HAVE_PROTOTYPES)
rb_type(VALUE obj)
#else
rb_type(obj)
   VALUE obj;
#endif
{
    if (FIXNUM_P(obj)) return T_FIXNUM;
    if (obj == Qnil) return T_NIL;
    if (obj == Qfalse) return T_FALSE;
    if (obj == Qtrue) return T_TRUE;
    if (obj == Qundef) return T_UNDEF;
    if (SYMBOL_P(obj)) return T_SYMBOL;
    return BUILTIN_TYPE(obj);
}

static inline int
#if defined(HAVE_PROTOTYPES)
rb_special_const_p(VALUE obj)
#else
rb_special_const_p(obj)
    VALUE obj;
#endif
{
    if (SPECIAL_CONST_P(obj)) return Qtrue;
    return Qfalse;
}

#include "missing.h"
#include "intern.h"

#if defined(EXTLIB) && defined(USE_DLN_A_OUT)
/* hook for external modules */
static char *dln_libs_to_be_linked[] = { EXTLIB, 0 };
#endif

#if defined(HAVE_LIBPTHREAD)
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
typedef pthread_t rb_nativethread_t;
# define NATIVETHREAD_CURRENT() pthread_self()
# define NATIVETHREAD_EQUAL(t1,t2) pthread_equal((t1),(t2))
# define HAVE_NATIVETHREAD

# define NATIVETHREAD_KILL(th,sig) pthread_kill((th),(sig))
# define HAVE_NATIVETHREAD_KILL
#elif defined(_WIN32) || defined(_WIN32_WCE)
typedef DWORD rb_nativethread_t;
# define NATIVETHREAD_CURRENT() GetCurrentThreadId()
# define NATIVETHREAD_EQUAL(t1,t2) ((t1) == (t2))
# define HAVE_NATIVETHREAD
#endif
#ifdef HAVE_NATIVETHREAD
int is_ruby_native_thread _((void));
#else
#define is_ruby_native_thread() (1)
#endif
#ifdef HAVE_NATIVETHREAD_KILL
void ruby_native_thread_kill _((int));
#endif

#if defined(__cplusplus)
#if 0
{ /* satisfy cc-mode */
#endif
}  /* extern "C" { */
#endif

#endif /* ifndef RUBY_H */
PK     Y\.  .    x86_64-linux/io/wait.sonu ȯ        ELF          >          @       '          @ 8 	 @                                                                                                                         0      0                   8      8      8      $       $                    x      x      x                             Std   x      x      x                             Ptd   \      \      \      4       4              Qtd                                                  Rtd                     p      p                      GNU %cQ0L6`y^I                `"            BE|qXMV                                                  	                                                                                                                                                                                z                                                                   U                                            g                                           &                     ,                       F   "                                                                                                             @        __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_io_taint_check rb_io_check_closed rb_io_check_readable rb_scan_args rb_time_interval feof rb_read_pending fileno __fdelt_chk rb_thread_select ioctl __stack_chk_fail rb_sys_fail rb_int2inum Init_wait rb_cIO rb_define_method libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 GLIBC_2.15 GLIBC_2.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                        ui	                ii                                         @                                                                                                                                                                        (                     0                     8                     @                     H                     P          	           X          
           `                     h                     p                     x                                                                                    HH9  HtH             5B  %C   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  H=  H  H9tH  Ht	        H=  H5  H)HHH?HHtH  HtfD      =M   u+UH=   HtH=>  Id%  ]     w    AWAVAUIATIUHSH   dH%(   H$   1HXHHtLHL$H`  1E1	H|$HtLl$ HD$ HT$(H+H?1҅t1H$   dH34%(   H   H   []A\A]A^A_D  HD$   HL|$0T$   LAƉHIcDA~MLA?)Ѻ   H1H	T01xSHH;HHT$T  1Iu$D$   IO   1f.     SHdH%(   HD$1"HXH6HH;HH1҅tHL$dH3%(   HuYH[@ Hpu<HHT$T  1u)Hc|$   ~
HD     41ff.     fSH  1HH54   H;|H;[H\H5   `HH01 ready? wait ;0      dL   tt   4                zR x  $         FJw ?:*3$"       D              H   \      FBB E(D0F8G
8A0A(B BBBF           ED Y
AE       @    Ec                GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           @                   7             F             V             a             l             z                                       	             @                                                            o    `                                
                                                                                         X                    	              o          o           o          o                                                                                                                                                         	      	      	       
      
       
      0
      @
      P
      `
      p
      
      
      
      
      
               GA$3a1 	      M               GA$3p1067        @                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY           &               GA+GLIBCXX_ASSERTIONS   wait.so-1.8.7-16.el8.x86_64.debug   7zXZ  ִF !   t/O$] ?Eh=ڊ2N``v ^)U)v3*fʹƇv2g	 ;r N>UaL'U%jUK<'+*	A|oSą&";/) /XU1c	0 -B]hp	oO++K/=1Tk44$[<Y}@"_i2a&2aO(P N,Ӕ>y9&=ٯ0	G굙<kW\ '^k:*yylͲo[͋0:gɖ$>{d T܂7u9X@..ɭjE]7(7> ܳ3:G!$\#yLDU?ܨ9m:GO'Tnu#b*ghH޾|d~=hslΚ)7sKEhdoNyW*&y7,	3rFY@s$ϦA@t̄06%Qaa8C+)<"kEL(l_0ZOSbMCEw-0@|Y!lEώg*~A(հVP8SD ̕D ًΈ=(EPM
u鉘4}ЀhJp訉ӮjOt,[K5D'Je(])c˅e,9(kueY>^ushs]5`lǸ6@hzf1k[X96H$GٻҐ #L[   Dܕng    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                               8      8      $                                 o       `      `      4                             (                         X                          0                                                      8   o                   2                            E   o                   @                            T             X      X                                  ^      B                                             h             	      	                                    c             	      	                                  n             
      
                                   w                         p                             }             @      @                                          2       M      M                                                \      \      4                                                                                                  x      x                                                                                                                                                                                                                                 0                                                    (                                                                                                                                                               `            H                                                  "      (                                                   #      d                                                   l&      +                             PK     Y\qA8a  8a    x86_64-linux/dbm.sonu ȯ        ELF          >          @       Y          @ 8 	 @                                 @      @                    HM      HM      HM      `      x                    `M      `M      `M      P      P                   8      8      8      $       $                    @      @      @                             Std   @      @      @                             Ptd   7      7      7      L      L             Qtd                                                  Rtd   HM      HM      HM                                  GNU O33uzl,?       ;         H   ;   =   >   BE|qXU                                                 c                      [                                                                                                                                 @                     m                                                                                                                                                    4                     c                                                                                      #                                                                x                                                                                                                                   U                      (                     )                                                                                     Q                                                                                                          B                                                                                                          1                     ,                       l                                          N                     V                     F   "                                                             z                     l                                               Q                  Q                  Q              {     0      q       __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_check_type rb_raise rb_hash_new dbm_firstkey dbm_fetch rb_tainted_str_new rb_hash_aset dbm_nextkey rb_ary_new rb_assoc_new rb_ary_push rb_string_value memcmp rb_iterate rb_intern rb_funcall rb_hash_delete_if rb_yield rb_block_given_p rb_ary_new2 rb_warn rb_eArgError dbm_close rb_scan_args rb_fix2int rb_num2int rb_check_safe_obj dbm_open ruby_xmalloc __stack_chk_fail rb_sys_fail rb_data_object_alloc rb_ensure free rb_secure rb_error_frozen dbm_delete rb_str_dup rb_protect rb_jump_tag rb_obj_as_string dbm_store __errno_location rb_eIndexError Init_dbm rb_cObject rb_define_class rb_eStandardError rb_mEnumerable rb_include_module rb_define_alloc_func rb_define_singleton_method rb_define_method rb_define_const rb_str_new2 libruby.so.1.8 libgdbm_compat.so.4 libgdbm.so.6 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 GLIBC_2.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                   _         ui	                    ii        ui	         HM             `      PM                    XM             XM      O                    O                    O                    O                     O         (           O         0           O         1           O         2           O         4           O         5           P                     P                    (P                    0P                    8P                    @P                    HP         	           PP         
           XP                    `P                    hP                    pP                    xP                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                      Q         !           Q         "           Q         #           Q         $            Q         %           (Q         &           0Q         '           8Q         )           @Q         *           HQ         +           PQ         ,           XQ         -           `Q         .           hQ         /           pQ         3           xQ         5           Q         6           Q         7           Q         8           Q         9           Q         :           HHy<  HtH             5<  %<   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   %}9  D  %u9  D  %m9  D  %e9  D  %]9  D  %U9  D  %M9  D  %E9  D  %=9  D  %59  D  %-9  D  %%9  D  %9  D  %9  D  %9  D  %9  D  %8  D  %8  D  %8  D  %8  D  %8  D  %8  D  %8  D  %8  D  %8  D  %8  D  %8  D  %8  D  %8  D  %8  D  %8  D  %8  D  %}8  D  %u8  D  %m8  D  %e8  D  %]8  D  %U8  D  %M8  D  %E8  D  %=8  D  %58  D  %-8  D  %%8  D  %8  D  %8  D  %8  D  %8  D  %7  D  %7  D  H=7  H7  H9tH5  Ht	        H=7  H57  H)HHH?HHtH5  HtfD      =}7   u+UH=5   HtH=3  	dU7  ]     w    S"   HHC HtHx [HD     [f     PXH5  1HH=6  D  AV"   AUATUSHWHC H~   L`MtuLIHHHtNfD  HHL2HcHHcHILLHLcHHHu[L]A\A]A^15D  AWAVAUATUSHH"   HIHC Ht}L`MttL,HHHtOHHLHcHII1IcLH#HLHLHHHuHL[]A\A]A^A_1yf     S"   HHC HtFHXHt= xt1[ø   [f     HhHt H(Hu11     AT"   USH{Hk Ht[LeMtRHcE ~[HD ]A\    LHt#1ېLHuHcHD ] []A\ø   11AV"   AUATUSHHC H   L`Mt}LLIHHHtVfD  HHLHcHHcHIyLHLHLHHHu[L]A\A]A^1ff.     fU"   SHH9HC HtXHXHtOHHHt0fHH%HcHHHHgHuHH[]1AU"   SHHHC HtMHXHtDHHGHt%fHcHeHH
HHuHH[]1ff.     ATUSHHH|$Ht$HD$"   HL`hHC Ht)HxHt LHHH[]HA\1PSHHH|$Ht$%"   HHC HtjHXHtaHNHt?f     HHHL$HcH;QuHqHtHHuH1[fH   [1ff.      ATUSHHH|$Ht$r"   HHC H   HhHt{HHIHtC@ HLHHL$HcH;QuHqHPt$H$HIHuH   []A\ IcH]H[]A\1ff.     fSHHH.  H=   H[ff.     fSHH=  H11H[1
f.     H1HHD  S"   HHC HtVHxHtMgHt>fHcHH"   HHC HtHxHtHuH[1     U"   HSHIHE HttHXHtkHHtTf.     HH5HcHH"   HHE Ht HXHtH[HuHH[]15D  AV"   AUIATUSIE H   HhH   H5IHHt|f.     HLHHcLHI1HcLH#HHhH@"   L#IE Ht(HhHtHIHHu[L]A\A]A^1[ff.     AUIATUSHHH|$Ht$!HD$"   LL`HhIE HteHxHt\LHt&HcH[HHH[]A\A]f.     HuEtHcL&HNH1f   1@AUHcATIIUSHHHE~/AELlH3   L1HHH_L9uHH[]A\A]ff.     1     AVHcAUIATUHSH#Ik   4  "   L^IE H  HhH  HIHHuG   @ "   LIE H   HhH   HyIHH   HLHHcHHcLHHHHHHyHL&i1H=  ~4EHlfD  H3   L1HzLHH9u[L]A\A]A^1H)  H57  H81}ff.     fS"   HH[ HtH{Ht'HC       [1AAUATUHH?  S  H(dH%(   HD$1ILL$LD$LNt!H|$Ht@/  H|$H   @usALH<$A    trH$DځHxIMur      HL$dH3%(      H([]A\A]@ AfD  L(H<$OH$HxxCھB   wIHt'   HE L` H|    H$Hx1Ҿ   4IHuH$11HxI- H$HxBfH   11ff.     ATHs   I1UH1SpLHH1HtuH[]A\       H[]A\ H=!'  HH[H{]A\ HtSHHHtH[@     SH   uHtHu[H=  ff.      AW1AVAUATUSHH"   HHC H   HXH    HoHIHtTHHIcHIIxIcLIjHHLIHLL[]A\A]A^A_H   []A\A]A^A_1D  AWAVAUIATUSHXdH%(   HD$H1LD$<    I1"   LIm H  H]H  E E H߉D$,tIIAH  HD$<HD$ GfD  "   LIm H  H]Hw  HIIAH   DLHLD$H    L!H	HIVLD$IcHT$LHD$HT$H|$HD$@HcH|$@IhLHHT$ H=i$  HT$<u!H%Ht$@LH ID$HT$@E1HT$H~`f     ID$ H|$JHD$@HD$@HH    L!L@@H	LHI[uLID$II9||$<uP\$,~)É] H\$HdH3%(   Lu+HX[]A\A]A^A_1kH=d%  H5v	  1Fff.     AV1AUATUSHHHt$aH|$HD$H߾"   LhD`H[ H   HkH   LLHHt@HcH5LLHITuSxHL[]A\A]A^D  A   tH|$HI[]LA\A]A^1]H=P$  H5b  12fAT1UHSn"   HLe MtYI\$HtOA$@ HHuH)HuA$    H[]A\H=#  H5  11     U1HSHHYHHH   H=HH[]fD  AW1AVAUATIUHSHHLHI{"   HMl$HLxDpEd$HC HtoHxHtf LMLA   Lt&8t4H="  H5  1    HH[]A\A]A^A_fD  1Q1f.     UH	   SHHH{~HC HHPH0H   []H   H5~  H81(     UHHw  SH(dH%(   HD$1HL$LD$KHT$H1Ht$HŃtHT$dH3%(   Hu3H([]D  ;HuօuH  H5  H81@ HH  H=  H0bH=  Hl!  H}  H0EH=V!  HG!  Hx  H0xH=9!  H5uH=&!  HH5{  H=!  HH5a  H=   1HWH5P  H=   1H{H5:  H=      HH5#  `H=   HMH5  AH=r      HH5  "H=S      HH5  H=4      HH5  H=   HqH5  H=  HRH5  H=  HH5s  H=  HH5[  hH=  1HH5I  LH=}  1HlH54  0H=a  1HH5  H=E  1HH5  H=)  1HHH5  H=  1HH5  H=  1HH5  H=  1HH5  H=  1HH5  lH=  1HH5  PH=     H-H5l  1H=b  1HH5W  H=F  1HH5E  H=*  1HH51  H=  1HH5  H=  1HH5  H=     HH5  H=     HH5  gH=     HH5  HH=y     HH5  )H=Z     HH5  
H=;     HH5|  H=     HHH5P  H=     HH5B  H=  1HMH5-  H=  1HH5  uH=    @H5  MH=    @H5  5H=v    @H5  H=^   @H5  H=  IH=:  HH5  H   HH       closed DBM file each_pair 12 DBM dbm_delete failed dbm_store failed pair must be [key, value] 11 key not found DBMError open initialize close closed? [] fetch []= store index indexes indices select values_at length size empty? each each_value each_key keys values shift delete delete_if reject! reject clear invert update replace include? has_key? member? has_value? to_a to_hash READER WRITER WRCREAT NEWDB unknown VERSION wrong number arguments(%d for 0)        DBM#select(index..) is deprecated; use DBM#values_at    ;L  (   h            $  p       @  8  @d    `  0  `$  @  X  0x      `   p4  l        p  ,  p  @    P  \    P    pX    p             zR x  $      @0   FJw ?:*3$"       D   H              \   7    E\
OF    |   0    AAM  <      4    FGB A(A0
(D BBBA   H          FBB B(A0A8G@
8D0A(B BBBA     $  h    Ej
AF
J  4   H  d    FFA c
FBHl
ABA<         FGB A(A0
(D BBBA   (     ,    EFG `
DAA (     t    EFG U
DAA 0     p    FAA G0O
 DAEA (   L      EG ~
CCD
FA@   x      FAA G0
 FABDO
 AABA        #    E]        4&    EZ        H    HK      Px    Ek
A   (   ,      EID |
DAA <   X  $    FGE A(A0
(D BBBA   8         BEA A(G@\
(D ABBK      8       4     4d    FEG A(G0@(D ABB      l       <   4  h   FEE A(D0B
(D BBBA     t  ?    Er
A8        FBA K(IP
(A ABBE      P       @     \}    FMH j
ABHI
ABDNHB      $  )    JU     @  2    Ad
A`   \      FDB B(A0A8G@
8G0A(B BBBED
8F0A(B BBBA L     <d   FBB E(A0A8D
8A0A(B BBBA   T     \    FDB A(A0G@
0D(A BBBF]
0D(A EBBA,   h      FCD [
ABA   $     d:    EFG bDA H     |    FDB B(D0D8G@
8D0A(B BBBG (     X    EIG c
FAA  (   8  D    EKF@R
AAF    d  q   HZ                GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     `             XM             /             >             R             _             o             z                                                                 8             5             HM                           PM                    o    `                                
                                   P                                                     P             8      	              o           o           o          o                                                                                                                                                                           `M                      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                     GA$3a1 8      5               GA$3p1067  p      5                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY     p                     GA+GLIBCXX_ASSERTIONS   dbm.so-1.8.7-16.el8.x86_64.debug    YqE7zXZ  ִF !   t/?r] ?Eh=ڊ2NO>>'>L$;	=ֿ0٬a<%9%PK',I3h%̦I@fK(d6:`(~Fٰz2[wib#4YU'ڦ6(̳"ƞQފa9
[&K +rvW&'V_NA`*~ uSowIf*jrJ[nO}`d!ntn6dےFcё.Mkn$?\S|l{ɲl$gk	[+(Dy$7prѧu򐶷RV\	gxiнZ`_CA{@h?=[_W@vO~Γ2*f6+)Qaj3FܭVGT }@B7\[ݝe6kF.{+M)4~EYgPġb$UkǙLDg<JFpZ٥A@q7	2xl'TW+XF:{&_,	'Q96q@8hRBpZ
`~\䬯Ah.،H33 }7Zzss0;"o} (ol|Pͭ4XfHV1XY(+KZ[Γ֌Ջd%R2eWP{<MmrAik"{b%-D'YE`7C_)>]hG\9
mρ
w:!%Ϭ?d=$TxgaA%vȁIu)>ҎkHGe<(p:w6o2(zV;%<9iןR1"dIqe.eUvN
2Kz5ef89ʼ30ѩYG\봃gXUz'@ u
=,S	"2] m(s=%vɈxAswi@%fq4Ĭot0\ªY>=u椛N|ShmX=`H@pk;g̑   ŻV"D5[ 	&  Prg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                               8      8      $                                 o       `      `      4                             (                                                   0                                                      8   o                   ~                            E   o                     P                            T             P      P      8                           ^      B                                             h             8      8                                    c             `      `      0                            n                                                      w                                                      }             5      5                                          2       5      5                                               7      7      L                                           9       9                                                @      @                                                  HM      HM                                                PM      PM                                                XM      XM                                                 `M      `M      P                                        O      O      P                                           P       P                                               Q      Q                                                  Q`     Q      H                                                  S      (                                                   T                                                         X      +                             PK     Y\: r   r    x86_64-linux/sdbm.sonu ȯ        ELF          >          @       j          @ 8 	 @                                 Y      Y                    `]      `]      `]                                x]      x]      x]      0      0                   8      8      8      $       $                    Y      Y      Y                             Std   Y      Y      Y                             Ptd   L      L      L                         Qtd                                                  Rtd   `]      `]      `]                                  GNU GuF}WC^fB       :         A$ 	:   >   E   BE|Ϲ=%2?ѣnVqX?~G*ŤZx|[!y                                                  (                                                                                                                                 	                                          5                                                                 u                                          Z                                           a                                          ]                                           L                     U                      i                                                                P                     (                                                                                                           p                      .                                           h                     >                     #                                          k                                                                u                                                                                    =                                          ,                                                                                                           F   "                   @                                          1                                              a                   b                   &      3            $             `      b                  p%      5            '                 D                a                   &      2           ,                 %                  '             w     #      r       __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize read lseek nullitem memcmp memcpy sdbm_prep __fxstat free __errno_location __stack_chk_fail sdbm_open strlen sdbm_close sdbm_firstkey sdbm_nextkey sdbm_hash sdbm_fetch sdbm_delete write sdbm_store rb_check_type rb_raise rb_hash_new rb_tainted_str_new rb_hash_aset rb_ary_new rb_assoc_new rb_ary_push rb_string_value rb_iterate rb_intern rb_funcall rb_hash_delete_if rb_yield rb_block_given_p rb_ary_new2 rb_warn rb_eArgError rb_scan_args rb_fix2int rb_check_safe_obj ruby_xmalloc rb_num2int rb_sys_fail rb_data_object_alloc rb_ensure rb_secure rb_error_frozen rb_str_dup rb_protect rb_jump_tag rb_eIndexError Init_sdbm rb_cObject rb_define_class rb_eStandardError rb_mEnumerable rb_include_module rb_define_alloc_func rb_define_singleton_method rb_define_method libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 GLIBC_2.14 GLIBC_2.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                                ^         ui	                            ii        ui	         `]             p      h]             0      p]             p]      _         >           _                    _                    _                    _                    _         (           _         0           _         1           _         2           _         4           _         5           `                     `                    (`                    0`                    8`                    @`                    H`         	           P`         
           X`         E           ``         ?           h`                    p`                    x`                    `                    `                    `                    `                    `                    `                    `         F           `                    `                    `         @           `                    `                    `                    `                    `                    `                     a                    a                    a                    a                      a         G           (a         !           0a         "           8a         #           @a         $           Ha         %           Pa         &           Xa         '           `a         <           ha         C           pa         )           xa         *           a         =           a         +           a         ,           a         -           a         .           a         /           a         3           a         D           a         5           a         6           a         7           a         8           a         9           HHiJ  HtH             5J  %J   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   h2   h3   h4   h5   h6   h7   qh8   ah9   Q%F  D  %F  D  %F  D  %F  D  %F  D  %F  D  %F  D  %F  D  %F  D  %F  D  %F  D  %F  D  %F  D  %F  D  %}F  D  %uF  D  %mF  D  %eF  D  %]F  D  %UF  D  %MF  D  %EF  D  %=F  D  %5F  D  %-F  D  %%F  D  %F  D  %F  D  %F  D  %F  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %}E  D  %uE  D  %mE  D  %eE  D  %]E  D  %UE  D  %ME  D  %EE  D  %=E  D  %5E  D  %-E  D  %%E  D  H=!E  HE  H9tHB  Ht	        H=D  H5D  H)HHH?HHtHB  HtfD      =D   u+UH=B   HtH=@  dD  ]     w    1f wfѸ   ftYwHGf HOf9|?   ~#5D  89'D@fD9|A9DHٸ    1ff.     fAWHP  IAVAUE1ATU1SHHD$1H    HE1   fD  Ht$A?   >H   MH  HLH?H?H4H=HÁ  H)ID AP  H)skHDAT$HNlhM9o  AMI]M  IIHMMIIM;H  tLA?1HH8IcH*  HH!Mo   IG I9o@uH[]A\A]A^A_ MgHIP1HHLH
1H)IGH       IǇ@      HA{Hx.A   LHxLtIo@w 1mHcH*  HH!Cf.     UHoHSHH   fD  D 9   HcȺ   H4	~T5HDM HH)Hu}HC({C0    HpHs(H9C@tH
1Hx_Hs({Hs@   HH~BHt6C0SHC0f`H	?  HRHtH[]    H>  KHHRH[]ff.     @ AWAVAUATUSH~}LcHT$IM      Hl6f     AD]HH9tAIT] A)HD9uH|$LLNuHD[]A\A]A^A_     E1ff.     AUATIUHS   HL/fE~Bo)Ӆu.IEf\E L, D)Eu9fB\-fE H[]A\A] HcHcDD$H5DD$fD  HcIcLHD  ATUSH/A   HHE1   UI9   LcЃ   NDSLIRHIHSLLHH)Bc)t,HH)HfD  AAHH9uJT)IJLSf.     BHfBH9uD#AA   fD#[D]A\    A   PAVIAUIP  ATAUSH   dH%(   H$   1HH  @    H@     H@(    @0    @   DL1BC   DL1(   Hƿ      HD$01ҹ   HC@HHHHC1HH  HSHHHP  H   HHH$   dH3%(   HuTHĠ   []A\A]A^    4D  ;	{H1D      Nff.      AWAVAUATUSHt$H   ? H   ALxHC<?mIH   HHHM0IK<<H .dirH@ T$LDHH.pagC LIHL[]A\A]A^A_    E1         SHtH?{H[     [ff.     USHH   HGH    H11HǇ@      HoHHP1HHH)   H{Hx>{   HvHx)HC@    HHC(    C0    H[]@ HY9  KHPH H[]        H.9  HPH H[]     HtBfH    H8  HPH Hff.      t(FHL1fD  HHi3  WHH9u1ff.     fAUATIUSHHuHHHt@HDHjHHuKHL8  KHHRH[]A\A]fD  H$8      HHRH[]A\A]@ sHt8LkHDHL&t"HHT HDHTFHL)fD  H7  HR뢐AVHAUIATUS   HH   ouzIDL|HHtMLsHDLLt_Hs@{1H
Hx {   LHx[]A\A]A^ÃKD      fD  Ɛ{    ff.      AWAVAUATLgHUSHHh  Ht$L$P  Lt$PT$HdH%(   H$X  1HP  D$L
   HD$8HGPHD$@   LLHk HHI$    Ht$8L}HF    H|$@HHLH)   H   LH$P  f   ImL|$(   H\$0ILIDHD$ fMIOD)N,LHȉHL)HL$T$LHD$(AIET$HL$LI^AWL;|$ uIH\$0Hk L}HD${H!L	L;  Hs@1H
H  {   LH  Hk@H{PILHLI$H)I  H)΁   H@  HLC;MIhI  IIHMIIHIHL$IH;H  tQ1LLD$ LL$HP  ;HP     eH4  HL$;LD$ LL$HH  HH?H4HŁ  H)LH?H=I H)   +P  HCI9|
H   HC1L]H   ;HP     H   HKH   ~ALt$HT	)ЍV9   HC Hs1ɋ{HPHT$H	1HLqHC Hs@HKH
Hx;{   L3Hx&l$L,   H5G     D  1H$X  dH3%(   uJHh  []A\A]A^A_ÐH1H
bHxŋ{   LHf   @ AWAVAUATIUDSH(Hu!HHt_   G4A  v*%    H([]A\A]A^A_f     IDIDL$LL$VHHHD$  DL$HEHL$HD$At^DUHEfE~jDLDLD$H}HDT$D$(      \fD  k    A DLHDUHL$EѸ   E   CT)AV9}Ht$DHL$L$tEDLH}HL3Hu@}1H
Hx}   HuHHfMfD$DL$LD$MHEHBH`S"   H.HC HtHx [HD     [f     PXH5  1HH=
3  %D  AV"   AUATUSHHC H~   L`Mtu\LIQHHHtNfD  HHLHcHHcHILLH;L#HHHu[L]A\A]A^15D  AWAVAUATUSHH"   HIHC Ht}L`MttLHHHtOHHLbHcHIIIcLHHLHLmHHHuHL[]A\A]A^A_1yf     S"   H^HC HtFHXHt= xt1[ø   [f     HHt HHu11     AT"   USHHk Ht[LeMtRHcE ~[HD ]A\    LhHt#1ېLuHuHcHD ] []A\ø   11AV"   AUATUSHgHC H   L`Mt}LIHHHtVfD  HHLHcHWHcHIILHnLHLHHHu[L]A\A]A^1ff.     fU"   SHHHC HtXHXHtOHH7Ht0fHHHcHHHOH'HuHH[]1AU"   SHH)HC HtMHXHtDbHHHt%fHcH5HHHHuHH[]1ff.     ATUSHHH|$Ht$HD$"   HL`hHC Ht)HxHt LHHH[]HA\1PSHHH|$Ht$u"   H(HC HtjHXHtaHHt?f     HHHL$HcH;QuHqHtHHuH1[fH   [1ff.      ATUSHHH|$Ht$"   HuHC H   HhHt{HHIHtC@ HLHHL$HcH;QuHqHt$HHIHuH   []A\ IcH-H[]A\1ff.     fSHHH^  H=   H[ff.     fSHH=  LH11H[1zf.     H1HHD  S"   H>HC HtVHxHtMHt>fHcHUH"   H HC HtHxHtHuH[1     U"   HSHHE HttHXHtkHOHtTf.     HHHcHH"   HeHE Ht HXHtHHuHH[]15D  AV"   AUIATUSIE H   HhH   HIHHt|f.     HLHbHcLHIHcLHHHH"   LIE Ht(HhHtHIIHHu[L]A\A]A^1[ff.     AUIATUSHHH|$Ht$qHD$"   LL`HhIE HteHxHt\LHt&HcH+HHH[]A\A]f.     HutHcLHH1f   1@AUHcATIIUSHHHE~/AELlH3   L1HHH/L9uHH[]A\A]ff.     1     AVHcAUIATUHSHI;   4  "   LIE H  HhH  H\IHHuG   @ "   LIE H   HhH   H9IHH   HLHHcHHcLHsHHHH-HyHLi1H=  R~4EHlfD  H3   L1HzLHH9u[L]A\A]A^1H%  H5  H81ff.     fS"   HnH[ HtH{HtHC       [1AATUSHH9  H dH%(   HD$1Hl$LD$H   H|$H   @  AHH|$,E   HD$1Ҿ   HxHH      HC Hh HHL$dH3%(      H []A\f.     HAH|$fD  HA  rH|$HD$DB   HxHHd>HD$11HxHH@Au   KfkAHD$Hx@H   11ff.     ATHs   I1UH1SLHH1HtuH[]A\       H[]A\ H=#  HH[H]A\C SHHHtH[!SH   uHtHu[H=  ff.      AW1AVAUATUSHH"   HLc M   I\$H   HHIHtqHHIcHIHT${HT$LIHchHLHIwA$xA$HLL[]A\A]A^A__    H   []A\A]A^A_1ff.     fAWAVAUIATUSHXdH%(   HD$H1LD$<    I1"   LtIm H  H]H  E E H߉D$,IIAH  HD$<HD$ GfD  "   LIm H  H]Hw  HIIAH   DLHLD$H    L!H	HIFLD$IcHT$LHD$HT$H|$HD$@HcH|$@ILHHT$ H=9   HyT$<u!H%Ht$@L( ID$HT$@E1HT$H~`f     ID$ H|$JHD$@8HD$@HH    L!L@@H	LHI+uLID$II9||$<uP\$,~)É] H\$HdH3%(   Lu+HX[]A\A]A^A_1{H=!  H5
  1A|ff.     AV1AUATUSHHHt$AH|$gHD$H߾"   LhD`H[ H   HkH   LLHoHtBHcHLLHIuUxHL[]A\A]A^    A   tH|$HI[]LA\A]A^1eH=x   H5e	  1f.     AVAUATUHSHHt$H$H   1#H|$IHAHD$"   HHXD`H$LhDpHE H   HxHt LMHA   Lt$8t2H=  H5  1D  H$HH[]A\A]A^@ 11HHH[]A\A]A^1?ff.     @ AT1UHS."   HLe MtYI\$HtOA$@ HHEuHHuA$    H[]A\H=  H5  11     U1HSHHYHHH   H=@HH[]fD  UH	   SHHFH{~HC HHPH0H   []H  H5J  H81H     UHH  SH(dH%(   HD$1HL$LD$[HT$H1Ht$gHŃtHT$dH3%(   Hu3H([]D  HuօuHj  H5  H81D@ HH  H=X  H0H=  H\  H  H0H=F  H7  H  H0(H=)  H5J%H=  HRH5E  fH=  HH5+  7H=  1H'H5  H=  1HKH5  H=     HH5  H=  HMH5  H=b     HH5  H=C     HH5  H=$     HPH5  dH=  HAH5k  EH=  H"H5T  &H=  HH5=  H=  HTH5%  H=  1HXH5  H=m  1H<H5  H=Q  1HH5  H=5  1HH5  xH=  1HH5  \H=  1H|H5  @H=  1HH5  $H=  1HTH5{  H=  1HH5d  H=  1HH5O  H=q     HH56  H=R  1HaH5!  H=6  1HEH5  yH=  1HyH5  ]H=  1HH5  AH=  1HH5  %H=     HH5  H=     HH5  H=     HH5  H=i     HuH5s  H=J     HVH5]  H=+     HH5F  kH=     HH5  LH=     HiH5  -H=  1HH5  H=  1HH5  H HH                   sdbm: cannot insert after SPLTMAX attempts.
                                                               ?                                                   ?                                           ?                                   ?        closed SDBM file each_pair 11 SDBM sdbm_delete failed sdbm_store failed pair must be [key, value] key not found SDBMError open initialize close closed? [] fetch []= store index indexes indices select values_at length size empty? each each_value each_key keys values shift delete delete_if reject! reject clear invert update replace include? has_key? member? has_value? to_a to_hash   wrong number of arguments (%d for 0)    SDBM#select(index..) is deprecated; use SDBM#values_at  ;  8     `  (  @<          PD  Pt      $  d  |  P  0      p    0  P   <    0    p$  P  p|      `   <  X  p  `       8	  L	  	   	  	  	  (
  <
   
  @
  
  p  l       L  t  0               zR x  $         FJw ?:*3$"       D   H             \   s       H   p      BLB E(A0C8DP
8C0A(B BBBD0          AEG 
AAHVAAH      \    BBB B(A0A8DPl
8D0A(B BBBI 8   <      BBD D(I@y
(A ABBD  ,   x      BAA 
DBD   @     r   FEJ D(C0G
0A(A BBBHH         FBB B(A0A8DP
8D0A(B BBBH    8  5    E[
HL <   X      EAD 
AAIV
AAH]AA     d2    T]      3       L         FDG A(D0E
(A ABBG]
(A ABBE   <     H    HHH C(A0z
(C BBBA   L   T     BBB B(E0A8J
8A0A(B BBBB   L        FBB B(D0D8D`B
8C0A(B BBBJ          (7    E\
OF      H    AAM  <   0  L    FGB A(A0
(D BBBA   H   p      FBB B(A0A8G@
8D0A(B BBBA       0h    Ej
AF
J  4     |    FFA c
FBHl
ABA<         FGB A(A0
(D BBBA   (   X  D    EFG `
DAA (     t    EFG U
DAA 0     p    FAA G0O
 DAEA (     (    EG ~
CCD
FA@         FAA G0
 FABDO
 AABA     T  8#    E]      p  L&    EZ        `    HK      hx    Ek
A   (         EID |
DAA <     <    FGE A(A0
(D BBBA   8   0      BEA A(G@\
(D ABBK    l  P       4     Ld    FEG A(G0@(D ABB            <        FEE A(D0B
(D BBBA       ?    Er
A0   (     FAA N@
 AABK    \  P       @   p  \}    FMH j
ABHI
ABDNHB            EU        2    Ad
A`         FDB B(A0A8GP
8G0A(B BBBLD
8F0A(B BBBA L   P	  Ld   FBB E(A0A8D
8A0A(B BBBA   T   	  l   FDB A(A0G@
0D(A BBBH]
0D(A EBBAT   	  $   FBB A(D0D@
0D(A BBBEV
0D(A BBBA,   P
      FCD [
ABA   $   
  <:    EFG bDA (   
  TX    EIG c
FAA  (   
      EKF@R
AAF          H                    GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             p      0      p]             O             ^             n             y                                                                 H             I             `]                           h]                    o    `             	                   
                                   `             p                                                     P      	              o    (      o           o          o                                                                                                                                                                                   x]                                                                                          0      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                                                                            GA$3a1 H      I               GA$3p1067        I                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY           .               GA+GLIBCXX_ASSERTIONS   sdbm.so-1.8.7-16.el8.x86_64.debug   a/7zXZ  ִF !   t/] ?Eh=ڊ2N4 ܠ"''	AA"'w,'t7-iX=S粝͸b~ͯ4LTvJҊ{0g8=`st::j˪ݛ
|QX4~NU[Ū,Be}*^0x )(1F(E6Y88csnD:xb$2|S0Nq/ .2oz$x#pl^dQi@!u|
h8^D:Ds<b;=W;XބƙG5ȸ<ěϱYdH.ZoF,>KU4hlE=;?t($z~(=S^	ů΄V0dWo3.́CbblWꙌfْtAT'Pƺ^F#P0cVg^ɧ:^o-cx'}y{nOd].,$R+|HgV/x}# QUK0 [8tͳoU0vOևtDHУgWDeU-4I	Tc0SXεj96dOc5jGT#lYPS.Hhtk(JC̀'Oh<ɴoNþAGg0N3h"B4wQBp)]BX6o5nݖ$&ol_fen#P$[=n@)bͲIGJOͥGzۢrwI!'X`Qt!רC07!NIF4Хϴd/rnU,:)j?Ig1-O2dX#IT=4EUp.'0WW}3c
ٴ[#%ҫV"9ޮTaA<P˕Cy,YX(Tq+Ӣ''7hCudwZG#k~&St5HQZj\:SڿValQߌ㲣J~9UԆ 1`DİT5,IXRiQ$	6M
8}mכP_҆QY=m_wd݂[v	k(^i;ɬJWecBD0g.~=IE̝R}"r1!;ߜǷ^eE+0 Ftpi_r/s(PWtK;u}@X署0f~    	 
+  t.̱g    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                               8      8      $                                 o       `      `      d                             (                                                   0             	      	                                   8   o                                               E   o       (      (      `                            T                         P                           ^      B                   p                          h             H      H                                    c             p      p                                  n                                                       w                         ,                             }             I      I                                                 I      I                                                  L      L                                                N      N                                                Y      Y                                                  `]      `]                                                h]      h]                                                p]      p]                                                 x]      x]      0                                        _      _      X                                           `       `                                               a      a      0                                             b`     a      H                                                  0d      (                                                   Xd      \                                                   i      +                             PK     Y\}=      x86_64-linux/zlib.sonu ȯ        ELF          >    &      @       @          @ 8 	 @                                                                                   @                                      @      @                   8      8      8      $       $                    ؎      ؎      ؎                             Std   ؎      ؎      ؎                             Ptd   xw      xw      xw                         Qtd                                                  Rtd                     @      @                      GNU !A?A$       c         @  c   e   f   BE|qX)hV                                                 V                                           1                                          c                                                                                                           D                                                               V                                                                c                      l                                                                &                     !                     y                                                                                                                                   8                                                               K                     B                     A                                                               ,                                          3                                          r                                                                                    s                     $                                            U                                           \                     c                                                                                                         .                                                               6                                          -                     c                     t                     w                                                                                                                                                    O                                                                                                           	                     f                                                                                     :                     6                                                               n                      U                                          ,                                                                                                           F   "                                                              4                                           N                         p                                     p                  0b             __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_check_type rb_cString rb_str_new rb_str_resize rb_exc_new2 rb_exc_raise rb_sys_fail __snprintf_chk zError rb_str_substr memmove rb_scan_args rb_fix2int inflateInit2_ __stack_chk_fail rb_ensure rb_warning ruby_xmalloc free rb_gc_mark rb_data_object_alloc crc32 memcpy rb_str_buf_new rb_str_buf_cat time deflateInit2_ rb_uint2inum rb_class_new_instance rb_block_given_p rb_yield rb_string_value inflateInit_ deflateInit_ get_crc_table rb_ary_new2 rb_ary_push rb_num2ulong adler32 zlibVersion rb_str_new2 stderr __fprintf_chk rb_raise rb_num2int rb_str_dup rb_int2inum rb_funcall rb_time_new inflateSetDictionary inflateSyncPoint deflateSetDictionary deflateCopy inflateSync rb_thread_schedule deflateParams rb_eArgError rb_rs memchr memcmp rb_eRuntimeError rb_ary_new rb_lastline_set rb_eEOFError rb_respond_to rb_str_to_str rb_Integer rb_big2ulong rb_check_safe_obj rb_file_open rb_obj_as_string Init_zlib rb_define_module rb_eStandardError rb_define_class_under rb_define_module_function rb_define_const rb_cObject rb_undef_alloc_func rb_define_method rb_define_singleton_method rb_define_alloc_func rb_intern rb_mEnumerable rb_include_module rb_io_addstr rb_io_printf rb_io_print rb_io_puts inflateReset inflateEnd inflate deflateReset deflateEnd deflate libruby.so.1.8 libz.so.1 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.14 GLIBC_2.4 GLIBC_2.2.5 GLIBC_2.3.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                                                                                   ii        ui	        ti	                      '      Ȝ             @'      М             М               P                    5                    
                                         =                               X                    `                    h                    p                    x                                                                                         &                    /                    1                    8                    E                    M           ȟ         Q           П         X           ؟         Y                    [                    ]                    b                                                    (                    0                    8                    @                    H         	           P                    X                    `                    h                    p                    x                                                                                                                                                                                                         Ƞ         !           Р         "           ؠ         #                    $                    %                    '                    (                     )                    *                    +                    ,                     -           (         .           0         0           8         1           @         2           H         3           P         4           X         6           `         7           h         9           p         :           x         ;                    <                    >                    ?                    @                    A                    B                    C                    D                    F           ȡ         G           С         H           ء         I                    J                    K                    L                    N                     O                    R                    S                    T                     U           (         V           0         W           8         Z           @         \           H         ]           P         ^           X         _           `         `           h         a           HHY  HtH             5  %   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   h2   h3   h4   h5   h6   h7   qh8   ah9   Qh:   Ah;   1h<   !h=   h>   h?   h@   hA   hB   hC   hD   hE   hF   hG   qhH   ahI   QhJ   A%}  D  %}  D  %}  D  %}  D  %}  D  %}  D  %}  D  %}  D  %}  D  %}  D  %}  D  %}  D  %}  D  %}  D  %}}  D  %u}  D  %m}  D  %e}  D  %]}  D  %U}  D  %M}  D  %E}  D  %=}  D  %5}  D  %-}  D  %%}  D  %}  D  %}  D  %}  D  %}  D  %|  D  %|  D  %|  D  %|  D  %|  D  %|  D  %|  D  %|  D  %|  D  %|  D  %|  D  %|  D  %|  D  %|  D  %|  D  %|  D  %}|  D  %u|  D  %m|  D  %e|  D  %]|  D  %U|  D  %M|  D  %E|  D  %=|  D  %5|  D  %-|  D  %%|  D  %|  D  %|  D  %|  D  %|  D  %{  D  %{  D  %{  D  %{  D  %{  D  %{  D  %{  D  %{  D  %{  D  %{  D  %{  D  %{  D  %{  D  H={  H{  H9tHnx  Ht	        H=i{  H5b{  H)HHH?HHtHx  HtfD      =%{   u+UH=x   HtH=nu  dz  ]     w    S"   HHC [H   H    S"   H~HC [ Hff.     S"   HNHC HP   Ht	HcBHD [U"   SHHHk HEHtKH4w  HHPHE   Ht HH	uHtH   H	H[]fD  11D  USHHHoHtMHwHAHv  H HEHC   HHC    HC8    C@    H[]f.     11'HfS"   H.H{ uHt HH	uHtH   H	[ff.     USH   H$ H   H$ HdH%(   H$   1H   S   HK  HcH>H=(y  k HH=x  TH=x  FH=x  8H=x  *H=x  HrH=x  HPALE  VH           1H=x  ZHY^H%f     SHH H   u0H   HC   HC    HC8    C@    HC   [HsPATUHcSH9o~sHHH1RHSIHt  H)H ID$HCHSHxH4/DHCHSHHH@)HѺ @  = @  HK8GC@L[]A\ []A\G    USHHD  HdH%(   HD$1H4"   HH<$Hk    Ht
   H<$H} p   HdD  uHM HHT$dH3%(   uH[]HuP\    Ht@ HHHHH<   H=  Ht@ HHHHH   H=5*  SHtTHu-H   HC   H{ PuHH       [D  H=H  1H     1H=H     [HsPpBfHD@ SHHH{[D  SHH   H   H   H{{H{[qAUIATIUH   SHHHxHHH     HHHǀ       1H)   HHH  L   11HHH    1HC`H HC   HC    HC   HChHCp    HCP    HC     C(    HC8    C@    Hǃ      ǃ       Hǃ       ǃ      Hǃ      Hǃ      L   H   HHǃ       H[]A\A]f.     HEH5n  f     HUH5n  yf     ATIUH   S,HHxHHH     HHHǀ       1H)   HHHw
  2HH5H    HC   HC    HC   HS`HshHCp    HCP    HC     C(    HC8    C@    L   []A\ H5m   H5m  ATIUHcSHHHtiHCH4(H9w|Cs@)9ֺ    BʉK@HGHLH5HCHkHkHhHk8[]A\@ C@    H{HCfHHLHCHfHCHkHPC@    HS8H@    []A\fUSHH(dH%(   HD$1H   @H   tH   H         t	҉D$   H߈T$Ht$
   D$fL$D$@l$H   Ht$HPHpH   H5C  HzH   Ht$HPHpH]   H5C  HIH HD$dH3%(   u H([]fD  1H    UHHM>  SH(dH%(   HD$1HLL$LD$"   H-H|$H] Ht
   H|$uH|$   E1Ht
   H|$K   Ajp   H{ H=  A   PZYu)H$HH   HHT$dH3%(   uH([]HsP AVAUE1ATUSHHF=  H0dH%(   HD$(1HL$HHD$(P1LL$(LD$ ^"   _HH|$ Hk Ht
   H|$ aAH|$A   Ht
   H|$9AH|$A   Ht
   H|$AH|$Ht
   H|$HV<  jpDH} P   EEZYu%HM HHT$(dH3%(   uH0[]A\A]A^HuP1ff.     S"   HHC [x@S6Hu
H[D  H=!k  HH[H;&  fD  SH   Ht$H|$H\$dH%(   H$   1HH{ p   HD$pHH5?;  HD$xHg  HD$    HD$   HD$     HD$(   HǄ$       HD$`    HD$0    D$8    HD$H    D$P    H$      HD$HH$   HH=0  HL$H$   H$   u1Ht)HT$uHtH   H	f.     H$   dH3%(   u	H   [Ht$`S UH:  SH   dH%(   H$   1HLD$HtH|$Ht
   H|$UHH\$H{ p   HdH9  HD$    HD$pHXHD$xHLf  HD$   HD$     HD$(   HǄ$       HD$`    HD$0    D$8    HD$H    D$P    H$      H$HH$   H?H=  HL$H$   H$   u)Ht!H$uHtH   H	 H$   dH3%(   u
H   []>Ht$`fATUSc   HL   H@ H;HHHL9uH[]A\@ ATUHH58  SH dH%(   HD$1H\$LD$HH|$HuqH|$tQ111IH|$tAHHD$LHPHpHtHL$dH3%(   u.H []A\ E1L11H    ;I!Hf  0Hf   HHuHtH   H HHH H   PH<  tt
HD  H<  Hf  H6     H81H     SHtH|c  H9   tH{H[fHIf  Hz<     H6  H81|f.     SHuH[jf.     H[RfS"   HBHC  t[H=ph  H536  1BfSHHHtHHH[ HHH[ff.     H   H HEHff.     @ HSHt1Hx HHHfD  H#Hc   HHD fHHc   HHD fHH   H    USHHHHtn   HH[]fD  c   HH[] HsH   HuHÐHxuHtH   HH3H   HuHÐH8uHtH   HSHHx0H@HtHxH9A      H   H5`f  H1H.111CHǃ       H      [f.     HsHc   H USHQHH   H   Hǃ      Hǃ      HHǃ      H[] HHx0HfD  HHxHH+xHfHH   H H1H   HQS"   HHC  t[H=he  H52  1fH   H HEHff.     @ HHc@xHHD D  HsH{   HÐATUHSP
   HH HH{IHt;9C@uH[]A\fD  HcHsHSHCHBDc@HC8H[]A\Hc1HC    HPHCDc@HS8H@    H[]A\ff.      HH   HÐHH   H HcHxHHfD  HCHx0HfD  ATUHSHHdH%(   HD$1	H$IHtHH	بtO    HH$I|$ HPHp
u=HL$dH3%(   Hu6H[]A\f.     HtH%   H	E It$Pm     SfHx Hztu1[D     [HsP&fD  ATUHSHHdH%(   HD$1	H$IHtHH	بtO    HH$I|$ HPHpu=HL$dH3%(   Hu6H[]A\f.     HtH%   H	E It$Pm     ATIUH"   S8HI\$ KHp H{ HuCHEHtHHCHEHtHHCHEHCHE HL[]A\1ff.     H1     H5	a  tHtHǾ   HD$HD$Hft\ATUSHHtHH[]A\fD  HHIzHLHE HHE H@    []A\    ff.     @ UHcSHHdH%(   HD$1fH$HpH{HP[HCHtH9h}3H   H$Hu1HL$dH3%(   uH[]@    ff.     HHtWUSHHPH9H   H[]     HHxH)H4MH} HwHH)[]    H        AT   USHH@t7HCH{   H@D hHC0VL9   u5CHH9u[]A\H=^  H5,  H=^  H52  1H=^  H52  1 Ht	@HGt   fD  HG   Hff.     fS"   H.H[ HHHu3H{ u,@t0H{HtuHtH   [@    [ÐHfD  AUATUHSHHt$H@u	HusH|$HD$HhL`HCH~   u1H[]A\A]D  k(H{ Lc xŅ   tϋs(H{ HsPBfHD$uHxH %   H	E gf.     HPH@H{ HS C(AŅt1HC   Rs(H{ HsPD     HCLkLHp+s(LL   
fS(Hs H{   fD  USHHHHt}HsHGHH)H=?  GH  ~NH @  HH= @  HNHHSHsk@HrHs8H[]    C@ @            @    1HC    HPHCC@   HS8H@    H[]f.     UHSH.H@   HuhHHKH   HSH9QtvHqH~IHCH@@(C@HCtHC8C@   H   []@ @tE ?uH} ~HEHK(Hu    HhHSHKu H Kf     AVAUAATUSHHHu   H{HCk@HPHD$HS HPS(   Ls $D  E   C@   Hk@HD$H   DLP+k@HkAAuHS(HC   HHHtPHs H{UHD$   H[]A\A]A^    At_AuYS@tRS(HHC   uH[]A\A]A^D  k@H'  G(    HG Hk@ S(HC   uHsPDHHs H{f     SHHVfD  H   DHD$HD$HtDHD$Hx ~HT$HD$   HHRHp)HCH	tHCH[ÐuH=X  H5&  1fD  SHG   HHPHpHH߹   1H5&  H[SHG   HHPHpHH[vfD  UHSH.1ҹ   H5w&  HHUH=Ht!HH	uHtHU    H	H[]ff.     fAUIATAHUHSHdH%(   HD$1DHLHHP%  1H<$Htm
   SH<$uYHHt$HH	uHtHU    H	 H\$dH3%(   u(H[]A\A]D     1H5Y%  H:c AVAUIATUHSIHt
   HH1It
   LL1LMl$    H5$  Lu,L5*  f1LfLLt݅u[   ]A\A]A^It$Pff.     @ LcHJLL9	)ȉ@ UIHSHD)HIqH?LHE     H[]@ USHHHuHhHtH{ u@t^H11[]G    HH   H   HHO@uHtHM    HH[]fD  H H11[]ATAUS      HHHGu&HcH9|
!fH9k}HHtHCHtYDH&H   H   HH@uHtHM    H[]A\fD  [1]1A\; @   uH6HQ  H5"  H81Jf.     H   HHtH@ H%  HH     SHfD  HHHu[     ATIUSHHdH%(   HD$17HLHHW!  1H<$HtD@u.ƅxBHKH\$dH3%(   u%H[]A\f    HxHP  H5]!  H81    ATUSH Ht HH{ ut[]A\    HCH   L   H@1fD  HH9s~&<0
tH[LHH]A\fD  HLHHjH{ t!H(H{ utk    HCH@y AWAVAUATIUHSH(dH%(   HD$1HÅ  H#O  H HD$Hl$H  HD$Hx    HD$D$    LpHD$LhLcM9   @ HhLcM9}wtM~   DHcHH|$dH3<%(   H  H([]A\A]A^A_f.     HA   L5  +D$   lfD  HCLLxD  L9~"   HHCIM)L@MǋT$uHD$L9pt
L9h  LcA6LLH)H
HHtrL)HIt6LLHH$t H$HLyL9~lfD     H?HŋD$H8 Il$fD  HL$H  1LhHD$HH|$   Hl$H H Hx U   HFHM  H5  H81f     AUAATIUHSHH    HHHLDHuHH[]A\A]ff.     ATAUHSHD  HHHDHuH[]A\@ HHtHHD$HD$HfD  SHu H	L  H5  H81     HHUH[UHSHHt$Ht<H|$`HD$HPuH~HpHH[]f        1H5  mH[]fD  UHSHHHtHH	uHtH%   H	HH1HDHH[]f.     AUIATAHUSHH(dH%(   HD$1HL$LDHLD$H@  1u	HujH|$1Ht
   +H|$Ht$HHZHH	uHuGHL$dH3%(   uNH([]A\A]@ HD$uHtH %   H	u    HtH   H	$@ H 	     SHuHtH   H   H5L  H   1u[H   H5L  tH   H5sL  11[ATIUSH tGut/H   L5HLH   HH'H[]A\+ 벐SHHdH%(   HD$1 t_   1H5  HH   Hߋ   $C0D$H@H   HL$dH3%(   uH[f@ AUIATAHUHSHdH%(   HD$1DHLHH  1GH<$Ht]
   H<$*uIHH   H5J  yuEHT$dH3%(   HuKH[]A\A]       1H5  H     H   H5J  11	fPXH5  1HH=ZJ  5D  AUATIUSH  uPLHZH1LhHPHL=HtL)HHjH   HL[]A\A]pAUATIUSH:  uPLHHB1LhHPHLHtL)HHH   HL[]A\A] USHH  uPHHu&HǨt2mH   HH[]@ SH   HH[]fK@ AUATUSHdH%(   HD$1~^HHIHIH$H<$H$LHx?LHމHoHL$dH3%(   u#H[]A\A]HE  H5  H81L    H  PH  @USHHH      H5+H  Hǃ      Hǃ      HHǃ      uH[]    H5G  HH1[1]_ff.     @ S"   HnH{ u   [fD  S   [ff.     SH   H'H[fSHHHt$Ht=H|$HD$HPHH[    HpH߹   7H[Ð   1H59  H[    USHHHt$Ht$Hu	HuKE teHuHH[]D  H|$nHD$HHPHpHH[]    @uHtH%   H	@ HE tHEHtHPHpHHE   l USHHHt$Ht$Hu	HuSE t}HtgH|$HD$HHpHP(11_HH	ڃuH   H[]Ð@uHtH%   H	@ HfD  HHpE tHMHtHQHqHH$HE   H$l HsH   H	bf.     ATIUHoS1HdH%(   HD$19D  I$   H$HtUIT$HpHHZH$HPID$1HPH)HXHHtHL$dH3%(   uH[]A\H=eD  H5c  17fAVAUATIUH"   SI\$ p   H  H{ %.  H
   HH     HCH@8  x  P  P       P   ҃	   HLk
   LH   @	   @u[@      HCHtHx ~   11HF[L]A\A]A^f.     ǃ      {   HA  HCHH@D0AD  DL@bHHSHzH)HI5H   uHtH   AvLH^HSHzH)HHH   uHtH   uLcH=B  H5  1H=B  H5  1H=A  H5  1HsPH=A  H5^  1H=A  H5!  1H=A  H5  w    ATUSHIHt4u/t*H݃?uHuULHE[]A\HD HXH USHHdH%(   HD$1~HufHu=H5Ht$   HD$HHL$dH3%(   u6H[]D  t?uH{ ~HC 묐HH#HtHH=  H5  H81@AUH=  ATUSHH5U  HH]=  HH:HH5  HH~@  !Hr@  HH5  HY@  HU@  HH5  H4@  H8@  HH5  H@  H@  HH5w  H?  H?  HH5c  H?  H?  HH5O  H?  s1HHH5=  Hy?  $H߹HuH5(  	H߹HJH5  1H%HH5  H=  ڿH5   HHH=v  輿HH5  HL-;  H5  HIU HH1HH9H5  H   HH5  1HHH5  1HHH5  1HHH5s  H1HNH5e  r1HHFH5W  Z1HHH5E  B1HHH57  *1HHH5+  1HHH5  1HHH5
  1HHH5  ʿ1HHH5  貿1HHH5  蚿1HHH5  肿1HHH5  jHߺ   H5  Hߺ   H5  Hߺ   H5h  HHH5  H H5u  IHLH5LHH5M  ԾL   HH5=  蹾LHZH5  螾L   HH5  胾LHH5  hL   HH5  M   LH~H5  2HHH5     HH5  HHHH5HHDH5Q  ؽH   H9H5x  载H   HNH56  袽H   HH5J  臽1HH{H57  o   HHH5
  THߺ   H5  Hߺ   H5  ܾHߺ   H5  ȾHHH5  貾Hߺ   H5  螾Hߺ   H5
  芾Hߺ   H5
  vHߺ   H5
  bHߺ   H5
  NHߺ   H5
  :Hߺ   H5
  &Hߺ   H5
  Hߺ   H5
  	   H5
  HH=
  .H=
  H9  H=	  H9  H=
  H9  H=	  H9  IU HH5e
  He9  hH9  H5`
  HIOLH5?
  HH+9  6H9  LH5(
  H9  H9  LH5
  H8  LHH5
  H8  LHH5	  IμHH5  HH0	HmLH5	  Lv1LHH5	  ޺1LHH5	  ƺ1LH
H5	  论1LHH5~	  薺1LHZH5l	  ~1LH2H5\	  f1LHH5N	  N1HHH5>	  6H   HWH5*	  L   H,H5	   L   HH5	  L   HH5  ʹL1HH5  貹1LHFH5  蚹1LHH5  肹1HHH5  j1HHH5  R1LHH5  :L   H[H5Z  1HH#H5H  1LHH50  1HHH5  ׸1LHH5  迸LHH5  贸LH5z襹LHfH5  zLHH5  _L   HPH5  DL   HH5x  )H2  L   H5  H2  LH5G  H2  LH53  طH12  LH5  轷HHH5  買HH5X裸H   HH5  x1HHlH5  `1HHdH5  HHHH5  -1HHQH5  1HH	H5q  1HHaH5b  H   HH5Q  ʶHH+H5=  诶HH@H5'  蔶HHH5  yHHH5  ^HHH5  CHߺ   H5  ߷Hߺ   H5  ˷Hߺ   H5  跷Hߺ   H5  裷Hߺ   H5  菷Hߺ   H5  {Hߺ   H5  gHߺ   H5  SHߺ   H5  ?Hߺ   H5|  +Hߺ	   H5q  Hߺ   H5f  Hߺ   H5]  Hߺ   H5P  ۶Hߺ   H5D  ǶHHߺ  [H55  ]A\A]驶 HH   unknown zlib error %d: %s 01 1.2.11 12 04 02 zlib(finalizer): %s
 closed gzip stream stream is not ready footer is not found unexpected end of file negative length %d given 

 rs modified end of file reached header is already written rb wb not in gzip format unknown flags 0x%02x Zlib StreamEnd NeedDict DataError StreamError MemError BufError VersionError zlib_version adler32 crc32 crc_table 0.6.0 ZLIB_VERSION ZStream avail_out avail_out= avail_in total_in total_out data_type adler finished? stream_end? closed? ended? close end reset finish flush_next_in flush_next_out BINARY ASCII Deflate deflate initialize initialize_copy << flush params set_dictionary Inflate inflate sync sync_point? NO_COMPRESSION BEST_SPEED BEST_COMPRESSION DEFAULT_COMPRESSION FILTERED HUFFMAN_ONLY DEFAULT_STRATEGY MAX_WBITS DEF_MEM_LEVEL MAX_MEM_LEVEL NO_FLUSH SYNC_FLUSH FULL_FLUSH FINISH write read seek GzipFile NoFooter CRCError LengthError GzipWriter GzipReader wrap to_io crc mtime level os_code orig_name comment lineno lineno= mtime= orig_name= comment= eof eof? sync= pos tell open putc printf print puts rewind unused readchar each_byte ungetc gets readline each each_line readlines OS_CODE OS_MSDOS OS_AMIGA OS_VMS OS_UNIX OS_ATARI OS_OS2 OS_MACOS OS_TOPS20 OS_WIN32 OS_VMCMS OS_ZSYSTEM OS_CPM OS_QDOS OS_RISCOS OS_UNKNOWN    ȴִ޴y    attempt to close uninitialized zstream; ignored.        attempt to close unfinished zstream; reset forced.      the stream state was inconsistent.      the stream was freed prematurely.       Zlib::GzipWriter object must be closed explicitly.      invalid compressed data -- crc error    invalid compressed data -- length error deflateParams() returned Z_BUF_ERROR    wrong number of arguments (0 for 1)     unsupported compression method %d       multi-part gzip file is not supported   encrypted gzip file is not supported    ;  ~     @  X  Ht  x    (       X  Xx      ȴ    x(  <  P  l    H  h    X  h,  x@  8x  h  h  ȼ8  T  (t    8    H,	  X@	  hT	  l	  	  X	  	  	  
  (
  X4
  xL
  d
  |
  
  H
  
    ($  xL  d  |      (  X  x    HT  hl            @  p  X    X  (  XX  p    x  H  84    H      (  L    8    0  H  (d      X  T    (  h    8  HL  l  (        8T          ,  X`      (    4  h                      zR x  $      ȡ   FJw ?:*3$"       D   `             \   )    ER      x   ̫$    ER         0    Ej   (      {    EFG U
AAG (      Hn    AAG J
AAK      E    E   4   $     AAG L@I@@K@a@D@   \  P    AC
A   4   |  ح    BAD r
ABDAAB  (     0    EAN0
AAA      0            Ю0                 Eu
Ft
A     ,  H          @  D          T  @    EQ      p  D?    Eu   8     hF   BED I(D0'(A ABB        |                   (         BDI AB       8          0  4       4   D  0    BDD V
ABERAB (   |  0   AAG@
AAG4         EKD@H\PFHA@j
AAA X     T   FBE A(A0N`YhFpRhF`hHpQhA``
0A(A BBBA    <      ER      X  :    EU
FN $   x  m   EGN
AA   ,        EMGq
AAA   (     dL    FAA @AB  0         BAK D@~
 AABD    0            D            X  -    Hd    p  $X    Gc
Fc        dV    Ed
G     .    EL
OI      .    AW
A     ̸4    E_
DK      !    HX       *    Ha    8      HP    P  $    HP    h  ,    HP 0     4M    EAG _
DAGODA      P@    HV
B_        p@    HV
B_        v    Ep           HP $   (  M    EAD @AA   P  $    HM    h  ,    HQ      4    HP      <    HR      D.    AW
A     X!    HX      p    HM      x    HV @         FAD s
ABGd
ABAnAB      X      HV    p      HP          HM          HM 0         FAD G0o
 AABK       :    E]
FF
A  0   	      FAD G0o
 AABK ,   D	  @    FDI e
ABA      t	  >    D y 8   	  ȼa    FAA R
ABKmABH(   	      ADG0e
AAE 4   	  `h    JAF T
AAI_DA   ,   ,
      BFA C
ABA      \
  3    dN     t
   j    EN
EF
B 8   
  lj   FBA D(D@K
(A ABBF 4   
      AAG ]
AAHSAA   (     8    EDD w
FAE T   8  w   BBE A(A0G@
0A(A BBBHj
0A(A BBBF      $    AG e
AB      @    Ev        *    E`   $     c    EDD SAA8         FEG D(D@
(A ABBF <   P      FBE A(D0
(F BBBA   $     TL    YIJ ]AA <     |    AAG e
EAL|
DAGLEA 8         BDA 
ABGA
CDH      4  8    Ho    L  (    Eb   0   h      FDA I0e
 AABC 4     H    BAA a
ABHy
JBKH        BBB B(D0F8D`
8A0A(B BBBK 4      4U    FED D(D0t(D ABB (   X  \<    FDD jAB        p*    H a      @    Ez   0     j    ADD0{
AAJWAA $     V    EDG @DA8         FEG A(GP
(A ABBE    P      Q~
Aj,   p  T_    BDC D
ABH             EG p
AC 8         FEG D(D@
(A ABBH           AAM  8     p    FBD A(D0P
(D ABBA 8   X  p    FBD A(D0P
(D ABBA 4     l    EAG q
DAEP
DAC  8     H    BBA A(D@k
(A ABBA                         0   0  q    AAG E
AAHKFC   d  4    E\
GK          EX   0     i    AG g
AHU
ABWA   4     P    EAG0p
DAFc
DAH  (        EAG0o
AAB 0   8      BDE F0~
 AABA <   l  X   FBB D(I0
(D BBBK  (     ]    FAA 
ABF(         EAG0[
AAF      0    HO
A  8         FIA A(D0(I HBB                    GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     '      @'      М                                                                             @             O             Y             i             t                                                                 8             p                                        Ȝ                    o    `             @                   
                                                                           0             x                   	              o    (      o           o    T      o                                                                                                                                                                                                                                                                                         p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                                                                             0       @       P       `       p                                                                !      !       !      0!      @!      P!      `!      p!      !      !      !      !      !      !      !      !       "      "               GA$3a1 8      p               GA$3p1067  '      p                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY     '      '               GA+GLIBCXX_ASSERTIONS   zlib.so-1.8.7-16.el8.x86_64.debug   {!kb7zXZ  ִF !   t/"] ?Eh=ڊ2N`=n G6,~Xo/)PR2׋d?oܠ#ށ	a..A7	ؚ8ْKmfVzhǫaiALi @ze?]JP'^M9/{ug&"k3ː`A)!_ų'z?qbR6vɜL (t5m2e!׹ywo:՝wgD$穓&&FV{b_VsCA\oy1? ;ȣD,jG8t
vbR?K){[<CeOX^{I+Nt$ˬ$X8Kcgo8woA2@"<VDoyOQ@ԱOxesy9ǰV^7lTTCfn*DcEjWolsNŢ-fo2E5@uHh'=C՝coY,[K1 ÍXs_'4S`kA$Id II_+Gd7'gl\T]Nwm:ܚV(0{.]J70s)ӞR_dp?W3h7?JJU:JvyU?D;4Q/q|
$4%(ŒĪ5n#(
Ÿ1Ba*ngp /RZ"c޺Nzk};K=@vǘ馻b}DKO%R^DָZ*Dws[)z{ªqlyc 9*2ܼ.d<<ʎŊ2wX[FKh_<I;ﱕEؾrm*<c1|7Lnt 4Z5|E0DYhhjvwUQnT"e)*]2¨-
G^]D@فK]Rt'X3m[R_xa|JDC6nb⎏.q+5D5j%S"XAMEt׷IZxk7iԞ6pXq](#A5d?y;%х	0"v59\#3O/qA<	"̉f]fo]!?~TśDICS}Pdp~F0r;da2v=$,\'0//sY罎-6c'Ww}Iz/AՎe^]KBQS
oĘ#ubO}-,2fWiMFQY~jU1Eqz*a1|gOW$zh.'<G&H B҇7Z7nR}c8Z}[B"?h>( '8ޑޤ0R>ۭ&eXx_n'Jl~Z'(U^
اvI!?i4YG,!%4{6tjGQ*d_TܭTn@*.)"^Jw SwReB)^@@Ss%z	:'/-xx>[!&8^p?\m	ຏLm^jkd^?0F&g:3x*j㚶X	LS#6v\ۥOLHm%]XfکVў7̋R:q<GEȥr,AN5%`*?>:&~hh^)E`Ձ"ΉO<F<<F8n'<@%DG)-I'<<r	zߎn<"V5}~k6{CuW"qnA0)tYP.   pJCW E  zg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                   8      8      $                                 o       `      `      4                             (                         	                          0             @      @                                   8   o       T      T                                  E   o       (      (      P                            T             x      x                                 ^      B       0      0                                h             8      8                                    c             `      `                                  n              "       "                                  w             &      &      7I                             }             p      p                                                 p      p      `                                          xw      xw                                                x{      x{      \                                          ؎      ؎                                                                                                        Ȝ      Ȝ                                                М      М      H                                                       @                                        X      X                                                              p                                         p      p                                                   `     p      H                                                        (                                                         0                                                         +                             PK     Y\kBQ  Q    x86_64-linux/thread.sonu ȯ        ELF          >          @       XJ          @ 8 	 @                                 h:      h:                    8=      8=      8=                                 P=      P=      P=      0      0                   8      8      8      $       $                    H:      H:      H:                             Std   H:      H:      H:                             Ptd   0      0      0                         Qtd                                                  Rtd   8=      8=      8=                                  GNU WSAa +j)       2         @ @ 2   4       BE|qXO+                            ?                     M                                                                                                            U                      h                                           2                                           %                                                                S                                                                                     c                     C                                                                                                            z                                            x                     y                                                                                    4                                                                                    ^                                                                (                                                                                     ,                                                                 V                     F   "                                                             @    0A              S    XA              G    0A              m    )      X       __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_thread_critical rb_thread_current rb_check_type rb_thread_alive_p rb_ensure rb_yield ruby_xmalloc rb_thread_join rb_thread_wakeup_alive rb_thread_set_join rb_thread_schedule rb_thread_stop rb_marshal_load rb_ary_shift rb_num2ulong rb_eTypeError rb_raise rb_eArgError rb_data_object_alloc rb_gc_mark rb_intern rb_funcall rb_str_new2 rb_eThreadError rb_iterate rb_cFixnum rb_cFalseClass rb_cNilClass rb_cTrueClass rb_cSymbol __stack_chk_fail rb_uint2inum rb_ary_new rb_ary_push rb_ary_unshift rb_marshal_dump ruby_xfree rb_thread_kill Init_thread rb_cThread rb_define_singleton_method rb_cObject rb_define_class rb_define_alloc_func rb_define_method rb_alias libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 GLIBC_2.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                           6         ui	   X     ii   d      8=             0      @=                   H=             H=      ?                    ?                    ?                    ?                    ?                    ?                    ?                    ?                    ?                    ?         "           ?         %           ?         +           ?         ,           ?         .           ?         /           ?         0           @                     @                    (@                    0@         	           8@         
           @@                    H@                    P@                    X@                    `@                    h@                    p@                    x@                    @                    @                    @                    @                    @                    @                    @                    @                    @                    @                    @                     @         !           @         #           @         $           @         &           @         '            A         (           A         )           A         *           A         -            A         /           (A         1           HH.  HtH     5.  %.   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %},  D  %u,  D  %m,  D  %e,  D  %],  D  %U,  D  %M,  D  %E,  D  %=,  D  %5,  D  %-,  D  %%,  D  %,  D  %,  D  %,  D  %,  D  %+  D  %+  D  %+  D  %+  D  %+  D  %+  D  %+  D  %+  D  %+  D  %+  D  %+  D  H=+  H+  H9tH)  Ht	        H=y+  H5r+  H)HHH?HHtH)  HtfD      =5+   u+UH=)   HtH=6'  Id+  ]     w    HU)  8   ff.     f   fD  SHHHtH;uZ@ H;tHHQHu   [     HqHBHHkHz tHCHB   HS[fD  HKHH1S"   HnH[ H;Ht
HuOH   [D  1[ff.     S"   HHC H8Hu1[f.     +H¸   Hu1f.     ATUSHH-'  H;IE    HuL#E        []A\ HtHKHHH=A  f.     f.     S"   HNH{ eH[He'  H=n'     HHc    @ HHHH=h  s S"   HH{ H='  H[HS     9f     SHHHGHtGHPHWHSH0H@    HtHBHCHCH[HHCHCH[fD     Ht$9Ht$fATUSH0H{HIqH;H-G&  D  ;Ht/H;L9t*>  E     JH;E    HuL#[   ]A\f.     HHtJSH+fHCHkH:HBHS'HHtHuHBHH9SuHC    [ø        H? tSHfHH; u   [    fUSHH^HHt!HHtD  H;HH[HuHH[]f.     S"   HH$  Hs HH=UHc    'RH[ff.     fSHHHS   [ff.     AUATIUSH"   HBHIl$ uHtuHèun<tj ?	u`H{ ~qHHhEHHE HCH[ t!LlD  H3HH!I9uHL[]A\A]fD  H#  H5b  H81H$  H5g  H81h     SH   ^HH  H  H    HH@    H@    H@    H@     H@(    H@0    H@8    H@@    H@H    H@P    H@X    H@`    H@h    H@p    H@x    Hǀ       Hǀ       [off.     @ SH    HH  H   H     HH@    H@    H@    [D  SH(   >HH  Hm   H    HH@    H@    H@    H@     [ff.     fSHHt H;H[Hu[ff.     fSHH?H[Ht    H;H[Hu[ff.     fUHSHH](HtD  H;H[HuH]HHtfD  H;hH[HuH]hHtfD  H;HH[HuH[]     SHH6HH=gHoH=H  H{1H1#   [ff.     SHH=  |H1[H1ff.     H=M   USHHH/kH9uH{-HH[]H   H5B  H81ff.     S   H)H[@ USHHH-0   E    H9u-HgHuH[]     HH[]RH+   H5  E     H81 ATUHSH"   H dH%(   HD$1tLe    H   H   H      HCH9!  tDHHL$$HH=\H\$HT$dH3%(   H   H []A\f"   HH[ HHLHZH=>@ H	  H lf     H  H TH  H DH  H 4H  H $lff.     HHtHh  t
HD  HD$HD$H@ HH5  HHH=tHc    fHHt
   Hff.      U"   SHHH[ HH   HHvHH[]ff.     W    ATI"   UHSHCH[       I$HHH;HChHuHusHk(L%Hu1D  HHLHH=P[HH{h tHH[]HMH=  A\/    HHChHH  H5  H81ZH  H5  H81@U"   SHHIH[ H]H{`H{@`HHHH[]ff.     U"   SHHH[ HH   HHHH[]ff.     U"   SHHHk 1HH    HxHHH[]ff.     S"   H^H{ EH   HDH[ÐHHe  HHH=Hc    HuHf     HH@ H   Hf     HWhHtsHBHGhH;Wpt5HOxH   HHJHWxH   Ht	H;   w     HGp    fD  HHHHD$HD$H@    f     U"   HSH)H] H=HCpHt+HShHKxHHHSxHCh    HCp    Hǃ       H{HHHH[]ff.      S"   HH{ eH[S"   HH  Hs HLH=EHc       HtHHH[f.     AUIATUSH"   H"HMe 6HtiLH&I$   H9sHu$I$   LHL[]A\A]fD  HI$   Il$HH)D  HpHuH  H5  H81pAT"   USH{Lc I\$hHHtD  H3HH[HuI$   oHH[H   ]A\ UHSHHtfH_wHHuH} HtfD  H_WHHuH[]     UHSHH_Htf.     H;(H[HuH]HHtfD  H;H[HuH](HtfD  H;H[HuH}Hu2H}(Hu8%H}HHuXH}hHuxHH[]ff.     fUHSHHHt H;pH[HuH] HHuHH[]9f     UHSHH_Htf.     H;H[HuH]HHu_HH[]AVI"   AUIATUSTI] HhH   HtVH;   wMHkHL%(fD  H;   w1HHLHH=ozHH   HuH{hL*Hs(HH\H=@[L]A\A]A^@ H  S1H[H5  H8H  H=  H3vH5HHE  0H=9     H=H5  H=  1HH5q  H=  1HH5b  iH=  1HyH5N  MH=  1H}H56  1H=  1HQH5  H=  1HH5  H=r  1HH5  H3H=  nH5HH5  (H=)     H5H5x  H=
  1HH5i  }H=     HjH5  ^H=  1HH5o  BH=  1HH5]  &H3H=  H50HHv  qH=j     H.H5  H=K  1HH5  H=/  1HH5  H=  1HzH5  H=  1HH5  rH=  1HH5  VH=  HH5  7H=     HTH5z  H=n  |H=g  HmH=f  HHKH=A  OH=>  H@H=9  HHH=  "H=  HH=  HHH=  H=  HH=  HHH=  H=  HH=  HHH5  H=     HxH5  HHo  H=c  1H2H58  H=G  HH5%  H=(     HH5
  H=	  1HxH5  H=     HH5  mH=  H=  HH=  HHH=  H=  HH=  HHsH=e  wH=i  HhH=Y  HHFH=8  JH=@  H;H=,  H[HHH   expected Array of queue data missing capacity value exclusive_unlock not owner queue empty value must be positive exclusive Mutex marshal_load marshal_dump locked? try_lock synchronize ConditionVariable wait broadcast signal clear empty? length num_waiting pop push enq << deq shift size SizedQueue initialize max max=  not owner of the synchronization mutex  wrong number of arguments (%d for 1)    ꌠ9Y>)F;  9   P    0  D  X  0|      @  P  p  (  <   X  p    P       ,  PH  0     P         8  T   p  0        `8  X  p  @  P  P    ,  @T  pp      p      p    \         	  @(	   d	             zR x  $      X@   FJw ?:*3$"       D   p0             \   H          p   T
              P    Er
Ii
G        D    Eu
FC       F    E`
K(      f    BAA u
ABD     T          $  P     EZ      @  T,          T  p          h  |7    Ea   (     n    AG v
AAP
AG (     v    FAA eFB       8X    IHA     |.    KYD $     F    EAG sDA    <  C    E}      X  $    E^   8   t       FBD A(L0
(D ABBG          E       XK    EA       S    EI       #    E]         3    Em   $   <  x    EDD hAA   d  `D    E~        $    EU               (     E    EAG ]
AAA           EV   4     m    AAG l
AAID
DAE  0   0  D   FAD L@
 AABC    d   <    D ^
FS        @B    D} $     xD    EFG lDA      	       ,         FIF 
APL   $     lE    EFG mDA $   0  D    EFG lDA $   X  E    EFG mDA      /    Ei        L    Dr
JG        (    HN      0    d W$     r    EID ZDA           EZ      0  V    EP  8   L  H    FEA A(L0G
(D ABBG (     m    FFA PIB  $      H    ADD |AA $     (    EDD DA$     G    EDD pDA $   ,  O    EDD xDA 8   T      FJE A(A0(D BBB       X   LD                  GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             0            H=                                                                              ,             6             n                          /             8=                           @=                    o    `                                
                                   @             H                                                           	              o          o           o    D      o                                                                                                                                                                                                                           P=                             0      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @               GA$3a1       %/               GA$3p1067  @      /                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY     @      S               GA+GLIBCXX_ASSERTIONS   thread.so-1.8.7-16.el8.x86_64.debug 7zXZ  ִF !   t/_K] ?Eh=ڊ2N~ uehU𽢶M PPhI,u%=*s.AoEݹ[Rɜb[P$+چi]hii]("^O--JU_|(I꾉YYs>fEdn_ZiZ~ BI+LFE`ߴ=ht}a*'~QPV=A?,=Ԥi|Yqyo8k,|(ܞcbQg}$4VHkhw߬Q5srb% +#:bo(zu)m'8N>E-Y'6vmϼ縦WH?ShʯM>6
G0 H,ߎ}Egu3ezSV@xcxEuL%#VuIqB7f#=;EY!Ц)\6;ue:UM<'uOIwA"qz^2od
Hy}V}۔t{ywvT$Σ1xFE^"U@D. N|M,e~L(	$T=!mu{Fg]ns]1Y_Bm.H{kbo?vQi*+|JYLt;4A]WU ڟ!3mڎ$	X/1|pfyp=k6oN
6Pγc^Լ<=)5	lOj;'[I1;91׉r5fE9yO`cۭ9Gaa?APs<-
<QEw.~L&8%fnG* o$(-s &_a2k2\id4rQ@ub(dda]uL5.~F5S4^1 Z*4FxxjrV8p&YN(9n7 5Xc'bO鍎~_^B倨mmǳQ<cc+UbbxH@bOda@I131	ε_flUҷolQ9()D~j1$ʛ/t9Ky`%j'f6RhaةgvQK"D@~ؐD&{͗eis~'WsB;I[1s67"$pCCnH   RY 
,  eg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                               8      8      $                                 o       `      `      4                             (                                                   0                                                      8   o       D      D      l                            E   o                   0                            T                                                    ^      B                   H                          h                                                       c                         @                            n             P      P      0                            w                                                      }             /      /                                                 (/      (/                                                0      0                                                2      2                                                H:      H:                                                  8=      8=                                                @=      @=                                                H=      H=                                                 P=      P=      0                                        ?      ?                                                 @       @      0                                         0A      0A      (                                            XA`     0A      H                                                  xC      (                                                   C                                                         ,I      +                             PK     Y\`<,  ,    x86_64-linux/version.hnu [        #define RUBY_VERSION "1.8.7"
#define RUBY_RELEASE_DATE "2013-06-27"
#define RUBY_VERSION_CODE 187
#define RUBY_RELEASE_CODE 20130627
#define RUBY_PATCHLEVEL 374

#define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 8
#define RUBY_VERSION_TEENY 7
#define RUBY_RELEASE_YEAR 2013
#define RUBY_RELEASE_MONTH 6
#define RUBY_RELEASE_DAY 27

#ifdef RUBY_EXTERN
RUBY_EXTERN const char ruby_version[];
RUBY_EXTERN const char ruby_release_date[];
RUBY_EXTERN const char ruby_platform[];
RUBY_EXTERN const int ruby_patchlevel;
RUBY_EXTERN const char *ruby_description;
RUBY_EXTERN const char *ruby_copyright;
#endif

#define RUBY_AUTHOR "Yukihiro Matsumoto"
#define RUBY_BIRTH_YEAR 1993
#define RUBY_BIRTH_MONTH 2
#define RUBY_BIRTH_DAY 24

#define RUBY_RELEASE_STR "patchlevel"
#define RUBY_RELEASE_NUM RUBY_PATCHLEVEL
PK     Y\@  @    x86_64-linux/etc.sonu ȯ        ELF          >          @       8          @ 8 	 @                                 !      !                    -      -      -                                -      -      -      0      0                   8      8      8      $       $                                                                Std                                               Ptd   ,      ,      ,                           Qtd                                                  Rtd   -      -      -      x      x                      GNU  3@82{s        (         D0   (   *       BE|UqX                                                                                                                                                                                     O                     c                     
                     l                     \                                                                                                           U                      `                      F                                                                                                             =                                                                 (                     }                                                                                     t                                                                                     ,                                             F   "                   1                     h    (1              {    P1                        2      o    (1               __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_ary_new rb_tainted_str_new2 rb_ary_push rb_uint2inum rb_struct_new getgrent endgrent setgrent rb_yield rb_secure rb_string_value rb_check_safe_obj getgrnam rb_eArgError rb_raise rb_num2uint getgrgid setpwent endpwent rb_sys_fail getpwent getpwnam rb_scan_args getuid getpwuid __stack_chk_fail getlogin getenv rb_block_given_p rb_ensure rb_eRuntimeError Init_etc rb_define_module rb_define_module_function rb_global_variable rb_struct_define libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.4 GLIBC_2.2.5 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                     ^         ii        ui	         -             0      -                   -             -      /                    /                    /         !           /         $           /         %           /         &           0                     0                    (0                    00                    80                    @0                    H0                    P0         	           X0         
           `0                    h0                    p0                    x0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                     1                     1         "           1         #           1         &            1         '           HH!  HtH     5!  %!   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   %  D  %  D  %  D  %  D  %  D  %  D  %}  D  %u  D  %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  H=  H  H9tH6  Ht	        H=q  H5j  H)HHH?HHtH  HtfD      =-   u+UH=   HtH=  Id  ]     w             ff.              ff.     AVAUATIUSI\$HH;HtHHH|H;HuA|$H~  I|$IHHDI<$IHHDlH=E  [IL]LA\HA]1A^jf.     HsHtHH1@   HfD  H   Hf     H   Hf     HsH1HHu   HD  H   Ht$H|$OH|$HD$HxHtH1hHHD$H5  HPH  H81RfS   HHHHtH[1Hu  H5  H81fH   Hf     H#   Hf     AWAVAUATUSHH   HH(H-Q  HHD_H{ IHHDLH{IHHD9{I{HD$H{H$HHDH;IHHDHMLj H=  H1AUATLD$(HL$ H8[]A\A]A^A_H={  D  HH1HHu   HD  HHtHH1   HfD  HH|$Ht$	H|$oHD$Hx!HtH1rHHD$H5  HPHv  H81ff.     UHS   HdH%(   HD$1G1HHH|  t<'ÉHt;H1HT$dH3%(   uH[]     H<$H  H5  H81T@ H   HtHH     H=  Hu۸   HD  H   ^t+  uE1H1n     H=ZHtHH1f   HH  H5[  H81~ff.      H   t+  uE1H1     H=OEHtHH1Rf   HHO  H5  H81ff.      HH=  |1HsH5  HHR  =H=F  HH5  H='     HH5  H=  1H_H5}  H=  1HcH5j  H=  1HH5W  H=  1HH5  H=     HH5%  pH=y     HH5  QH=Z  1HH5  5H=>  1HuH5  H="  1H9H5  H=  1HH5  H=  HH  L  j Lo  H;  PH  H   PH5  H=  1.H H=  H  gE11Lj  H  Hc   H5?  H=R  Hc  H  HHcan't find group for %s can't find group for %d /etc/passwd can't find user for %s 01 can't find user for %d USER parallel group iteration parallel passwd iteration Etc getlogin getpwuid getpwnam setpwent endpwent getpwent getgrgid getgrnam group setgrent endgrent getgrent gecos name Passwd shell dir mem Group    ;         4     4(  T<  x  $  D  d      d  0  H        d     d@  d           zR x  $      (0   FJw ?:*3$"       D   0              \             p          8          BBB D(A0q(G EED        t*    HQ
GI             HN           HN      ;    Hr    (  n    H D
A    D  N    Eh
G   `  D    HN    x  L    HN T     T    BBB B(A0A8DPXH`NhBpS8A0A(B BBBAP      ;    Hr       *    HQ
GI         d    H z
A  (   <  h    EDK0a
AAI    h  K    H[
MZ             HO
II
A             HO
II
A   (     2   HP O(O0YK                    GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             0            -                                        0             ;             F             T             ^                                                    -                           -                    o    `                                
                                   0             0                           
             
                    	              o    	      o           o    |	      o                                                                                                                                           -                      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P               GA$3a1                      GA$3p1067  @                      GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY     @      T               GA+GLIBCXX_ASSERTIONS   etc.so-1.8.7-16.el8.x86_64.debug    2TU7zXZ  ִF !   t/] ?Eh=ڊ2N :t''	AA":Xzu֑:Ebͼ;v-3Y¦Hր
uVH<1fI6!H3"NXIe|b2I~!ݼD@\&P<Cb[)v}	&oO_# .T-x`Mm8 vM FR|twԈۍ;DShE4Z8u0.4XÈL;݁_ӈK=}Z{Z	Q,*TY1m0,ȍ:Ni\ʖJ/j%'exUz(QΒlToti]CU%TgvwJ0+rx=!yފ>}'8w]w%E[߿:fH."lbe	ߩ"A琳yW5A-!]}1
X+V[9k׿5qYMܿ!?G
Zq,f_.7G]]N Vh66;1#OT@mxGa< zIsm7W6RݍTRDvwX	yC{=W@+)U~y~}=$J`2i!1oBPZEc&WVP _2J9H=ifj)zO+4hjtZSxox-ȟ'nl@,"4e>U 4cɨϰaD;r-P? *H[+Iwܚٔ nkV	y>8g]\:a%	Y뤥 D#@NMIϢSq(ht❬QdEWD6a~ɢx7F2he   )4蓜 !  Fg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                               8      8      $                                 o       `      `      4                             (                                                    0                                                      8   o       |	      |	      X                            E   o       	      	      0                            T             
      
                                  ^      B       
      
      0                          h                                                       c             0      0      0                            n             `      `                                   w                         b	                             }                                                             2                   8                                         ,      ,                                                                                                                                                                 -      -                                                -      -                                                -      -                                                 -      -      0                                        /      /      0                                           0       0      (                                         (1      (1      (                                            P1`     (1      H                                                  p3      (                                                   3                                                         7      +                             PK     Y\˚ b   b    x86_64-linux/strscan.sonu ȯ        ELF          >          @       Z          @ 8 	 @                                 @A      @A                    @M      @M      @M             8                    XM      XM      XM      0      0                   8      8      8      $       $                     A       A       A                             Std    A       A       A                             Ptd   7      7      7                         Qtd                                                  Rtd   @M      @M      @M                                  GNU qK#*_A,yDH       8         @`   8   ;       V`TdBE|qX                                                 $                     V                                          {                                                                                                             !                     p                      M                                          .                                                                                                           [                                                                                                                               U                                             b                                                                                       Z                                                                                                          4                     B                                                                {                     ?                                          3                                                               E                                          p                     ,                                             F   "                                                              h                                          s    0-      _          `Q                  xQ                  `Q               __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize ruby_xmalloc rb_check_type rb_num2int rb_int2inum rb_fix2int rb_eRangeError rb_raise rb_eArgError rb_string_value rb_str_dup rb_obj_freeze ruby_re_copy_registers rb_obj_classname rb_eTypeError rb_gc_mark rb_scan_args __stack_chk_fail ruby_re_free_registers free rb_data_object_alloc rb_str_new rb_num2long re_mbctab rb_kcode_set_option ruby_re_search rb_kcode_reset_option ruby_re_match rb_warning __memcpy_chk rb_str_dump rb_str_new2 rb_str_append rb_class2name __snprintf_chk rb_cFalseClass rb_cFixnum rb_cNilClass rb_cTrueClass rb_cSymbol Init_strscan rb_intern rb_cObject rb_define_class rb_eStandardError rb_define_class_under rb_const_defined rb_const_set rb_define_alloc_func rb_define_private_method rb_define_singleton_method rb_define_method rb_alias libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.4 GLIBC_2.2.5 GLIBC_2.3.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                             ii        ui	        ti	         @M                   HM             P      PM             PM      O                    O                    O         	           O                    O                    O                    O                    O                    O         %           O         *           O         +           O         1           O         2           O         3           O         6           P                     P                    (P                    0P                    8P                    @P                    HP         
           PP                    XP                    `P                    hP                    pP                    xP                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                     P         !           P         "           P         #           P         $           P         &            Q         '           Q         (           Q         )           Q         ,            Q         -           (Q         .           0Q         /           8Q         0           @Q         3           HQ         4           PQ         5           XQ         7           HH!=  HtH             5R=  %S=   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   a%:  D  %:  D  %:  D  %:  D  %:  D  %:  D  %:  D  %:  D  %}:  D  %u:  D  %m:  D  %e:  D  %]:  D  %U:  D  %M:  D  %E:  D  %=:  D  %5:  D  %-:  D  %%:  D  %:  D  %:  D  %:  D  %:  D  %9  D  %9  D  %9  D  %9  D  %9  D  %9  D  %9  D  %9  D  %9  D  %9  D  %9  D  %9  D  %9  D  %9  D  %9  D  %9  D  %}9  D  H=y9  Hr9  H9tH7  Ht	        H=I9  H5B9  H)HHH?HHtH7  HtfD      =9   u+UH=7   HtH=4  )d8  ]     w    H     SG Ht%HG0HS(C$       HS+S[D  (   (   HC(xC 
   HC0ff.     UH"   SHHVH[ H{tjHu3~HSHRHx3H9|3HCHH[]f.     KHSHRHyHyH6  H5;  H81HB6  H5  H81f     SHHHt$"   H|$H[ H|$-HCHH#HD$HC    H[f.     ATUHSH"   HHtwurtm?"ucH   H9CuV"   HLe Hs I9t0HI|$ H I$HFID$HFID$HFID$H[]A\@ H0H5  HH4  H81D  H AVI"   AUAHATUSHH dH%(   HD$1Hl$UHLD$LH  D1Lc eHHD$ID$HL$dH3%(   uH H[]A\A]A^^ff.      SHH H[fD  SH8   fHH HHH H@0    H@   @@ [1HuHtH %   H	D  LG   IHH9|NSHHHH9HNHH)I@H:uHtHHsHD$HD$H[fff.     @ UHSH"   HHm H}tpE tJtXHHcU$Hx4H9~4HU(Hct'HU0HuHHcH[]HH"fHyH   []    HHH2  H5m  H81S S"   H.H[ HsHtHHSH~HHH9}aHNH5.2  H6HSHL
H9HOHHHHK HS0HK(HHC[HcHc1HHO       [H2  H5  H81f     SH   HHHOH9|BLHH)L9HLHwHHVuHtHHsHD$HD$H[ff.      AVAAUAATEUH   SHHH߾"   H[ HCH   H#HKH9H   HHCHsLC H}P)HpEuUM1AhQ   xDHsHC0HHsHcEtHHCHDEu*[]A\A]A^Ð1D  [   ]A\A]A^fH[]A\A]A^Hq0  H5"  H81H=1  H5P  1 HHE1f.     E1   1ff.     fE111pE11ɺ   ]ff.     fE1      :f.     HA   H    A      1f.     A   11ff.     fA   1ɺ   f.     A             UHSH"   HvHm HEH   t7HuH@HHH9}@H<HH)H9HHLH[]D  HHuHHEH@H9|1H=  uHtHHuHD$aHD$H[]H6.  H5  H81ff.     fU1HSHH=  HHHH[]SH  H_dH%(   H$  1H9~|H)HwHOI   HLILH>HvH$  dH3%(   uAH  [f.        I$FD$... D$먐H=  d-ff.     fPXH5  HH-  H81fS"   HHS HBHtHJHP   H9}H)HD[ff.     @ S1HH=  ZH[@ S"   HHH[ HCHtRHsHPH9}HH[f1H=  uHtHHsHD$EHD$H[D  S"   HH{ HGHt'tHPHG0[Hc0HwfD     [@ S"   HNH{ Ht"tHG(1[HcHW    [\ff.     S"   HH{ Ht*tHW0HO(HG[HcHc1HHp   [@ S"   HHC HxtH [H S"   H~HS HBHtH@H9B[H     S"   H>HS HBHtH@H9B[HX     S1HH=  H[@ S"   HHC HPHt-HH   H;J   HtHB|
H[ff.      S"   H~HS HztH
t,HBHH
HBH[H)  H5i  H81OH= +  H5Y  1:f.     S"   HHC HxtH@[HD 3 S"   HHC H@Ht[	f     S"   HHS HBHtH@H"HBH[f.     S1HH=  H[@ S"   HNHS HztHHB    H"[mff.     fS"   HHC Hxt* tHP0H@([:+8Hcf        [@ S1HH=O  H[@ S"   HH[ HKHtWHHSHHH;Q}<HSHHHHSHHS0HK(HHC[HcHc1HH   [t@ S1HH=  :H[aUSHHHt$"   Hk H}t"H|$_H}Ht$HH[]fAW"   AVAUATUSHIAH(  dH%(   H$  1Hk H}H  HuH;w  H;  HA  Ld$IML   L)HwLLJ40L)0HhHuH}IIVLuHHHELxM  HA  HX  H    H{HT$H$H$L   ILM  1QHT$   R   AWAVaH LHcuHtHHuH$H$H$  dH3%(     H(  []A\A]A^A_f     LeLxHELpM   H  H  H%  <  H{#H\$HL`  AWI      AV   H1ATH HcH8D  H$  H8H$  H8@ M   H}  HT  H     H{        Ha$  H8PLd$D$... A   MD$ M   H-  H   HI  O  H{H\$L)
  I5    H#  H8H#  H8H\$L
  I      H1   9@ H#  H8Hy#  H8@ H#  H8IHa#  H8THI#  H8@H#  H8HA#  H8[HQ#  H8H"  H8;H"  H8H"  H8H#  H8H#  H8H"  H8H"  H8ff.      UH=
	  SHHK"  H=  HH3qHj"  H5  HH#  H1H;HH#    H=  kHH@H=  H=#  HHH=  6HHH=  OH=x#  HHH=f#  H5jH=S#  HH5?  kH=4#     HH5+  LH=#  1H<H5  H="  1HH5  tH="  1H$H5  XH="  1HHH5  <H="  1HH5   H="     HH5  H=j"     H^H5  H=K"     H?H5  H=,"  1HH5t  H="     HH5Y  H=!  1HH5B  lH=!     HiH5+  MH=!     H
H5  .H=!     HH5  H=x!     HH5  H=Y!     HMH5  H=:!     HH5  H=!     HH5  H=      HH5  tH=      HQH5n  UH=      HH5V  6H=      HH5C  H=   1HGH53  H=d   1HH5  H=H   1HH5
  H=,      HH5  H=      HaH5  H=  1HeH5  iH=  1HH5  MH=  H=  HrH=  HHH=  1H@H5|  H=m  1HdH5e  H=Q  1HH5P  H=5  1H|H5:  H=  1HH5'  H=  1HH5  xH=  1HH5  \H=     HH5  =H=  1HMH5  !H=  1HH5  H=n  1HEH5  H=R  1HH5  H=6  1HH5  H=  H1[H\H5t  ]    H  H;H6
 HH   uninitialized StringScanner object      wrong argument type %s (expected StringScanner) StringScanner#peep is obsolete; use #peek instead       StringScanner#restsize is obsolete; use #rest_size instead      StringScanner#empty? is obsolete; use #eos? instead     unscan failed: previous match had failed        StringScanner#clear is obsolete; use #terminate instead StringScanner#matchedsize is obsolete; use #matched_size instead        StringScanner#getbyte is obsolete; use #get_byte instead        $Id: strscan.c 11708 2007-02-12 23:01:19Z shyouhei $    index out of range 11 regexp buffer overflow #<%s (uninitialized)> #<%s fin> #<%s %ld/%ld @ %s> #<%s %ld/%ld %s @ %s> ScanError StringScanner 0.7.0 Version Id initialize initialize_copy must_C_version reset terminate clear string string= concat << pos pos= pointer pointer= skip match? check scan_full scan_until skip_until exist? check_until search_full getch get_byte getbyte peek peep unscan beginning_of_line? bol? eos? empty? rest? matched? matched matched_size matchedsize [] pre_match post_match rest rest_size restsize inspect  ;  7     h     4  (P  |  8      $  @  \  8p    X      t        8  X         (  <  t        H  h  @  8d        H       <  xX  t      8  x    $  hH  d    H	             zR x  $         FJw ?:*3$"       D   X             \             p   U    Ai
F(          EIG w
DAO        TV    EG HA,          FAD 
ABE        $       @          FJH A(A0GP`
0D(A BBBA    `  |    EP      |  O    EE                    a    SJ AC   4         EDL L
AAMI
FAH           E{
XF
A    ,   b    AL SA`   L  p-   BEE D(I0
(A BBBBQ
(F BBBCD
(A BBBE        <&            X            d            `             l            x)          (            <            P            d         4   x      EDL0G
AAJP
AAA$     l/    EFN IGA       t    AGl
AK         AAK       A    Ev
A   4  H    EU   (   P  L{    EL d
DGt
AA     |  L    Ei
RF
A        D    Ed
OF
A        L    Ej
QF
A       $-    E\
G     88    Eg
G      \8    Eg
G   <      EU      X  R    EG
A      x  f    Es
A     -    E]
F     ,'    E\
A     @6    Ek
A     d    EU        h3    Eh
A       L    Ef
UF
A     D      EU       `  |    EZ
QF
A          EU   (     N    EAG0v
DAA  t     @b   FGB B(A0A8QKGBII
8A0A(B BBBJVIOLI (   D  8_   EHD 
COL             GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   P      PM             N             ]             m             x                                                                              3             @M                           HM                    o    `             8                   
                                   P                                                                         	              o          o           o    D      o                                                                                                                                                                                                                   XM                                                                  0      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @               GA$3a1       3               GA$3p1067        3                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY                          GA+GLIBCXX_ASSERTIONS   strscan.so-1.8.7-16.el8.x86_64.debug    Gr7zXZ  ִF !   t//}] ?Eh=ڊ2Nz\#%#%^%ف<a6].T*$fr8A]!3 =!.bp@(ٵ~#tXlB'kUp=T̸[p*}R
Q|ܳA9#:@x$-[lF*]=˃E.G (tow'PX#~k-VlLf0uÜߞ^A ͂8;ݏ=O)
lO%noHbc)ѶboPxI}ↄRsCɘU#IXH6֦Bs6H>"q1ǅnjmAޫuX08OmlR!KgV#U9d0!ރa0776:	dj4IĊ6Xzn0s	amDrUFizUoY$+
=۸6zZ^"ol-a^DڴQ
X(q@o~(s0?8!mDeJ
A+݌C?zzZz֋{BLYU+ĶWk
;UB˝oV3g*UhXB1)4	`:g5
gDEL$[?cW]m؁H0R:'9s=>hRd2%.k] wHyRsWEc/3gۃ󜱘9h"KG%G>CvB tvoo4Mg};Sf6q%6;*Hs17rm;0^H=>lpIHӌ{J\|}O<?bX8$ %c]/Nlo3D<3ՖH.:eln>Q`=tF:iJ+DZ$}Msb,g}"Q*hI2քW
B_10:]`"~4[kǷVܠҐ?o-҂J9BhY5N&)dF^rux\Q[S+25mNvH*cH 4f_k#5SK9;oITez.XFP~o@ygLmq6cfIDcFMGH/ctfWSݧ3SF56 D~"pBC"}
NeOI"JDS9g@?K/+f[#vwQ
-˫H1U=/>lƇ_d)M-Y>rMPЁO7^LZq"ۣEjls`$D"OLsECq|%?+|Fm
$Bf;$TD     ,C 2  #qg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                               8      8      $                                 o       `      `      4                             (                                                   0             8      8                                   8   o       D      D      x                            E   o                   @                            T                                                      ^      B                                             h                                                       c                                                     n             P      P                                  w                                                      }             3      3                                          2       3      3      G                                         7      7                                                9      9      p                                           A       A                                                  @M      @M                                                HM      HM                                                PM      PM                                                 XM      XM      0                                        O      O      x                                           P       P      `                                         `Q      `Q                                                  xQ`     `Q      H                                                  S      ,                                                   S                                                         Y      +                             PK     Y\!"  "    x86_64-linux/dl.hnu [        /* -*- C -*-
 * $Id: dl.h 11708 2007-02-12 23:01:19Z shyouhei $
 */

#ifndef RUBY_DL_H
#define RUBY_DL_H

#include <ruby.h>
#include <dlconfig.h>

#if defined(HAVE_DLFCN_H)
# include <dlfcn.h>
# /* some stranger systems may not define all of these */
#ifndef RTLD_LAZY
#define RTLD_LAZY 0
#endif
#ifndef RTLD_GLOBAL
#define RTLD_GLOBAL 0
#endif
#ifndef RTLD_NOW
#define RTLD_NOW 0
#endif
#else
# if defined(HAVE_WINDOWS_H)
#   include <windows.h>
#   define dlclose(ptr) FreeLibrary((HINSTANCE)ptr)
#   define dlopen(name,flag) ((void*)LoadLibrary(name))
#   define dlerror()    "unknown error"
#   define dlsym(handle,name) ((void*)GetProcAddress(handle,name))
#   define RTLD_LAZY -1
#   define RTLD_NOW  -1
#   define RTLD_GLOBAL -1
# endif
#endif

#if !defined(StringValue)
# define StringValue(v) if(TYPE(v) != T_STRING) v = rb_str_to_str(v)
#endif
#if !defined(StringValuePtr)
# define StringValuePtr(v) RSTRING((TYPE(v) == T_STRING) ? (v) : rb_str_to_str(v))->ptr
#endif

#ifdef DEBUG
#define DEBUG_CODE(b) {printf("DEBUG:%d\n",__LINE__);b;}
#define DEBUG_CODE2(b1,b2) {printf("DEBUG:%d\n",__LINE__);b1;}
#else
#define DEBUG_CODE(b)
#define DEBUG_CODE2(b1,b2) b2
#endif

#define VOID_DLTYPE   0x00
#define CHAR_DLTYPE   0x01
#define SHORT_DLTYPE  0x02
#define INT_DLTYPE    0x03
#define LONG_DLTYPE   0x04
#define FLOAT_DLTYPE  0x05
#define DOUBLE_DLTYPE 0x06
#define VOIDP_DLTYPE  0x07

#define ARG_TYPE(x,i) (((x) & (0x07 << ((i)*3))) >> ((i)*3))
#define PUSH_ARG(x,t) do{x <<= 3; x |= t;}while(0)
#define PUSH_0(x) PUSH_ARG(x,VOID_DLTYPE)

#if SIZEOF_INT == SIZEOF_LONG
# define PUSH_I(x) PUSH_ARG(x,LONG_DLTYPE)
# define ANY2I(x)  x.l
# define DLINT(x)  (long)x
#else
# define PUSH_I(x) PUSH_ARG(x,INT_DLTYPE)
# define ANY2I(x)  x.i
# define DLINT(x)  (int)x
#endif
#define PUSH_L(x) PUSH_ARG(x,LONG_DLTYPE)
#define ANY2L(x)  x.l
#define DLLONG(x) (long)x

#if defined(WITH_TYPE_FLOAT)
# if SIZEOF_FLOAT == SIZEOF_DOUBLE
#   define PUSH_F(x) PUSH_ARG(x,DOUBLE_DLTYPE)
#   define ANY2F(x)  (x.d)
#   define DLFLOAT(x) ((double)x)
# else
#   define PUSH_F(x) PUSH_ARG(x,FLOAT_DLTYPE)
#   define ANY2F(x)  (x.f)
#   define DLFLOAT(x) ((float)x)
# endif
#else
# define PUSH_F(x) PUSH_ARG(x,DOUBLE_DLTYPE)
# define ANY2F(x)  (x.d)
# define DLFLOAT(x) ((double)x)
#endif
#define PUSH_D(x) PUSH_ARG(x,DOUBLE_DLTYPE)
#define ANY2D(x)  (x.d)
#define DLDOUBLE(x) ((double)x)

#if SIZEOF_INT == SIZEOF_VOIDP && SIZEOF_INT != SIZEOF_LONG
# define PUSH_P(x) PUSH_ARG(x,INT_DLTYPE)
# define ANY2P(x)  (x.i)
# define DLVOIDP(x) ((int)x)
#elif SIZEOF_LONG == SIZEOF_VOIDP
# define PUSH_P(x) PUSH_ARG(x,LONG_DLTYPE)
# define ANY2P(x)  (x.l)
# define DLVOIDP(x) ((long)x)
#else
# define PUSH_P(x) PUSH_ARG(x,VOIDP_DLTYPE)
# define ANY2P(x)  (x.p)
# define DLVOIDP(x) ((void*)p)
#endif

#if defined(WITH_TYPE_CHAR)
# define PUSH_C(x) PUSH_ARG(x,CHAR_DLTYPE)
# define ANY2C(x)  (x.c)
# define DLCHAR(x) ((char)x)
#else
# define PUSH_C(x) PUSH_I(x)
# define ANY2C(x)  ANY2I(x)
# define DLCHAR(x) DLINT(x)
#endif

#if defined(WITH_TYPE_SHORT)
# define PUSH_H(x) PUSH_ARG(x,SHORT_DLTYPE)
# define ANY2H(x)  (x.h)
# define DLSHORT(x) ((short)x)
#else
# define PUSH_H(x) PUSH_I(x)
# define ANY2H(x)  ANY2I(x)
# define DLSHORT(x) DLINT(x)
#endif

#define PUSH_S(x) PUSH_P(x)
#define ANY2S(x) ANY2P(x)
#define DLSTR(x) DLVOIDP(x)

#define CBPUSH_0(x) PUSH_0(x)
#define CBPUSH_C(x) PUSH_C(x)
#define CBPUSH_H(x) PUSH_H(x)
#define CBPUSH_I(x) PUSH_I(x)
#define CBPUSH_L(x) PUSH_L(x)
#define CBPUSH_F(x) PUSH_F(x)
#define CBPUSH_D(x) PUSH_D(x)
#if defined(WITH_CBTYPE_VOIDP)
# define CBPUSH_P(x) PUSH_ARG(x,VOIDP_DLTYPE)
#else
# define CBPUSH_P(x) PUSH_P(x)
#endif


#if defined(USE_INLINE_ASM)
# if defined(__i386__) && defined(__GNUC__)
#   define DLSTACK
#   define DLSTACK_METHOD "asm"
#   define DLSTACK_REVERSE
#   define DLSTACK_PROTO
#   define DLSTACK_ARGS
#   define DLSTACK_START(sym)
#   define DLSTACK_END(sym)
#   define DLSTACK_PUSH_C(x) asm volatile ("pushl %0" :: "g" (x));
#   define DLSTACK_PUSH_H(x) asm volatile ("pushl %0" :: "g" (x));
#   define DLSTACK_PUSH_I(x) asm volatile ("pushl %0" :: "g" (x));
#   define DLSTACK_PUSH_L(x) asm volatile ("pushl %0" :: "g" (x));
#   define DLSTACK_PUSH_P(x) asm volatile ("pushl %0" :: "g" (x));
#   define DLSTACK_PUSH_F(x) asm volatile ("flds %0"::"g"(x));\
                             asm volatile ("subl $4,%esp");\
                             asm volatile ("fstps (%esp)");
#   define DLSTACK_PUSH_D(x) asm volatile ("fldl %0"::"g"(x));\
                             asm volatile ("subl $8,%esp");\
                             asm volatile ("fstpl (%esp)")
# else
# error --with-asm is not supported on this machine
# endif
#elif defined(USE_DLSTACK)
# define DLSTACK
# define DLSTACK_GUARD
# define DLSTACK_METHOD "dl"
# define DLSTACK_PROTO long,long,long,long,long,\
                       long,long,long,long,long,\
                       long,long,long,long,long
# define DLSTACK_ARGS  stack[0],stack[1],stack[2],stack[3],stack[4],\
                       stack[5],stack[6],stack[7],stack[8],stack[9],\
                       stack[10],stack[11],stack[12],stack[13],stack[14]
# define DLSTACK_SIZE  (sizeof(long)*15)
# define DLSTACK_START(sym)
# define DLSTACK_END(sym)
# define DLSTACK_PUSH_C(x)  {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;}
# define DLSTACK_PUSH_H(x)  {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;}
# define DLSTACK_PUSH_I(x)  {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;}
# define DLSTACK_PUSH_L(x)  memcpy(sp,&x,sizeof(long)); sp++;
# define DLSTACK_PUSH_P(x)  memcpy(sp,&x,sizeof(void*)); sp++;
# define DLSTACK_PUSH_F(x)  memcpy(sp,&x,sizeof(float)); sp+=sizeof(float)/sizeof(long);
# define DLSTACK_PUSH_D(x)  memcpy(sp,&x,sizeof(double)); sp+=sizeof(double)/sizeof(long);
#else
# define DLSTACK_METHOD "none"
#endif

extern VALUE rb_mDL;
extern VALUE rb_mDLMemorySpace;
extern VALUE rb_cDLHandle;
extern VALUE rb_cDLSymbol;
extern VALUE rb_cDLPtrData;
extern VALUE rb_cDLStructData;

extern VALUE rb_eDLError;
extern VALUE rb_eDLTypeError;

#if defined(LONG2NUM) && (SIZEOF_LONG == SIZEOF_VOIDP)
# define DLLONG2NUM(x) LONG2NUM((long)x)
# define DLNUM2LONG(x) (long)(NUM2LONG(x))
#else
# define DLLONG2NUM(x) INT2NUM((long)x)
# define DLNUM2LONG(x) (long)(NUM2INT(x))
#endif

typedef struct { char c; void *x; } s_voidp;
typedef struct { char c; short x; } s_short;
typedef struct { char c; int x; } s_int;
typedef struct { char c; long x; } s_long;
typedef struct { char c; float x; } s_float;
typedef struct { char c; double x; } s_double;

#define ALIGN_VOIDP  (sizeof(s_voidp) - sizeof(void *))
#define ALIGN_SHORT  (sizeof(s_short) - sizeof(short))
#define ALIGN_INT    (sizeof(s_int) - sizeof(int))
#define ALIGN_LONG   (sizeof(s_long) - sizeof(long))
#define ALIGN_FLOAT  (sizeof(s_float) - sizeof(float))
#define ALIGN_DOUBLE (sizeof(s_double) - sizeof(double))

/* for compatibility */
#define VOIDP_ALIGN  ALIGN_VOIDP
#define SHORT_ALIGN  ALIGN_SHORT
#define INT_ALIGN    ALIGN_INT
#define LONG_ALIGN   ALIGN_LONG
#define FLOAT_ALIGN  ALIGN_FLOAT
#define DOUBLE_ALIGN ALIGN_DOUBLE

#define DLALIGN(ptr,offset,align) {\
  while( (((unsigned long)((char *)ptr + offset)) % align) != 0 ) offset++;\
}

typedef void (*freefunc_t)(void *);
#define DLFREEFUNC(func) ((freefunc_t)(func))

typedef union {
  void*  p;
  char   c;
  short  h;
  int    i;
  long   l;
  float  f;
  double d;
  char  *s;
} ANY_TYPE;

struct dl_handle {
  void *ptr;
  int  open;
  int  enable_close;
};

struct sym_data {
  void *func;
  char *name;
  char *type;
  int  len;
};

enum DLPTR_CTYPE {
  DLPTR_CTYPE_UNKNOWN,
  DLPTR_CTYPE_STRUCT,
  DLPTR_CTYPE_UNION
};

struct ptr_data {
  void *ptr;       /* a pointer to the data */
  freefunc_t free; /* free() */
  char *stype;      /* array of type specifiers */
  int  *ssize;      /* size[i] = sizeof(type[i]) > 0 */
  int  slen;   /* the number of type specifiers */
  ID   *ids;
  int  ids_num;
  int  ctype; /* DLPTR_CTYPE_UNKNOWN, DLPTR_CTYPE_STRUCT, DLPTR_CTYPE_UNION */
  long size;
};

#define RDLPTR(obj)  ((struct ptr_data *)(DATA_PTR(obj)))
#define RDLSYM(obj)  ((struct sym_data *)(DATA_PTR(obj)))

void dlfree(void*);
void *dlmalloc(size_t);
void *dlrealloc(void*,size_t);
char *dlstrdup(const char *);
size_t dlsizeof(const char *);

void *rb_ary2cary(char t, VALUE ary, long *size);

/*
void rb_dlmem_delete(void *ptr);
void rb_dlmem_aset(void *ptr, VALUE obj);
VALUE rb_dlmem_aref(void *ptr);
*/

void dlptr_free(struct ptr_data *data);
void dlptr_init(VALUE val);

VALUE rb_dlptr_new(void *ptr, long size, freefunc_t func);
VALUE rb_dlptr_new2(VALUE klass, void *ptr, long size, freefunc_t func);
VALUE rb_dlptr_malloc(long size, freefunc_t func);
void *rb_dlptr2cptr(VALUE val);

VALUE rb_dlsym_new(void (*func)(), const char *name, const char *type);
freefunc_t rb_dlsym2csym(VALUE val);


#endif /* RUBY_DL_H */
PK     Y\v A  A    x86_64-linux/digest/sha2.sonu ȯ        ELF          >    @      @       8:          @ 8 	 @                                 @(      @(                    -      -      -                                -      -      -      0      0                   8      8      8      $       $                     (       (       (                             Std    (       (       (                             Ptd   $      $      $                           Qtd                                                  Rtd   -      -      -      p      p                      GNU ziu3                @ hLI         Rr\2&BEb{Y˨I|"6DM(qX" FV,-I~\&                                                                        t                                                                                                                                                       ,                       F   "                                                             |           [      R                 0    81              U            =       :          	       k     @      8      C    @1                               $           w       7    81                   `                 P            j    P                        u                 w                         __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_Digest_SHA256_Init SHA256_Transform rb_Digest_SHA256_Update memcpy __assert_fail rb_Digest_SHA256_Finish rb_Digest_SHA512_Init SHA512_Transform rb_Digest_SHA512_Update SHA512_Last rb_Digest_SHA512_Finish rb_Digest_SHA384_Init rb_Digest_SHA384_Update rb_Digest_SHA384_Finish Init_sha2 rb_require rb_intern rb_path2class rb_define_class_under rb_cObject rb_data_object_alloc rb_ivar_set libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.14 GLIBC_2.2.5 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                  &            H     ui	   S      -                   -                   -             -      /                    /                    /                    /         
           /                    0                    0                    0                    0                    0                    0                     1                    (1                    01                    0                     0                    (0                    00                    80                    @0                    H0                    P0         	           X0                    `0                    h0                    p0                    x0                    HHq$  HtH             5r$  %s$   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !%#  D  %#  D  %#  D  %#  D  %}#  D  %u#  D  %m#  D  %e#  D  %]#  D  %U#  D  %M#  D  %E#  D  %=#  D  H=#  H#  H9tH~"  Ht	        H=#  H5#  H)HHH?HHtHU"  HtfD      =}#   u+UH=2"   HtH=  9dU#  ]     w    Ht3fo/  fo7  HG     fG(WG8GHGX AWHL  AVA/BAUATUHo(SDID_DxXDhH|$D`@Hl$D$%D  E0ADd$DEEAIA҉ىډ؋>D!H1ʉA9I1ʉD!1D$DD!ADC<71D
1D1D!1Hy  DL9el$LxHl$   Dd$D$i,@ AD\$IEDl$AADD$DDaDDL DDA1qD1DL$DD EDA
AD1A΃	AD1ANt A!AD ƉA611D!D1EΉt$t$1ȉE!A
1DD1!D1A@HD$0PDPDXDHxXDh[]A\A]A^A_     H  AUATUHSHH  HH  HG IH?uYIH?  ID$HLl@fD  HHH@HE    L9uA?M   H[]A\A]@ @   )H|(L9   rzHLGIIHHDHDL)I)׃r1ƃM2M09rHU HI)Hu(HII?/^fD         ttDfDD  HM(DAscA   EtAU U(tDADfDILe H[]A\A]    LILe H[]A\A]D  IE Hu0HHE(DITHTH)AI)̓r1҉уI| H<9r{DDAU U(DADDRH]    H5  H=  D  ATUSH  HHH   HG Lg(HHHHW ?   PD(8   @   LHjfC(ID$0    AD$AD$ HS HS`LH:1     ʉT HH uH{H    1HHC`    H)KhH[]A\fG(AD$AD$ ID$0    G(D  8   HL(1)Ѓs]   X M1fD?@ @   )Ht(1 9rfD  HqH    HD    HH)ȃ1҉уH<9r    D    HJ    H5
  H=
  fHHtjfo\  fod  HGP    HXfo`  foh  HGp    GOW_H)   1HHBH    HB@    f     AWHLh  AVI"(ט/BAUATUHoPSLIL_LxHX Lh(H|$L`0HH@8Hl$HD$H%@ M0ILd$LMMIIHIHHHH>HHL!HH1HHI9HIH1HHL!H1HD$HLHHLHH!ILHK<7H1LHH1LH1L!H1HH
  LL9ILxHl$   HJiHl$Ld$HD$+IL\$IMLl$IIDHD$HHLDaDLL LLIHHH1qL1LL$LD MLIIHL1A΃	AL1INt I!IHD HHHHHI6H1HHH1HHL!L1MHHHHHHt$HHt$H1HM!IHH1LL1H!L1HHAPHD$H0HPLPLXLH Hx(HX0Lh8[]A\A]A^A_ff.     H+  AUATUSHHH3  HH'  HO@IHHunIH!  ID$HL   HHHC@H   HC@H=  wHCHHL9uAM   H[]A\A]f        )AHDPM9   rqHHxHHJLJL H)H)ƉHHK@HHS@sHCHLM)HsPHII!`D         ttBLfBL HO@    HSPAsVA   EuyILc@Lc@HCHH[]A\A]D  LHI!Lc@Lc@̐IE H{XLHHCPDILHLH)AH)HAE CPAuDALfLbBLBL HO@AE CPDALL3H    H5  H=(  +ff.     UHoPSHHHG@HWHHHHHWHHHw@   PDPpvj     HHCH}H1HHCP    H)HEv    ~HHSHHs@H   HHH   H[] p   HLP)ЃrwHyH    HD    HH)1HHSHHs@f.     HGP    HXH1HG`    HH)pHCP\fD     t t1ftf.        HLP1)Ѓs-    1fD@ HqH    HD    HH)ȃ1҉уH<9rpfD      D        D    @ff.      USHHteHHHt(Q1    HHHHT HH@uH{H    1Hǃ       HH)   HH[]H  U  H5Y  H=Y  mff.     fHHtjfoL  foT  HGP    HXfoP  foX  HGp    GOW_H)   1HHBH    HB@    f     '    USHHteHHHt(!1    HHHHT HH0uH{H    1Hǃ       HH)   HH[]Hu    H5)  H=)  =f.      AVH=  AUATUSH=  ,H=  H]H=  INLH5  HIyH-2  11H5G  IH} HLH]LLH5  ;H} 11H5  IHLH&LLH5{  H} 11H5U  I]HL[H]A\A]A^   HH       sha2.c context != NULL  context != NULL && data != NULL         rb_Digest_SHA384_Finish         rb_Digest_SHA512_Finish         rb_Digest_SHA512_Update         rb_Digest_SHA256_Finish         rb_Digest_SHA256_Update         ɼg	j;ʄg+rn<6_:OтRQl>+hkAكy!~[؞]|6*)bp0ZY9Y/1g&3gXhJd.ۤOHG"(ט/Be#D7q/;Mۉ۵8H[V9YO?m^BؾopE[N1$}Uo{t]r;ހ5%ܛ&itJi%O8GՌƝew̡$u+Yo,-ntJAܩ\SڈvfRQ>2-m1?!'Y=%
GoQcpn
g))/F
'&&\8!.*Zm,M߳8ScTs
ew<
jvG.;5,rdL迢0BKfpK0TQlReU$* qW5ѻ2pjҸSAQl7LwH'Hᵼ4cZų9ˊAJNscwOʜ[o.h]t`/CocxrxȄ9dǌ(c#齂lPyƲ+SrxqƜa&>'!Ǹ}xnO}orgȢ}c
?G5q}#w($@{2
<LgCB>˾L*~e)Y:o_XGJDlg	jgrn<:ORQhك[/BD7q۵[V9Y?^[1$}Ut]rހܛtiGƝ̡$o,-tJܩ\ڈvRQ>m1'YGQcg))
'8!.m,M8STs
e
jv.,r迢KfpK£Ql$օ5pjl7LwH'49JNOʜ[o.htocxxȄǌlPxqdigest metadata Digest Digest::Base SHA256 SHA384 SHA512    ;            d      4  D  4    D0             D         zR x  $      P    FJw ?:*3$"       D                 \   =       @   p   8   FLH B(A0E80A(B BBB p      [   OBA D(D0s
(A ABBEH0j
(A ABBHT
(A ABBF ,   (     FAA 
ABA      X  Tw       @   l     FLL B(A0E8U0A(B BBB `     u   OBA A(G0
(A ABBJH0d
(A ABBF   (     (   EEG 
AAH (   @      EAD g
AAA    l  w            	       ,         EAD g
AAA     8     h    FIB A(A0(D BBB               GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         -                                                                                           &             _             h             L             -                           -                    o    `                                
                                   0             8                           0
                                	              o    h      o           o    ,      o                                                                                                                                   -                                                                              0      @      P      `             @                                                            0                                                                    @       h                                        GA$3a1 h      Y               GA$3p1067         C                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign             GA$3p1067  P      I                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY            =               GA+GLIBCXX_ASSERTIONS   sha2.so-1.8.7-16.el8.x86_64.debug   |K7zXZ  ִF !   t/A] ?Eh=ڊ2N  !k& Z;$10,>Dib5kv
x]\q a-[ul(7O$3^X+{4F J{pRi-rpfP(w|{æ+#kEVfׇRu61?WGR@f#^q;l.c--qEQ[vPR	o:Ɉ`EoԶ	-X6ikU Tz}S~Sq'1ҴϲRla$h<G?4W;lG;PX,'rX,: HO	>{!-M-(gK*+3d!qSGMxÌ*_mlCgKQh@$/n/.fܨo!`{ᇳl7ZU:w:Ob!z 5sVdAeFzF'|
l*>^=1g'%˚!2Ijlp2-{V|?3^KG|@jMQ@O{2O</)~VŸ:&FMl$6W.B,ge{-)mޥxxY%8;&@̺I F{*6VJK"#ǎWy*J|.5bwb<rô&qh LJ` *P[16ívj۞2aUm@Ι4}bXi,ݓ	TQbv..z휔tm utnv(WHڋW$g%T    f~Z   fg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                     8      8      $                                 o       `      `      l                             (                                                   0                                                      8   o       ,      ,      <                            E   o       h      h      0                            T                                                    ^      B       0
      0
      8                          h             h      h                                    c                                                      n             p      p                                   w             @      @      	                             }             L      L                                                 `      `      9                                           $      $                                                  %       %                                                  (       (                                                  -      -                                                -      -                                                -      -                                                 -      -      0                                        /      /      (                                           0       0                                                0      0                                                  81      81                                                  @1`     81                                                        T5      (                              "                     |5                                                          9      1                             PK     Y\N        x86_64-linux/digest/sha1.sonu ȯ        ELF          >    	      @                 @ 8 	 @                                                                                                                          @      @                   8      8      8      $       $                                                             Std                                            Ptd   ,      ,      ,      ,       ,              Qtd                                                  Rtd                                                 GNU eƓ*ؽpI                @   (          sS|CEDVqX                                                                     x                                                                   ,                       F   "                   _                                                                  j                                                                                             
             k                  X                  U     P
             _                   __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize Init_sha1 rb_require rb_path2class rb_define_class_under rb_cObject rb_data_object_alloc rb_intern rb_ivar_set SHA1_Init SHA1_Update SHA1_Finish SHA1_Final libruby.so.1.8 libcrypto.so.10 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                               N         ui	   p                   t
                       @
                    
                                                                                                                                                                                                                                  (                    0                    8         	           @         
           H                    P                    HHq  HtH             5  %   h    h   h   h   h   h   h   h   q%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  H=  H  H9tH6  Ht	        H=  H5  H)HHH?HHtH  HtfD      =   u+UH=   HtH=n  	de  ]     w    UH=   SHH=   H=   HHH5   H1H5  1HHP  H8H=j   HHHHH[]=f.      HHH  HHdigest Digest Digest::Base SHA1 metadata   ;(      TD   l   $             zR x  $          FJw ?:*3$"       D   p           $   \       EHD bJA                           GNU                                                                                                                                                                                                                                                                                                                                                                                             @
       
                                                                          +             6             D             N             |             X             
                                                            o    `             x                   
                                                                                                            	              o    P      o           o    "      o                                                                                                                                                                                                    	                            @       `                                        GA$3a1 X                     GA$3p1067  P
      
                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign             GA$3p1067  
      
                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign    sha1.so-1.8.7-16.el8.x86_64.debug   k77zXZ  ִF !   t/] ?Eh=ڊ2N> ^)U)v3,1?G]]iGʦcӃA5N)({(.8/|gbthwݨ2)d֪On;ʌiԸ(ԋն3b9'Xhm]"N&M#,2)*PB ^e&7b${cEW4E")Wf8۾\6\/'vn",)T k5]R=BGU7l,̛km piԢ
q฼ܱl'p͸dR,:QfJ٦#A-ŽFA qzH2 B]6AYSi!1PM  MK[@I_A=)5qWmt
ߥ]j"B%X-冪K;*p
@.<&DSQUL:{}t4+2OPK$R&z9` 3n|5F'%u&	h~·d#rAi7?N$ZiϹus쵰U4f5630t+G$U#ʑS(o ,=u84q>]A]pe\7,mjož\tjؑxy`,CyX'{Ըi-,ULULܣOeESGFm*VVޠiP)4R薔@maZ(2Ŋ;v hJ?   dg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                 8      8      $                                 o       `      `      8                             (                                                   0             x      x                                   8   o       "      "      (                            E   o       P      P      @                            T                                                    ^      B                                              h             X      X                                    c                                                      n             	      	                                   w             	      	      b                             }             
      
                                          2                   )                                          ,      ,      ,                                           X      X                                                                                                                                                                                                                                                                                        @                                                    (                                                        X                                          `      `      8                                                                                                    `                                                             d      (                              "                           X                                                         1                             PK     Y\7Ǡ        x86_64-linux/digest/md5.sonu ȯ        ELF          >    	      @                  @ 8 	 @                                                                                                                            @      @                   8      8      8      $       $                                                             Std                                            Ptd                     ,       ,              Qtd                                                  Rtd                                                 GNU 	P+g(                B A           ^U|CEqX+qZ                                                                     w                                             ,                       F   "                                         ^                                                                                                              i                                            U     @
             f                  S                  Z                       
              __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize Init_md5 rb_require rb_path2class rb_define_class_under rb_cObject rb_data_object_alloc rb_intern rb_ivar_set MD5_Init MD5_Update MD5_Finish MD5_Final libruby.so.1.8 libcrypto.so.10 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                       t
            I         ui	   k                   0
                   	                                                                                                                                                                                                                                  (                    0                    8         	           @         
           H                    P                    HHy  HtH     5  %   h    h   h   h   h   h   h   h   q%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  H=  H
  H9tHF  Ht	        H=  H5  H)HHH?HHtH  HtfD      =   u+UH=   HtH=~  	du  ]     w    UH=   SHH=   H=   HHH5   H1H5  1HH`  H8H=i   HHHHH[]=f.      HHHn  HHdigest Digest Digest::Base MD5 metadata    ;(      TD   l   $             zR x  $          FJw ?:*3$"       D   p           $   \       EHD bJA                           GNU                                                                                                                                                                                                                                                                                                                                                                                                             0
      	                                                                         &             1             ?             I             w             P             
                                                            o    `             x                   
                                                                                                            	              o    H      o           o          o                                                                                                                                                                                                                               @       \                                        GA$3a1 P      
               GA$3p1067  @
      
                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign             GA$3p1067  
      
                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign    md5.so-1.8.7-16.el8.x86_64.debug    /7zXZ  ִF !   t/] ?Eh=ڊ2N> ^)U)v3,1?G]]iGɢcӃA< dJvmk XCTBvE/|Hx=&;T_y	Ԏ;:(ͩFʷ󓔬h<]GXhL=.I^
[IP<*̮ EQ8#ծFn!P[rA[9r˘1p|On,_eH@|B6<0Sc$p/*^SI]W3QHڜ 5Hv_-xOeгӯm6AEW<As	Bf#"GW߇5<?ǡYOʚ')Y^yw,hscj|kIUȩ
4&yN&}XL!>G^a¿H-jifl͒DwFtUE@Rԏ:Ϩ3_{:{J-3{xČ
nD@1ej5v
vH؆ztR՟(6i^y.3-]:9&!Giɽ*xWxc%g&>X]\b#2/~h
js`r=$¬G/ney#ɠ|u]{d9@VYwX%@6Y'D$4s=HW|W"Ð)-D=tmH Mzyajܟ	v!['N1({c}~*
u3ȧfKe	    ޛ    8)g    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                     8      8      $                                 o       `      `      8                             (                                                   0             x      x                                   8   o                   (                            E   o       H      H      @                            T                                                    ^      B                                              h             P      P                                    c             p      p                                   n              	       	                                   w             	      	      b                             }             
      
                                          2       
      
      (                                                      ,                                           H      H                                                                                                                                                                                                                                                                                        @                                                    (                                                        X                                          `      `      8                                                                                                    `                                                             d      (                              "                           \                                                         1                             PK     Y\pC        x86_64-linux/digest/rmd160.sonu ȯ        ELF          >    	      @                  @ 8 	 @                                                                                                                            @      @                   8      8      8      $       $                                                                Std                                               Ptd   <      <      <      ,       ,              Qtd                                                  Rtd                                                 GNU ?%,CA9uON l                D A           b&|CEqX                                                                     z                                             ,                       F   "                   a                                                                                                                                    l                                            U     `
             ~                  k                  r                       
              __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize Init_rmd160 rb_require rb_path2class rb_define_class_under rb_cObject rb_data_object_alloc rb_intern rb_ivar_set RIPEMD160_Init RIPEMD160_Update RMD160_Finish RIPEMD160_Final libruby.so.1.8 libcrypto.so.10 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                      t
           a         ui	                      P
                   
                                                                                                                                      	                                                                                            (                    0                    8                    @         
           H                    P                    HHa  HtH             5r  %s   h    h   h   h   h   h   h   h   q%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  H=  H  H9tH&  Ht	        H=  H5  H)HHH?HHtH  HtfD      =}   u+UH=   HtH=^  	dU  ]     w    UH=   SHH=   H=   HHH5   H1H5  1HH@  H8H=l   HHHHH[]=f.      HHH^  HHdigest Digest Digest::Base RMD160 metadata ;(      TD   l   $             zR x  $          FJw ?:*3$"       D   p           $   \       EHD bJA                           GNU                                                                                                                                                                                                                                                                                                                                                                             P
      
                                             #             3             >             I             W             a                          h                                                                         o    `             x                   
                                                                                                            	              o    `      o           o    4      o                                                                                                                                                                                              	      	                            @       `                                        GA$3a1 h                     GA$3p1067  `
      
                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign             GA$3p1067  
                      GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign    rmd160.so-1.8.7-16.el8.x86_64.debug g܃7zXZ  ִF !   t/] ?Eh=ڊ2NH@> +p)o·]]h]pƷך9Dp^B+{RkRa!mVGݡpqJ eGXhWf.y=ĦV)&/I!^
>flh,yJPITC+^0xQ(7DM)M=OoaP%Q u
"E)|6{Ŗ]l(4WWS#W.ȣ͖ݘD{0T\q>ugxzy'9  {0)GvZyC%C2OX=@`׀1s@ -y9\>tF)L=78qyz5rB1f;Eq9xCFeG0_"4Ah8/FoS `OMW:ܱB$6I*
5EL2dݕ<Q&"2&%'*	P>}>*'p#`ʜ6#l/_r|`gj΁BJ8cҵq%aEOuʉ %U\|}^q o(vVVB䍢5j5j$0GiM@ab
8C>nBӍӋxbeV\-QXȉ>'o ,kKאK{d^C(*зN8䅶X%z\wk:l=C{I  vŮ=   ;Pg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                 8      8      $                                 o       `      `      8                             (                                                   0             x      x                                   8   o       4      4      (                            E   o       `      `      @                            T                                                    ^      B                                              h             h      h                                    c                                                      n              	       	                                   w             	      	      b                             }                                                             2                   +                                          <      <      ,                                           h      h                                                                                                                                                                                                                                                                                          @                                                    (                                                        X                                          `      `      8                                                                                                    `                                                             d      (                              "                           `                                                         1                             PK     Y\;.  .  #  x86_64-linux/digest/bubblebabble.sonu ȯ        ELF          >    0
      @       '          @ 8 	 @                                 H      H                                                                                  0      0                   8      8      8      $       $                    (      (      (                             Std   (      (      (                             Ptd                     D       D              Qtd                                                  Rtd                     p      p                      GNU NZ"ħvR^$                @              BE\1A|qX                                                                                                                     U                                                                                                                                                                               p                      e                      ,                       F   "                   s    x                                                    z    x                __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_string_value rb_str_new rb_eRuntimeError rb_raise rb_funcall rb_funcall2 Init_bubblebabble rb_require rb_path2class rb_define_module_function rb_define_singleton_method rb_define_method rb_intern libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                           i         ui	                      
                   
                                                                                                                                                                        (                     0                     8                     @                     H          	           P          
           X                     `                     h                     p                     HHQ  HtH     5b  %c   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1%  D  %  D  %  D  %  D  %}  D  %u  D  %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  H=A  H:  H9tH  Ht	        H=  H5
  H)HHH?HHtHe  HtfD      =   u+UH=B   HtH=  Yd  ]     w    AWAVAUATUSH(H|$H|$HD$H*LhL`LHH9  Ht@1HD$H@HD$ xM  HD$M   E1A   IH-F  AHxL$  A)s    CDIG-A>HAWHAWB4    D)AAAø98AD)M9   CHAAEADARA)McBD DوGȃAGAщAR)HcD GM9xHD$H([]A\A]A^A_fD  DAyLcAYMcHcHcR)D HcL5 Ht$BHBx>뛻   a      A   e   A   H  H5@  H81VfD  HH5Q  11XHHff.     H@ HHH5  H׉BHHffD  ATH=   USH=    H=   IH=   HL   HsHH5   HHeH5   H1HH5z   H=A   []HL  A\ HH           digest string too long digest Digest Digest::Instance Digest::Class bubblebabble                bcdfghklmnprstvzxaeiouy ;D      `      (   X       0             zR x  $      p    FJw ?:*3$"       D              H   \   *   BBB B(A0A8D`
8A0A(B BBBG      d$    HT       |             x*    HZ (          FHA AI               GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
      
                                +             ;             F             Q             _             i                                       8                                                            o    `                                
                                                                             `                                 	              o          o           o    T      o                                                                                                                                                                                        	      	       	      0	      @	      P	      `	               GA$3a1       E               GA$3p1067  
      7                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY     
                     GA+GLIBCXX_ASSERTIONS   bubblebabble.so-1.8.7-16.el8.x86_64.debug   e{x7zXZ  ִF !   t/G] ?Eh=ڊ2N$=fK> zqbA&@o2Jz_V_)|5gLcS2x ڈ*EkSിQB4T`S-Z*ݙz-4&?0Fe z|<-Bz~y
5w	+M^'Y-ѶzjkLm0X]7ތl,*FFWN/SE
]| +UAtP6QVZɯpKt =oz]^Ue',M.Bo.Įb
8U:d}ҩq\NIM,4J]v~	y֪-JUDcg_Dlo]%_ttU\\՞a],*&]9dP1g-e]k~CH6ؑUH+{^>Bk/ccNL.+F@HHzwI}͹n5ګUb݂A$>'$k}XySpaXD݁_8Jl7YURA'9pq׿Ww!sG/eҠW	]Q7.0?edXe!Yi|O
Q̝_)+4@#&̀ LyEK/X@y9i[8ƒ.q(Pw"[$JlND!1D!|}.FN(0lYCfJ2>i!'S+<sUMhCIQ{*g>Wk)z+2Y  NZ   ۱g    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                   8      8      $                                 o       `      `      4                             (                                                   0                                                      8   o       T      T      *                            E   o                                                T                                                     ^      B       `      `                                 h                                                       c                                                      n             p	      p	                                   w             0
      0
                                   }             8      8                                                 P      P      w                                                       D                                                                                                 (      (                                                                                                                                                                                                                                 0                                                    (                                                          x                                          x       x                                                    `     x       H                                                  "      0                                                   "                                                         x&      +                             PK     Y\%0Q  0Q    x86_64-linux/iconv.sonu ȯ        ELF          >           @       I          @ 8 	 @                                 :      :                    8=      8=      8=                                P=      P=      P=      0      0                   8      8      8      $       $                    :      :      :                             Std   :      :      :                             Ptd   05      05      05                           Qtd                                                  Rtd   8=      8=      8=                                  GNU uU^\^8TD>9k/	g       F         @  F   H   I   BE|qX                                                                                                                                                             >                                          
                                                               j                     :                                           3                                                                G                                                                                                                                                                         $                                                                 S                                                                                                                                 w                                           Y                     U                      P                     >                                          {                      [                                                               a                     A                                          m                                                               )                                           j                     y                     ,                                            F   "                                                             a                      o                                                                !                     ,                                                                                    4    A              G     B              ;    A                  @1             __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_attr_get rb_call_super rb_ivar_set iconv_close rb_str_new rb_str_substr rb_string_value_ptr rb_intern rb_funcall2 st_lookup __stack_chk_fail rb_data_object_alloc rb_class2name rb_str_new2 rb_str_buf_cat2 rb_str_buf_cat rb_inspect rb_str_buf_append rb_cFixnum rb_cFalseClass rb_cNilClass rb_cTrueClass rb_cSymbol rb_check_type rb_eArgError rb_raise rb_ensure rb_obj_dup rb_class_new_instance rb_ary_new4 rb_str_cat2 __errno_location rb_exc_raise rb_sys_fail iconv_open __sprintf_chk strlen rb_gc rb_ary_new3 rb_str_append rb_ary_push rb_ary_new2 rb_block_given_p rb_yield rb_string_value ruby_errinfo rb_str_concat memcmp rb_str_cat rb_fix2int rb_scan_args rb_range_beg_len rb_num2long Init_iconv rb_cData rb_define_class rb_define_alloc_func rb_define_singleton_method rb_define_method rb_define_module_under rb_define_class_under rb_eRuntimeError rb_include_module rb_gc_register_address rb_hash_new libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.3.4 GLIBC_2.4 GLIBC_2.2.5 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                               *     @   ti	   L     ii   X     ui	   b                 ui	   b      8=                   @=                   H=             H=      ?                    ?                    ?                    ?                    ?                    ?                     ?         !           ?         #           ?         '           ?         +           ?         .           ?         3           ?         8           ?         9           ?         :           ?         D           @                     @                    (@                    0@                    8@                    @@                    H@         	           P@         
           X@                    `@                    h@                    p@                    x@                    @                    @                    @                    @                    @                    @                    @                    @                    @                    @                    @                    @                    @                    @                     @         "           @         $            A         %           A         &           A         (           A         )            A         *           (A         ,           0A         -           8A         /           @A         0           HA         1           PA         2           XA         4           `A         5           hA         6           pA         7           xA         :           A         ;           A         <           A         =           A         >           A         ?           A         @           A         A           A         B           A         C           A         E           HH)  HtH             5)  %)   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   h2   h3   h4   h5   h6   %]&  D  %U&  D  %M&  D  %E&  D  %=&  D  %5&  D  %-&  D  %%&  D  %&  D  %&  D  %&  D  %&  D  %%  D  %%  D  %%  D  %%  D  %%  D  %%  D  %%  D  %%  D  %%  D  %%  D  %%  D  %%  D  %%  D  %%  D  %%  D  %%  D  %}%  D  %u%  D  %m%  D  %e%  D  %]%  D  %U%  D  %M%  D  %E%  D  %=%  D  %5%  D  %-%  D  %%%  D  %%  D  %%  D  %%  D  %%  D  %$  D  %$  D  %$  D  %$  D  %$  D  %$  D  %$  D  %$  D  %$  D  %$  D  %$  D  H=$  H$  H9tHF"  Ht	        H=y$  H5r$  H)HHH?HHtHe"  HtfD      =5$   u+UH=J"   HtH=  d$  ]     w    H#  @ H5#  H5#  ATIUHSH   HHt$Ht$gH5#  LHeH5#  HHSHH[]A\    HD@ HHcHttLGHWI9tGLH1SHH9tGHHt HH	ڃuHtH   H	[D  HH9u    L)HHrH8     SHH dH%(   HD$1HHD$H"  H@Ht@u!HHL$dH3%(   u]H [ H=  H|$11HH|$HD$Ht$HT$H3"  HxtHD$Hff.     @ H11ff.     AUATUSHH   H   H   H      H{7H5!  HIEH5!  HI3H=  HTLHY   H5  HLHHH_   H5Z  H[HHHH5H   H5/  [H]A\A]'    H  H85H  H8%Hy  H8H  H8H  H8S"   HHH9CuHC [u:HtLHt;HtYtHH{H5  HHR  H81@H  H8H  H8H  H8H-  H8H  H8@ SHSHt&HC     HH  HH=r  [@    [ÐAVAUIATIUHSHH dH%(   HD$1Mt
A8    Htut?uH{   HH$Ld$H\$Ht#H}Lu 9LHAHc}HD$CHL   #HL$dH3%(   ujH []A\A]A^fD  LH$fHuHHD$D  1   HIH1H5  HH$D@ SH u#I1ɺ      H={  HNHfD  HH$tHH=w  ff.      Hu   ÐH   Hff.     fAWMAVIAUIATIUSHHMLH     LLHHt+H; uAH   HEH[]A\A]A^A_f.     HHtߋE tH~&t1Tu@H  H[]A\A]A^A_fD  u HM   HQ      1H=       AUATUSH(H|$H|$H4$#HHHHHHtH([]A\A]f     D IA      H  HT$H$1H@HBHtHT$HIHD$ HD$    H  LJHHxHD$p1RHD$(HXHHT$(HBXZAt`H        DH uAI   H8  D HHHEe H$Ht$   1[I1ɾ   H=  HHzf.     ATIUHSHHu%HC     LHBHHC H[]A\ HfD  U1HSH1HHHL$dH%(   HD$81HD$D$   HD$ H  HD$0DHHHD$(HHt$HD$HH=y	  HqHT$8dH3%(   uHH[]D  SH0dH%(   HD$(1~nHFHHD$HL  |$HcHD$ {HsH;HD$*HHH=  H$HHHT$(dH3%(   u%H0[H     H5  H81PSHHH1HHQHHH.u
H[D  H=a  HH[HFfD  AWAVAUATUSH   H$ H   H$ H   Ht$HLD$(dH%(   H$   1H  H|$HIa  H|$HHHHD$HLxHc@IL|$`HxHHH9}H)HHD$xL$   H$HD$pHD$HD$hHD$HD$`HD$H$   HL$hL1HD$ HD$HHD$0L$HL$LLl$pHT$Ht$HD$x    Ƅ$    tIHD$xH=          H)HL$xIt%LD$`LL)H9w'  H|$h    H|$H  I)H  LHH"HT$xLHL|$`HLI   H  L9  T$hH|$HLGLD$ LHHL$(HIHD$HI*  H@  LL IĨ  Ht=H  H  H  <   ?	  M|$MWL|$`H  L9`  H$   dH34%(   H  H   []A\A]A^A_@ HD$hH-ID$ HH0ItID$ H@HD$HH{H|$0XHT$HHjHBHl$`IHD$h@ A    H|$ 2   H  I)   1RL%S  L|$`ZLH+HHT$HHH   H	D  LH|$HHH)mL|$`HH  L$   HD$h    HD$`HD$`LD$xHL$pHT$hHL$Ll$pHD$x    HL$HT$HD$vH
  HD$`    E11    LH|$HHH)H%D  HLuL|$`H1     HLLLD$@HL$8HL$8LD$@H|$h tnMfD  LHHH)OL|$`D  LHHH)/f.     HLLHL$8HL$8HIL|$`| HL$(E1   HǾ   vH   H     HHt2u.<t*?	u Hx ~yH@ H8HH|$HD  H|$HHHu HdH|$HU    =   v2H|$HHt LHMaHD$H   H|$_   D$_HD$HL5HF  H5  H81-HAUATAHUHSH8dH%(   HD$(1IQHLL$LHLD$1DHj  1HD$    HD$     	H<$tLzHhH|$A   Ht'@   HHHT$H   H9   HL$Ht_   HHT$HL$ H)H9Hl$ HH4$HE1HHt$(dH34%(      H8[]A\A]     HHT$HL$ D  HHT$pHL$  E1HT$ Ht$HHu#H|$f     kH HL$ HT$HHHHff.     HE111Ҿ        ATUSGH~^HGI H(H;1ILHH{HS CPHCSHHCHuHC[]A\     H;11Iؾ   <Hx tH{HS HC[]A\fUH=/  SHH0  H0H5iHHH߹   HH5  H߹HH5  H߹   HH5  H߹   HH5  1HHH59  HHH5L  oHH5v  0   HH5S  HH  >H=  1HH5@  "H=  1HH5,  H=  1HfH5  H-K  HH5	  HU HU HH5  HS  HU HH5  H)  H-  HH5  H  HU HU HH5  H  qH5  H=  H  H5  H=  H5  H=  H5  H=  H5  H=p  H=  H=	  HI  |H=-  H.  )D1HHH	  HH5   []   HH       downcase #< :  ,  > Iconv expected (%s) ... iconv_close invalid encoding  %s("%s", "%s") closed iconv bug?(output length = %ld) 12 Iconv open initialize Failure success failed inspect InvalidEncoding IllegalSequence InvalidCharacter OutOfRange BrokenLibrary charset_map   wrong number of arguments (%d for %d)   ;         0  H  \  p    @  P      $  `  |       `    ,    0     0  T  0t    P  p  T             zR x  $         FJw ?:*3$"       D   Hp             \   `          p   \             X       ,      TY    FDD L0w DAB                         ayFPP           AG0K
AD    $         8   8  O   FBA A(G0
(M DBBL    t      A_
A     ,?    Ej
IF @     L,   BBE D(D0GP
0A(A BBBG      8:    A       `"    DQ
A     (  t#    TN `   @      BEE E(D0A8G@~
8A0A(B BBBKg
8A0A(B BBBG  D        BBA A(DPv
(A ABBJGXp`bXAP (     PJ    FDD k
ABD(     t    EFI`
AAA     D      ED@
AA    h  tZ    Eu
FN T     `   BBB B(A0A8G L@LBx
8A0A(B BBBE   8        FBG D(D`
(A ABBI      @       4   0  L    FAA \
ABIjAB  (   h     EHD HA                    GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         H=                                                                                            *             n                          3             8=                           @=                    o    `             	                   
                                   @             (                                                           	              o          o           o    $      o                                                                                                                                                                                                                           P=                      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                                 GA$3a1       3               GA$3p1067        3                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY                          GA+GLIBCXX_ASSERTIONS   iconv.so-1.8.7-16.el8.x86_64.debug  z}7zXZ  ִF !   t/C] ?Eh=ڊ2N.]@F@N}eql,h>L2}sF%Bm}Vjq]3`V7q:~<44Ft?N>Xm~`c#1lб*f8%V oڧGbOm$=
[-]V|yszn;qˢnIe2B|@p2D:XeúeI{`/U^4rh)6SEIݑY
9|1]c$*A'%Ê8Y;.0E{_g	
KoIg>ogLBh̒ϕE3%tm5a0J[=%V!hauW.b@h)Ojc6|VwVЛ:zc`B$C}(#8Ӑ]'fipl>b.xXLJOGaUG_3KD+#@Q·b0nD; fN=EWs*PrzN椇cWT~\P2S,K>4^]}xy䒄
]5ޏȯsf-vZJ	p6
ia`w!5Wi,#b:*Se#VDyB,:SKF3zJh}'`a@<)yx93k'Fpřk<b;~Cn$Nb^*VI15.tH'A˲Vnbi0VVp	eMku(CwemD&ۀ,9L`E5%]rO\cJ/KvRk/`yEV
i#WLV𦼬W
JvBx`g/)u]->{V/aR8f=vp	I K#LCb\ig>8utrt5`#:4[G  ']ح #  ig    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                               8      8      $                                 o       `      `      4                             (                                                   0             	      	                                   8   o       $      $                                  E   o                   `                            T                                                    ^      B                   (                          h                                                       c             0      0                                  n                         p                            w                                                        }             3      3                                          2       3      3      8                                         05      05                                                  6       6                                                :      :                                                  8=      8=                                                @=      @=                                                H=      H=                                                 P=      P=      0                                        ?      ?                                                 @       @                                               A      A      P                                             B`     A      H                                                  D      (                                                   @D                                                         H      +                             PK     Y\a7` b   b    x86_64-linux/gdbm.sonu ȯ        ELF          >          @       Z          @ 8 	 @                                 `J      `J                    @M      @M      @M                                XM      XM      XM      @      @                   8      8      8      $       $                    @J      @J      @J                             Std   @J      @J      @J                             Ptd   8?      8?      8?                         Qtd                                                  Rtd   @M      @M      @M                                  GNU ]0*9c       B         @$  B   D       BE|VqX                                                  t                                                                                                                                 3                                                                                    K                     (                                           [                                                               +                                                                                                                                                                                                                                                                  U                      E                                                               e                     }                                            Y                     >                     A                     u                                                               z                                                                N                                          c                      )                                           Z                     ,                                                                 5                     k                     s                     F   "                                                                                   j                                                                                         Q              
    Q                  6      n          Q               __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_check_type rb_eRuntimeError rb_raise gdbm_firstkey rb_str_new free gdbm_fetch rb_string_value gdbm_nextkey rb_hash_new rb_hash_aset rb_ary_new rb_assoc_new rb_ary_push memcmp gdbm_exists rb_iterate rb_intern rb_funcall rb_hash_delete_if rb_yield rb_ary_new2 rb_block_given_p rb_warn rb_eArgError gdbm_close rb_scan_args rb_fix2int rb_num2int rb_check_safe_obj gdbm_open gdbm_errno_location rb_sys_fail ruby_xmalloc gdbm_strerror __stack_chk_fail rb_data_object_alloc rb_ensure gdbm_setopt rb_secure rb_error_frozen gdbm_sync gdbm_reorganize gdbm_delete rb_protect rb_jump_tag gdbm_store __errno_location rb_eIndexError Init_gdbm rb_cObject rb_define_class rb_eStandardError rb_eException rb_mEnumerable rb_include_module rb_define_alloc_func rb_define_singleton_method rb_define_method rb_define_const gdbm_version rb_str_new2 libruby.so.1.8 libgdbm.so.6 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 GLIBC_2.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                                     ui	                    ii        ui	         @M                   HM             P      PM             PM      O                    O                    O                    O                    O         !           O         *           O         +           O         0           O         4           O         5           O         6           O         9           O         :           P                     P                    (P                    0P                    8P                    @P                    HP         	           PP         
           XP                    `P                    hP                    pP                    xP                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                    P                      Q         "           Q         #           Q         $           Q         %            Q         &           (Q         '           0Q         (           8Q         )           @Q         ,           HQ         -           PQ         .           XQ         /           `Q         1           hQ         2           pQ         3           xQ         7           Q         8           Q         :           Q         ;           Q         <           Q         =           Q         >           Q         ?           Q         @           Q         A           HH:  HtH             5:  %:   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   h2   h3   h4   h5   %7  D  %7  D  %}7  D  %u7  D  %m7  D  %e7  D  %]7  D  %U7  D  %M7  D  %E7  D  %=7  D  %57  D  %-7  D  %%7  D  %7  D  %7  D  %7  D  %7  D  %6  D  %6  D  %6  D  %6  D  %6  D  %6  D  %6  D  %6  D  %6  D  %6  D  %6  D  %6  D  %6  D  %6  D  %6  D  %6  D  %}6  D  %u6  D  %m6  D  %e6  D  %]6  D  %U6  D  %M6  D  %E6  D  %=6  D  %56  D  %-6  D  %%6  D  %6  D  %6  D  %6  D  %6  D  %5  D  %5  D  %5  D  %5  D  H=5  H5  H9tH3  Ht	        H=5  H55  H)HHH?HHtH3  HtfD      =m5   u+UH=3   HtH=0  dE5  ]     w    S"   HnHC HtHx [HD     [f     PXH5   HH2  H81fPXH5   1HHH=4  nff.      USH%Ht@HHcHHH'@uHtHM    HH[]fD     HH[]ÐS"   H~HC HtAHxHt8 x    t[D  Hu   [    H1[1ff.     fUSHeHt@HHcHHHW@uHtHM    HH[]fD     HH[]ÐSHHH|$Ht$	HD$HHpP1sH[ff.     fUH"   SHHjHC HtHxHtHH1[]1@ 1     UHSHHvP+Ht>HHcHHH]@uHtHM    HH[]@    HH[]f     AT"   USHHC HteHhHt\4HI1HHt7@ HH1HLH=HH1 HHuL[]A\1fD  ATUSH"   HIHC HtbHhHtYH1HHt<f     HH1HLHHH1HHuL[]A\1^ff.      AW"   AVAUATUSHHqLk M   MeM   IcE ~HHD []A\A]A^A_ LpHHtPE1D  HLA!HIHcLHMuIcHD Eu H[]A\A]A^A_D     E11    AT"   USHHC HtmHhHtdHI1HHt?@ HH1HHLHHH1HHuL[]A\1ff.      AW"   AVAUATUSHHHC HtL`MtvZLIHHHtI@ HHLHLII1HHLHHLLPMuHL[]A\A]A^A_12fAT"   USH[HC HtUHhHtLHI1GHHt'@ HLHH1HHuL[]A\1fD  USHHH|$Ht$4"   HHC H   HhH   H1HHu ffD  HH1SHHtH1HHHtHL$HQH;PuHpHyuH   []f     H1[]1USHHH|$Ht$d"   HHC H   HhH   H1HHu ^fD  HH1HHt@1HHHtHL$HQH;PuHpHy)uHH[]    HH[]1fATUSHHH|$Ht$HD$"   HL`hHC Ht(HxHtLHlH[]HA\1SHHH  H=   H[ff.     fSHH=  \H11H[1f.     H1HHD  U"   HSHIHE HtfHxHt]1@HHtAD  H("   HHE Ht(HxHtH1HHuHH[]1 AT"   IUSID$ HtvHXHtmH1HHtP HH1H"   LnID$ Ht)HXHt HH1HHuL[]A\1@ AT"   IUSID$ H   HhHt|H1
HHt_    HH1HH H"   LID$ Ht)HhHt HH1kHHuL[]A\1AAUHcATIIUSHH1HE~*AELlH3L1HHHL9uHH[]A\A]Ð1     AUHcATIUHSHHI     "   LID$ H   HhH   H1HHuP       "   LID$ H   HhH   HH1+HH}   HH1HHHH9HtHL@ 1H=  2~/EHlfD  H3L1H_LHH9uHL[]A\A]1zH&  H5b  H81S"   HH[ HtH{HtHC       [1!HtSHHHtH[@     AUATIH  U  SH(dH%(   HD$1ILL$LD$Lt!H|$Ht@  ZH|$H   @   zL H<$7       H$߉   LQHxIM   [  8t8	t8
  H$Hx@ l@ L1fH<$H$HxxyL   yIHtQ   I|$ H1XI\$ LLkHL$dH3%(      H([]A\A]    H$HxLO1ɾ    IHuH$L-1ɉھ   HxI \@ 8H=%  H5  H1l@    Hf     Hu11\ff.     ATHSI1UH1S0LHH1^HtuH[]A\       H[]A\ H="  HH[H]A\ PXH8H=$  H5  H1fD  UH"   SHHdH%(   HD$1HC HtLHxHtC1HT$   H   D$t&HL$dH3%(   HuH[]1Je1>ff.      UH"   SHHdH%(   HD$1FHC HtLHxHtC1HT$   H   D$0t&HL$dH3%(   HuH[]11ff.      UH"   SHHdH%(   HD$1HC HtKHXHtBHHT$   H߾   D$t&HL$dH3%(   HuH[]1&1ff.     @ SH   uHtHu[H=  ff.      S1H"   HHC HtHxHt
H[1qS1Hq"   HHC HtHxHt
H[11AW1AVAUATUSHHH|$"   HBLs M   InH   AHXIHHur cMLMtHHLHHILIfH߅t*MtLH8aH=b!  H5  H1	A    HD$H[]A\A]A^A_17    U1HSHHHHH  H=HH[]fD  AV1AUATUSHHHt$H|$kHD$"   HLpDhHk HtbLeMtYLLLAt5LLLOu<U H؅xU H[]A\A]A^fD  H   []A\A]A^1?E 8H=   H5O  H1@ AT1USH"   H1HC HtRL`MtIL1%HHt,HL1?HHI1[LH]A\0[   ]A\1ff.     @ AWAVAUATIUSH(dH%(   HD$1LD$    I1Q"   LtIl$ H4  LuM'  E E LD$1QHH   L|$C "   LIl$ H   LuM   HL1HHtPHL1HH H=Y  LHT$uHtHLcvfD  IE1H~$D  IE LH41HBIEH9|$u;L$~)M HL$dH3%(   LuH([]A\A]A^A_1aAV1AUATUSHHHt$H$H|$SHKHD$"   HHhD`H$LhDpHC Ht{HxHtr LMHA   Lt28t@8,H=-  H5_  H1@ H$H[]A\A]A^    11f.     UH	   SHHH{~HC HHPH0H   []H  H5  H81H     AUATUSHH  H(dH%(   HD$1HL$LD$WLd$H1Ll$L HHt't0HT$dH3%(   Hu]H([]A\A]@ It2LuMHuŅuH  H5H  H81 #tLHff.     fAT1IUHS[HHtHL1H[]A\D  tHHfHH  H=  H02H=  H4  H  H0H=  H  H  H0H=  H  H  H0H=  H5=H=  HEH5H  iH=  HH5.  :H=  1H*H5  H=w  1H.H5  H=[     HOH5  H=<  HH5  H=     H1H5  H=     HH5  H=     HH5  gH=  HtH5n  HH=  HUH5W  )H=  HH5@  
H=c  HwH5(  H=D  1HH5  H=(  1HH5  H=  1HH5  H=  1HH5  {H=  1H;H5  _H=  1HH5  CH=  1HH5  'H=  1HGH5~  H=d  1H{H5g  H=H  1H/H5R  H=,     HpH59  H=  1HH5$  H=  1HhH5  |H=  1HH5  `H=  1HH5  DH=  1HH5  (H=     HH5  	H=b     H&H5  H=C  1HH5  H='  1HnH5~  H=     HoH5d  H=     HH5P  tH=     HH5;  UH=     HH5&  6H=     HsH5  H=p     HTH5  H=Q     HH5  H=2     HH5  H=     HWH5  H=  1HkH5  H=  1HOH5}  cH=    @H5m  kH=    @H5\  SH=    @H5K  ;H=t    @H5;  #H=\  !   H5)  H=D  A   H5  H=,     H5  H  H8H=  HH5  H  HH   closed GDBM file %s each_pair 12 GDBM pair must be [key, value] 11 key not found GDBMError GDBMFatalError open initialize close closed? [] fetch []= store index indexes indices select values_at length size empty? each each_value each_key keys values shift delete delete_if reject! reject clear invert update replace reorganize sync cachesize= fastmode= syncmode= include? has_key? member? has_value? to_a to_hash READER WRITER WRCREAT NEWDB FAST SYNC NOLOCK VERSION       wrong number arguments(%d for 0)        GDBM#select(index..) is deprecated; use GDBM#values_at  ;  4     H  h  (  D  `  X    (  h  <  P  (    X  (H  x  x    ,  d    8  h      D  ht      H    4  p  (      x  <  h    8  x  x	  0	  	  (	  
  T
  
  
  H
             zR x  $      p   FJw ?:*3$"       D   P`             \   X7    E\
OF    |   x    AAK        |"    EAM  0      _    AAD ~
DAGIDA $      c    Em
FP
HK
A0     _    AAD ~
DAGIDA    D  03    AG iA (   d  P<    AIG [
FAB       d       0     `g    ADD E
DAEIDA,         FFA r
ABA   ,         FAA 
ABA   `   8  l    FGB B(A0A8G@k
8F0A(B BBBDP
8A0A(B BBBF ,         FFA z
ABA   H     H    FGB B(A0A8G@
8D0A(B BBBA ,     z    FFA b
ABA   4   H      EAG0
FAJD
CAA 4         EAG0
DADI
DAA 0     ,o    FAA G0N
 DAEA      h#    E]        |&    EZ      $      HK (   <      EID n
DAA ,   h      FIA 
ABA   ,     l    FIA 
ABA   4     _    FEG A(G0{(D ABB              8     p   FED D(G0+
(D ABBA   P  D?    Er
A   l  h)    JU  8     |G   FBK F(DP
(A ABBH            @     }    FMH j
ABHI
ABDNHB        *    AAD  (   8      EIG0g
AAA (   d  `    EIG0g
AAA (         EIG0f
AAA      H2    Ad
A     l?    Er
A     ?    Er
AH         FDB B(A0A8GP
8A0A(B BBBA $   \  h:    EFG bDA T         BDB A(A0G@x
0A(A BBBGD
0F(A BBBA8         FCA X
GBEA
FBA   H     \   FBB B(D0A8D`n
8A0A(B BBBA@   d      FDB A(A0G@
0A(A BBBH (     \X    EIG c
FAA  8         FBA C(NP[
(A ABBE (   	  4N    FFD _
ABF   <	  Xn   HW                GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   P      PM                                                                                                                     %                          <             @M                           HM                    o    `             (	                   
       R                            P                                                     X                   	              o          o           o    z      o                                                                                                                                                                                                   XM                             0      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p               GA$3a1       <               GA$3p1067        <                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY                          GA+GLIBCXX_ASSERTIONS   gdbm.so-1.8.7-16.el8.x86_64.debug   s"7zXZ  ִF !   t/] ?Eh=ڊ2N&$+Lxe+Fc}q]f鴓-ʰtvqEel.4iv>K>ucJ>YXxy845lػ_涣uZa@fZېʺCywG|EgFYMiS^+B2b\%R f#㸢fg@Z@)@ʸ_[רK^Ir7"9&fou:J;T\*y~vZsuQ4	X4D([o4~"n -KY4 β])S 򌺆xDb!ܦq{OlޱգLU_ņP.&|g?؊Q̆FU0=sF텩\obvIf}Oȿ|T;re~1J<5WE&&]*w+c/(8MD%:0$Kܲq+
O9?쓲Bw(wԸRHE*,-d-?"MćxNDߑuXvPjmy= @UGv%VyB;dB(})TKUfokH^W?{I?jK(J1fp{A)c1-1\Nf]S/di%QH-7ǃBD|t+?6,[ߎ(=a(JNEkPoεpm2B@>61zWVLE^b qY{{+DBi{}W9Kc)-=cv=];X?񭬲z8Г
7e]{k,x
F~r2E2_~\ݒډf;۠Wn}R|nh+~>M%16Jf[EfZ4,I4ޮe>/<UMxfuM;'*ui}jeQ+(3UJx
M#T2Nr{5:%M!Uʛ4uF ^8rOGp7g4!Y*l߄>͌hI?LJEeL"$gS1a<"ƥtjL H[T!ZZ{PJ36;8*b=FhN4]#!{j։!#|Vך
Yȕ>)8UIN|hVR7P  / 
+  kR`g    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                   8      8      $                                 o       `      `      4                             (                                                   0             (	      (	      R                             8   o       z      z                                  E   o                   P                            T             X      X                                 ^      B                                             h                                                       c                         p                            n                         `                            w                         !                             }             <      <                                          2        =       =      8                                         8?      8?                                                @      @      X	                                          @J      @J                                                  @M      @M                                                HM      HM                                                PM      PM                                                 XM      XM      @                                        O      O      h                                           P       P                                               Q      Q                                                   Q`     Q      H                                                  T      (                                                   8T      X                                                   Y      +                             PK     Y\2    x86_64-linux/syck.sonu ȯ        ELF          >    ps      @       h         @ 8 	 @                                                              !     !           `                    h     h!     h!     0      0                   8      8      8      $       $                                                          Std                                         Ptd   \     \     \                        Qtd                                                  Rtd        !     !     p      p                      GNU mB\{h2﹔|`5AfD       q      
   86 2V^Z%pDDXA@X ` (B  Xǃp<p0  1@' D@  $ Dl!PA@ /MP q   r   s   t   u       v   z   |   }                                                                                                                                                                                                                                                                                                  	                                                      !  #  $          %          &      )  %4
#ōΥǂZ8|ysrkHθ`ϋRSjNw8A"R慧~6" :9/_2m)ⶈECӵ#\h#g4S8ST(tH@%Hw4SIBLV_{?94u ah?޼""}KCzsӢTThC+̈M06iݾ]M@hpu>LU>=E6"Jޡ9ɹgMIVv`T䷴
$igɶpP3Y0n(QACP}ot6qX }7ᵧa;JmhJ'{rxj?8/^%rQ 4DfzzԻn!åKX

c lA8+CQs߿~gw_'vpV] mi9DQxqkx<њd 4=X0м
ۙL=[$>!PdI͈n	;tĪpB|X#.e#fJmqA=xN[W|_G	/hBEG	fgKM;TRpi,ntWƬ	۹T=﷌tؾrxI%j}TSwC!BmL628=_Ef%_j3:/';Y1!?"KDRzW
                                             Y                                                               G                     F                                           T                                                                                      9                     n                                           $                                                               
                     
                                          B	                                                                                                                              ^                                           a                                          v                                          h                     ;                     i                     g	                                          #                     )                                                                                                                               C                     	                     /                                                                                                          	                                          
                     O                                                                                                           u                     	                                          U                      &                     	                     q                                           
                     4                     6                     2
                     Z                                                               K	                     D                     ^                     ]	                     G                                                               ]                                          	                     	                                          	                     r	                     u                     

                                          +	                                                                                                          ,                       G                                                               F   "                                                             W
                     g                     	                     i                                                                                     6	                     '                     .     A                                      	       R                                                   t          c       O           1                                                             @B     ,       x    Py                  |      {       ?    B            :    @      	           P                 pw                 S                 `v      	       ~
          S                <                 y           `     ,          |      8                                         t     u      #           `             \          	            \                @     .       !                                      w             w    `                       '          @}             7    `                 ?                Ь                  @u      E       H     x                  u             
          L       ^          :       #    P                 w      	       5                 |    =     8                            P@                Љ      #                       k    0~      H           @      X       C     ~      (                        Y    P             Q                }                 I    0o                             
                 .          ,            C     :       	          -           `      ^       W    Ђ                P                               w      	           p                 P=     `       ~    ~                 !                      L       7    v                 0            2    w      1       a    x                       F                            P      U           `      U       m    <     F       ^    P             S          v          !                 {      .       3    @      _                 D                  D       O    B                0                      
           .     Q           P      p      Q    v      l           0                `>     .           =                A     P           0      @                                        =    pB                z      2       (                     `<     Q       1     ?                      \                       9    .           e                 L    @      :       	    |      |       	          f           Э      v      4    p      
           0      W                       q    p      -           C           $    P      C      
          6       h          N          P{      ~           `R                       :       f    @             	    p            F          G       E    P      M-      +          ;       |                 r    `            x         F           !             .    }      "       \     t      3            u      3       h     [               z      `       W    !                      
                 V           S     ,      w    `w      	           0t                 !             
                     A     Y           w                 w                             t         Y                           P               @      ;           p             5                 w           	      	    @      J       t           {       G                           l                           >     b           =     '                 X           0A     !           `A     !       	    Pz                 pv      X       c
    P      !       (           a       >
    0                 @      R                            <     5           B            ]                                 J    ?     x        __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize memcpy syck_io_file_read fread syck_st_free_nodes syck_free_node syck_assert fflush stderr __fprintf_chk abort syck_strndup calloc syck_parser_reset_cursor syck_parser_set_root_on_error syck_add_sym st_insert st_init_numtable syck_lookup_sym st_lookup syck_st_free st_foreach st_free_table syck_parser_handler syck_parser_implicit_typing syck_parser_taguri_expansion syck_parser_error_handler syck_parser_bad_anchor_handler syck_parser_set_input_type syck_parser_current_level syck_parser_pop_level syck_parser_reset_levels syck_new_parser malloc syck_parser_add_level strlen realloc free_any_io syck_parser_file syck_parser_str syck_parser_str_auto syck_move_tokens memmove syck_check_limit syck_parser_read syck_parser_readlen syck_parse syckparse syck_default_error_handler __printf_chk syck_hdlr_add_node syck_hdlr_add_anchor st_init_strtable __stack_chk_fail syck_hdlr_remove_anchor st_delete syck_hdlr_get_anchor syck_add_transfer syck_type_id_to_uri syck_xprivate strncat syck_taguri syck_try_implicit bytestring_alloc bytestring_append __assert_fail bytestring_extend syck_yaml2byte_handler syck_map_read strcpy syck_seq_read syck_yaml2byte syck_st_free_anchors syck_base64enc syck_base64dec syck_emitter_st_free syck_emitter_current_level syck_emitter_parent_level syck_emitter_pop_level syck_emitter_add_level syck_emitter_reset_levels syck_new_emitter syck_emitter_clear syck_emitter_flush syck_emitter_write syck_emit __sprintf_chk syck_emit_tag syck_tagcmp syck_emit_indent syck_scan_scalar syck_emitter_escape hex_table syck_emit_1quoted syck_emit_2quoted syck_emit_literal syck_emit_folded syck_emit_scalar syck_match_implicit syck_emit_seq syck_emit_map syck_emit_item syck_emit_end syck_emitter_mark_node memset eat_comments escape_seq newline_len is_newline sycklex_yaml_utf8 syck_parser_ptr __ctype_b_loc strtol syck_alloc_str try_tag_implicit syckwrap syckerror sycklex sycklex_bytecode_utf8 syck_resolver_detect_implicit rb_str_new2 rb_syck_io_str_read rb_int2inum rb_funcall2 rb_string_value rb_syck_err_handler rb_eArgError rb_raise syck_emitter_node_export rb_funcall syck_merge_i rb_check_convert_type rb_syck_load_handler rb_data_object_alloc rb_hash_aset rb_syck_bad_anchor_handler syck_new_map syck_resolver_node_import rb_check_type rb_str_new rb_hash_new rb_cHash rb_obj_is_kind_of rb_cArray rb_ary_pop rb_ary_reverse rb_ary_push rb_each rb_iterate rb_ary_new2 rb_ary_store syck_badalias_cmp rb_ivar_get rb_syck_free_parser syck_parser_s_alloc rb_gc_mark rb_gc_mark_maybe syck_resolver_add_type rb_attr_get syck_parser_set_resolver rb_ivar_set syck_resolver_use_types_at syck_emitter_reset rb_scan_args rb_check_string_type rb_respond_to syck_out_initialize syck_badalias_initialize rb_iv_set syck_domaintype_initialize syck_yobject_initialize syck_privatetype_initialize syck_scalar_initialize syck_scalar_style_set syck_scalar_value_set syck_seq_initialize syck_seq_style_set syck_map_style_set syck_node_type_id_set syck_set_ivars rb_ary_entry syck_resolver_tagurize syck_genericresolver_node_import syck_map_count syck_seq_count syck_scalar_alloc syck_seq_alloc syck_alloc_seq syck_seq_value_set rb_check_array_type syck_seq_empty syck_seq_add syck_seq_add_m syck_map_alloc syck_alloc_map syck_map_initialize rb_hash_aref syck_map_add rb_eTypeError syck_map_add_m syck_map_value_set syck_map_empty rb_syck_emitter_handler rb_syck_free_emitter syck_emitter_s_alloc rb_syck_output_handler syck_emitter_emit rb_fix2int syck_new_str2 syck_node_init_copy syck_defaultresolver_detect_implicit rb_num2int syck_emitter_set_resolver rb_str_cat rb_io_write syck_parser_assign_io rb_syck_compile syck_get_hash_aref rb_syck_mktime rb_cTime rb_num2long __memcpy_chk yaml_org_handler strncmp strcmp rb_ary_shift syck_str_blow_away_commas rb_cstr2inum strtod rb_float_new rb_require rb_intern rb_cObject rb_const_get syck_defaultresolver_node_import syck_set_model syck_parser_load syck_parser_load_documents syck_const_find rb_str_split rb_to_id rb_const_defined syck_resolver_transfer rb_cBignum rb_obj_alloc rb_obj_is_instance_of rb_ary_new rb_ary_unshift rb_ary_join rb_str_append rb_str_cmp rb_str2inum syck_out_mark syck_out_map rb_yield syck_out_seq syck_out_scalar Init_syck rb_define_module rb_define_module_under rb_define_const rb_define_module_function rb_define_class_under rb_define_attr rb_define_method rb_global_variable rb_define_singleton_method rb_define_alloc_func rb_include_module fwrite fputc apply_seq_in_map syck_map_assign syckdebug syck_map_update syck_new_str syck_new_seq syck_alloc_node syck_replace_str2 syck_replace_str syck_str_read syck_seq_assign syck_free_members strchr get_inline libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start GLIBC_2.3 GLIBC_2.14 GLIBC_2.3.4 GLIBC_2.4 GLIBC_2.2.5 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                                                                                                                                                                                                                                                                          ii                ti	        ii        ui	         !             t      !            s      !            !     !                 !            b     !                 !                 !                 !            ǃ     !            Ճ     !                  !                 !                 !                 !                  !                 (!            '     0!            3     8!            =     @!            A     H!            E     P!            I     X!            M     `!            Q     h!            U     p!            Y     x!            ]     !            e     !            v     !            i     !            q     !            y     !                 !                 !                 !                 !                 !                 !            ބ     !            ń     !            τ     !            ۄ     !                  !                 !                 !            B     !            	      !                 (!            !     0!            /     8!            ?     @!            O     H!            `     P!            ]     X!            k     !                   !                   !                  !                  !        
           !                   !                  !                   !                   !                  !                  !                   !                    !                   !                   !                   !        v            !                   (!                   0!        "          8!                   @!        '          H!        #          P!                   X!                   `!                   h!                   p!                  x!                   !        r           !                   !                   !        :           !        ;           !                  !                   !                  !                   !                   !                   !                   !                  !                   !                   !                    !        N           !                   !                   !                    !                   (!                   0!                   8!                  @!                   H!                   P!                   X!        W           `!                   h!                   p!                   x!                   !                   !                   !        a           !                  !                   !        b           !                   !        e           !        u           !        y           !                   !                   !                  !                   !                  !        m           !                    !                   (!                  0!                   8!                   @!                  H!                   P!                   X!                   `!                   h!                   p!                   x!                   !        }           !        	           !        !          !                   !                   !        	          !                   !                   !                   !                   !                   !                   !                   !        $          !                   !                    !                   !        ~           !                   !                    !                   (!                   0!        z           8!                   @!                   H!                   P!                   X!                   `!                   h!        &          p!                   x!                   !                   !                   !                   !                   !                   !                   !                   !                   !                   !                   !                   !                   !                   !                   !                   !                     !        !           !        "           !        #           !        $            !                   (!                   0!        t           8!        %           @!        &           H!        {           P!                   X!        '           `!        (           h!                  p!        )           x!        *           !        +           !                   !                  !        )          !        ,           !                  !        -           !                   !                   !        .           !                   !                   !                   !        /           !        0           !                    !        1           !        2           !        3           !                    !        4           (!                   0!        5           8!        6           @!        7           H!                   P!                   X!                   `!        8           h!        9           p!        <           x!        =           !        >           !                   !        ?           !                  !                   !                   !                   !        @           !        
          !                   !        A           !                   !                   !        B           !        C           !        D            !                   !                   !        s           !                    !                   (!                  0!                  8!                   @!                   H!        E           P!                  X!        F           `!        G           h!        H           p!                   x!        I           !                   !        J           !        K           !        L           !        M           !                  !        |           !                   !        O           !        P           !        Q           !                  !                   !        w           !                   !        R            !                   !                  !                   !        S            !        T           (!                   0!        %          8!        x           @!        U           H!        V           P!                   X!        X           `!        Y           h!        Z           p!        [           x!                   !                   !        \           !        ]           !        ^           !        _           !        `           !                   !                   !                   !                  !                   !                  !                   !                   !        c           !        q            !        d           !        e           !                   !        f            !                   (!                   0!        g           8!        h           @!        i           H!        j           P!        k           X!        l           `!                   h!        n           p!        o           x!                   !        p           HH! HtH             5b! %c!  h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   h2   h3   h4   h5   h6   h7   qh8   ah9   Qh:   Ah;   1h<   !h=   h>   h?   h@   hA   hB   hC   hD   hE   hF   hG   qhH   ahI   QhJ   AhK   1hL   !hM   hN   hO   hP   hQ   hR   hS   hT   hU   hV   hW   qhX   ahY   QhZ   Ah[   1h\   !h]   h^   h_   h`   ha   hb   hc   hd   he   hf   hg   qhh   ahi   Qhj   Ahk   1hl   !hm   hn   ho   hp   hq   hr   hs   ht   hu   hv   hw   qhx   ahy   Qhz   Ah{   1h|   !h}   h~   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   %}y! D  %uy! D  %my! D  %ey! D  %]y! D  %Uy! D  %My! D  %Ey! D  %=y! D  %5y! D  %-y! D  %%y! D  %y! D  %y! D  %y! D  %y! D  %x! D  %x! D  %x! D  %x! D  %x! D  %x! D  %x! D  %x! D  %x! D  %x! D  %x! D  %x! D  %x! D  %x! D  %x! D  %x! D  %}x! D  %ux! D  %mx! D  %ex! D  %]x! D  %Ux! D  %Mx! D  %Ex! D  %=x! D  %5x! D  %-x! D  %%x! D  %x! D  %x! D  %x! D  %x! D  %w! D  %w! D  %w! D  %w! D  %w! D  %w! D  %w! D  %w! D  %w! D  %w! D  %w! D  %w! D  %w! D  %w! D  %w! D  %w! D  %}w! D  %uw! D  %mw! D  %ew! D  %]w! D  %Uw! D  %Mw! D  %Ew! D  %=w! D  %5w! D  %-w! D  %%w! D  %w! D  %w! D  %w! D  %w! D  %v! D  %v! D  %v! D  %v! D  %v! D  %v! D  %v! D  %v! D  %v! D  %v! D  %v! D  %v! D  %v! D  %v! D  %v! D  %v! D  %}v! D  %uv! D  %mv! D  %ev! D  %]v! D  %Uv! D  %Mv! D  %Ev! D  %=v! D  %5v! D  %-v! D  %%v! D  %v! D  %v! D  %v! D  %v! D  %u! D  %u! D  %u! D  %u! D  %u! D  %u! D  %u! D  %u! D  %u! D  %u! D  %u! D  %u! D  %u! D  %u! D  %u! D  %u! D  %}u! D  %uu! D  %mu! D  %eu! D  %]u! D  %Uu! D  %Mu! D  %Eu! D  %=u! D  %5u! D  %-u! D  %%u! D  %u! D  %u! D  %u! D  %u! D  %t! D  %t! D  %t! D  %t! D  %t! D  %t! D  %t! D  %t! D  %t! D  %t! D  %t! D  %t! D  %t! D  %t! D  %t! D  %t! D  %}t! D  %ut! D  %mt! D  %et! D  %]t! D  %Ut! D  %Mt! D  %Et! D  %=t! D  %5t! D  %-t! D  %%t! D  %t! D  %t! D  %t! D  %t! D  %s! D  %s! D  %s! D  %s! D  %s! D  %s! D  %s! D  %s! D  %s! D  %s! D  %s! D  %s! D  %s! D  %s! D  %s! D  %s! D  %}s! D  %us! D  %ms! D  %es! D  %]s! D  %Us! D  %Ms! D  %Es! D  %=s! D  %5s! D  %-s! D  %%s! D  %s! D  %s! D  H=s! Hs! H9tH.j! Ht	        H=r! H5r! H)HHH?HHtHk! HtfD      =r!  u+UH=k!  HtH=e! idr! ]     w    ATIUHSHHNHFHxbH)H~BHHVH9vHFHH9sHHH)HHI<, H[]A\    H9r H[]A\     H HHVz
tH9w UH)HH<SHHH   HD  H[]ff.     fHtHH1H 1ff.     fATAUH1SEH   Hj! H  1H;8H;ff.     UHH~SH   HHHHH[]ff.     fSHG@HHtg  H    HC    HCH    HCP    HCX    HC`    HCh    HCp    HCx    Hǃ       Hǃ       [D  H8   HC@@ Hw    SHHH   Ht HHǍYHcH[    H<$Ht$H<$HT$H        H   Ht 1D  SHH   Ht%H5g! 1H   Hǃ       H   Ht%H5g! 1H   Hǃ       [@ Hw    1GÐ1GÐHw     Hw(    w0     Hc   H   HHD@    ~!   HHH   Hxfff.     @ USHH   ~     H   H   uE    H[] 1H=  ǃ      HE HEH   E    H[]fD  S      |   H_HHǃ       H   H       H   Hǃ       Hǃ       Hǃ       HC   HC0    HC8   HC@    H[ff.      AUAATUSHHHc      H   9}bHL$E,$LlAD$    LLHID$Hc   HHH   h   H[]A\A]@    HcHHXHc   H   sD  SG4HtuH   HtHǃ       [ff.      SHH   HtHǃ       HHH   HGHtH4H   HG     H{@Hǃ       HtHC@    HGH[ff.      ATIUHSHHC4      H   L HtHh[]A\f     H-!c! Hh[]A\AUIATIUHSHHHE4        HHXLH   HXMtL`H[]A\A]    L%a! L`H[]A\A]fATIUHHSHLHH[H]A\2fATUSHw`Ht_HWxHG@HII)H)t@HM~LHHC@HSxHC`HHHCpHHChHCXHCPHCHHSxL[]A\ÐE1[]LA\D  Hh HG@tHHGxf     HGhHGPHGHHGpHHGx     USHHG4tD1u"L   H{@  HLAPHHHHHH[]fD  SL   H{@  HLAPH@ UHSHHG4tIu<L   HH{@HLAPHHHHH[]    1@ L   HH{@HLAPHff.      SH3H;HH[ff.         HOhI1H+OPH5     x     SHHHHuWHH{ tH[f     HHD$SHD$H[     ATIUHSHH H   dH%(   HD$1HrHD$    HtHT$8udI$   H   HT$HtH|$HtI$   HH?HHL$dH3%(   uQH []A\ {tHD$LHH HAT$I$   Hu    +HI$   hFfD  UHSHH(H   dH%(   HD$1Ht$HtOHT$Ht$tH|$HtH      HhHD$dH3%(   uH([]ÐHH   f.     AUATIUHSHH   dH%(   HD$1H$    H   ILuMH$H   H{    HtH@HL$dH3%(   H   H[]A\A]fD  H$HuI$   HtaLH&uHLAT$(I$   HHH$Pf HLAT$(HH$H{ ^Hkbf[HI$   yf     ATAUHH~SHHtaHC    EuHk[]A\ H HCHt[H]A\+ff.     UH~SHcHfHcHHHx-privatHe:  HfAA
 +H[]@ AVIAUIATUHcSVH|I	LL tag:HHxA:   HLHfBD#[]A\A]A^ff.     @    fD  S(   A   HøHHC@   HC@   |C     HC  H[f     AUATUSHH  HH9   AHA   HtH   II)IHSH{HCL9   H)HD/HGHt$H9vH)1 DD5 DD7HH9uHȺ
   fHCL)HCH+CH;C   H[]A\A]D  HHL hfD  LHL$H)H@HHH{HwHHSwHCHtPH{HSHL$=H  8   H59  H=>  mH  P   H5  H=c  NH  D   H5  H=  /ff.     @ ATUSH  HH9  IH  H9  F uzHWHnF    H+nHGHH9   It$H)HH.H9s1     HH9uH  HCH)HCH+CH;C   []A\@ HV:A   H     H9
uHH[R   ]A\fHH)H@HHHSHpHCHSHHCHC=Hd  Y   H5  H=  HE  Z   H5  H=  H&  \   H5j  H=  H  q   H5K  H=  ff.     @ AWAVAUIATUSHH(dH%(   HD$1HD$    *HSHHt1ɾA   HLcMtAEr  1LT   HXC  |     HC D$SHPH@HL|fD#IHA
EuM9vL9  M9   11A
  Z   HHD  11ҾM   HHC E1Lt$Hx  ~e@ L1HLLHuHt$HhL   HLLIHFHt$H9HC L9` 11ҾE   H.HLHL$dH3%(   H  H([]A\A]A^A_fD  LHx7L !IHx1LT   HLCc11ҾQ   HHC E1Lt$Hx H    LHILLHSHt$HFHC L9`    t$LH0D$C0fD  N   HHfD  ATUHSHdH%(   HD$11H1HHH5SU! HK1H1   H$   HHHHHqu5L$$I|$HxHŸD
  fE H}E It$HOHHL$dH3%(   u	H[]A\f.     @ HtHH1H@ 1ff.     fH    UHHVUUUUUUUHSH?HHHH)HzHN  1H=  D  HH0?0SAA<ED	HcL0KAȃ?AED	HcT0HT0HH0HtYHt
H[]ÐL  @0?AA<8@9HL0T0D0=D0=
H[]D  H=  AA0A?FDKD0=AA<ED	HcT0HL0T0
H[]fD  H1/fD  UHSHHZ! H4+tOZ!     H=Z! HH   fHH9u1ҹA   L  IHH@uHH=Z! H9   Hu    HHt
tDA   HS   LCMFA   LKB,tJAF    HHAE	EDQAAAE	EADQA	DIH9QH{H9v {=uAB<    HAD	@yH{H9v*{=u$B4    HA	D	@qQ H[]HH9vA=uAHD	ڈQԐSHH@HtH5XR! 1aH{@xHC@    H{HHtbHCH    H{8HtLHC8    [fHc   H   HHD@ Hc   H   HHD@    ~!   HHH   Hxfff.     @ AUAATUSHHHc      H   9}jHL$E,$LlAD$    LLHID$Hc   HHH   h@       H[]A\A]D     HcHH`Hc   H   kff.     fUSHH   ~     H   H   uE    H[] 1H=   ǃ      HE /HEH   E    E    H[]ff.     @ S   q   HH     H@    H@    H    P   HCH   HC(H       HC     HC@    HC8    HCH    HCP   HCX    HC`    HCh    HCp    HCx    H   HH   HHǃ       [ÐHwp    Hwx    SH#HH   HGHtHH   HG    H{XHǃ       HtH[ff.     fSHGXHHt  HCXHCh    HC`[f.     HP   HCXff.     UHSHHHwXHo`HWPH)H~,H(H9rH9HHNHSxHkhH)k`H[]@ Hff.     AUIATIUSHHHGXH   H{`HH)HLH;CPsLL{Lc`H[]A\A]@ H1nH{`HkPHH+CXH)I9~    HLI)I/Hk`H11H{`HkPHH+CXH)L9|     KHCXVfAVAUATUHSHH dH%(   HD$1HD$    HD$    cS$Iąu/   {     H5=  HC$   A$1xC,ƺ   H.HH{@ ItH{8HH}   HHSpHt   t;HD$dH3%(     H []A\A]A^f.     {lB   H5  H<    C$    D  H{@H4$HT$&iH{HH  Ht$HT$  Lt$L]HxM   H  IHH1H|$'LHHPLpH{HHt$   HD$   AD$   fD     @   @   E1A   IHǾ   1Ha  jL
H!%tHL  DHJHDщ HL)L     Ld$LCHxM   H  HHH1H|$HHHP~HVKHHCH^*f.     H   AVAUATUHSHHtHHuuEtQHR; ItJ   H=S  H tX
   H=N  H "  AD$   []A\A]A^ú   H5  Hf.         HH5  H   IyLK   L  LL    S   MȀ:   @ IA:tu:UMcLMpIH)M)HvIP   LH    LL)LHH   H5/  LLH.f   H5  HHHs
HHP   H5*  Hp AUHsHHcU M!     L)HS@ ATIUS`I|$h HuID$XI9D$`t;y[]A\fD  Hc- 
HHcD ~1    D H9QLHHc[H]A\@ H  AUIATUSDA@AH<<wHw    H	AL%   A?j  H     0 LV  HG  Aq@   @
~  
3  A|
uA tA	u	fD  H~$   LH=H       DIE1E1LjHcL%  &AH^  IL9   EIAHvAuA
   HAL)AH~   LL    DDA	   D	    LL)MH9nIL9k[]A\A]       
R  A A	H 	f.        
u|A'tbA"   A]   A}   A    A:   A,A	 t
t	M9     DMjf.     @X     H     8     1D  A9#fD  A	 t
tM9HqA	A uff.     fH   AVAUL-  ATL$UHSH5     LH;    u[H5  HHL9t8    <^wHH;\uغ   LHHL9u[]A\A]A^fHH5q  3H   L5B! L3   HLkjfD  ff.     @ AWAVAH5  AUATUHSHHHT$   HD$IcHL$HIIH9r!Mf
tk   HHI9t1LLx    'uκ   H5)  HI9uHHߺ   [H5  ]A\A]A^A_ A$< t<
tA< t<
u   H5  HcI9tMHM e E~#A<$ tL)H;D$~I9us        H5  HI9IfD     H5h  HI9u%f.     AWAVIֺ   AUIMATML%  UHSHt$H5  LM9sY>\H^w>fIcL>    H5  H\L9t%    Hހ>\H^vĺ   HL9uHH   [H5  ]A\A]A^A_   H5  HL9uD  HcD$  A?   L)H9  L9   f   H5N  HL9SlfD     H5  HL9+DfD     H5  H\L9fD     H5  H4L9fD     H5  HL9   <   <
     H5g  HIHIyf        H5H  HL9SlfD     H5  HL9+DfD     H5  H\L9fD     H5  H4L9fD  *D     H5  HL9fD  IIff.     fAVAH5`  AUIATIUSHӺ   A(   A2   LIXHL9rPfD  L9tSH;
HkuHLH)YL9tLH       H5  A2u[]A\A]A^D  I9vLH)[L]A\A]A^D     H5n  LT       H5v  L4    AWAVAAULcH5  ATIULSHHT$   A(0  |$2E  L=EMcl$HHIH9r-   < uA> tH)L9   f.     I9tuLL{<
uHLH)A< t<
tA< t<
    I9tLML |$2   H5D  uH[]A\A]A^A_L9sLH)HL[]A\A]A^A_D  HLLMLED     H5  L\g       H5  L<       H5  L    AWAVAUATIUSH(Hl$`Lt$hH4$L$DD$MDL$LI
HHD$H9  HDMuAEE1o  |$LHLHD$HILH=  H<$HI  A}  H4$LLMtLu1D$ÃAT$    EAED$	     L$  H|$AM L$   uAU)  Pv&tRD$(w0H5  HcH>    ڃ  u@   H([]A\A]A^A_|$D$   2   E@|$@ AEMЃ)ЃuH<$H5  E1QAE1H  AHDBD$    Ht$AT$,AU D  H<$H5j  R   M|LjoD  AEЃ)Ѓ$H<$ Mc  H<$LO  AD$B  H4$LLsfD  |$@9  @6  5  D  D$     HEfD  H(L   [H5)  ]A\A]A^A_fD     t$LHLAE@ t$LHLnAED  t$LHL]AE@ T$t$MHLAELHLAEf        H5  LAE          fD         D$   D  AVAUATIUSHHI蜿H+  LHIt"AFPvt9AE   []A\A]A^Hߺ   H5  AE   []A\A]A^ AFЃ)Ѓu   H5  HAF   D  AVAUATIUSHWHIܾH  LHIt"AFPvt9AE   []A\A]A^Hߺ   H5U  LAE   []A\A]A^ AFЃ)Ѓu   H5  HAF   D  AWAVAUIATIUSH#HË@	w9H  HcH>@ k~    K  H5  LkLLkH[]A\A]A^A_:f.     C   Lc3Ej     H5w  LFk먐LsuP     L   H5N  L k_     kL   H5  Lѿk0f     LhSDsu
x  A?Lakf     LHC   kf     H5  LQkf     kD3D+0A	L=          LLD9u A~Hc$B0 HcHŅ   1    D  HcH9HL譾H腺FE++(L=/  D     LLAdD9uf.     K)  HL1Hv USHHNHH賻Ut{v)tTuA   H5  HH[]սD  uU   x   H5-  tH[]    HHߺ   [H5  ]醽fD  Ut)ʃ)ʃu   H5j  t       H5N  \       H52  D    AUATUHSHH(H8dH%(   HD$1HD$    HD$    H   HT$H   H{@H   Ht$HT$輸uwHkH   HHx
HC@Dh¿HIHD$A1LHP
@   LEHH1H{@HT$Ht$葻HL$dH3%(   HD$umH([]A\A]ÐH{8HGPHcHT$V@ ˾HHC8    賾HHC@       H-Ž   zf.     SHHChHSxH)HC`H~s
tt~tWHHCh     HPHShHSp@<
   <u%HChHPHShH;SxuHֺHShf:
t;HC`HCh[ÐH踺HCh|    HPHShx
NfD  HHShHSpH;Sxt<
HShD  H`HShf.     WЀF   Hݾ  HcH>@ 1D     f.        f.        f.        f.     
   f.        f.     	   f.        f.     ff.     f   
t1t    1
@ W    AWAVAUATUSHHHH.! H~h H<$H0  D   EuvHChE1H9CP   H-  HFHIƅu@   HChHSxH)HC`H~ 8}HP3  HcL H>D  H訸HChfǃ       HHD[]A\A]A^A_@ HSxEH-*  H)HC`H1  8.  HcT H>f.     HShA  HC`HCh    HSh@	fD   <	t< HChHHChH;CxuHHChѐHShE;.   AF   DHA  jHC`HChD  HSh@-<MwIH  HcH>D  HShHSpH     
  f     E;.gd   轺HIHC`HChjHHD$]PtLshHc LH+sPD$8H9u%t    H*Lsh    D$8D$d   M1ILI_`IGxH)H,  Ls< -  E  <	D  .  <
   <  Mwh{
=  MNMOhMOpM;Ox#  A<4   < #   <
   I_`H"HHIGPI;GHvA   IGHIGhH9  HHNt     HصHSh@ : _  HHShH;Sxu    HShd   E1Ad   HT$EH-3  MHT$IHCxEDHSXH)H  <    t<
  AHC`HSXHHShH98  HMcLmA} ^Ot= Hu)  f     }^F  LLeM9wH$A  L(B     HShHSp@
</yH^  HcH>D  H蘴HSh@ : g  HHShH;Sxu    HShE;.H諳   Hߋ0	HC`D @ HShHSpH   t[
HHShHC`IcHH+sPH9  AF   $@ HгHSh@ : uHHShH;Sxu HShHdHC`D     HShE;.H˲   Hߋ0)HC`D @ HShHSp@<L  < 4  <
,  Lk`L(HLHCPH;CHv   HCHHChI9q  ILUt    HShx
HHShHSpH;Sx)  p@ HShH輺    HShE9.d   HT$A   1HT$Dt$Ad   IIIFxIV`H)HJ  
HBn    =  
e  IFhIFpB<m!  < x   <
p   I^`HHHIFPI;FHvA   IFHIFhH9  HH&tHSh@-<MmH  HcH>f     HShGHPHShx
  D  HC`HCh^HHBHChH谳0  d   δHk`HIE D$8
   <>t<|       DD$8D$    LkhD$     HL9   Le A-t8A+   	H BD`tκ
   1HOLkhD$D  D$(   fD  <   <\(	  HrAHshHspB"<VR  HcD H> HH! D$2   C H(HCh    A E1H-
  MD$     D$d   HCxLc`L)H~A<$-{  A$HcD H> HLchf.     HD|$裯HShL$2fD  8   HSPA    H)Ѐ: DDH軮HSh:#tpV  E1M ID$HChHCpA|$-  IEnD9l$  HC`Mc C7IcEA     ID$HChA|$
uHHChHCpH;Cx   <  <   <
  Lc`L誶HLHCPH;CHv   HCHHChI9
  ILװt뿐ID$HChHCpAD$ IHLch蘭x.
  HFLchLc`2f     Hز1聫{H     H=  HE1҃|$8HE Ic|$2LxHHtMEtHMd
fD  ILuHU |$(HBtHJHLI9I I)ID$HBH$A	  H( HPHShHSpx.HPHShx.HPHShH   '  
HHShHUD@Eu~HChHSx}    HPHShHSpx-bHPHShx-PHPHShH$   
)HHShH٫x%  0C@ HA  "HC`HChD  HHHChPHChHSx HPHShx
HBHChHCpH;Cxg   <6  < %  <
  Lk`LHLHCPH;CHv   HCHHChI9  ILt     HPHShHSp@fD  HpHSxHshHH HHChH9  	t tAD+kPfD  HHHCh耪DE    HkhHHShf: HHShH;Sxu    HAHC`ZHŪHSh: &HHShH;Sxu    L=Q  f     HHShH;Sx>  -<M   IcL> ILch' HBHChz
HCpHChL=  HCxHHShH)H
  
</wIcL>f     E;.HC`A  H)HxHrݬH4$H+HBHChB0<6w5H~   ~ Hs%HBHChBHЀ6w   HH  HshHE9o  BCD= IcAD  IHBHChRE9  KL= HL$ŭHL$IcAD  HShHH-   HHShH;Sxg  -<MwHcD H>HC`A  H)HxHr̫H4$HHH躭D  H蘨HChHSx, HHHKhx
H HHShHC`8:  HPHShD f.     H8HSh    D$   Hct$LìI HSh%    HChHPHShH;Sx  :
HCpHCh@ HBHChz
oAH:f.     HBAHChz tFf.     8 3HHChH;CxuHaHCh HAHSh<:     <]
  <}  HD$MwhxB  ; tHi^  IGhHXI_hHcIw`HcT$HD$ HH)Ht$(H9YH)L   HD$H% L       LLI   NIM9uHD$t$H

   D$Ht$(IH|$ I)LLD=HcAD  <,  MwhMwpC<J  <    <
L  HcIw`M$HD$ HcD$I)Ht$L9XI)H   LLd$(H L0   HLH   ~II9uLd$(D$I
A
B    D$Ht$H|$ MLI)LLDhHcAD  LrMwhA>   IMwhM;wxu@   LMLsh1Hc褢HS`HShHP LzHjH4${   Hv  A  hfD  A   LHT$Ic葩HT$Im@ 8 HSx  HHAHK`>H{M)ԠLLL)覧HCHZI<HH$ HsHHhIVHuHHA  ϤLwfHHHKhx
HfD  H    EnD9l$  HC`McLch C7IcEA     8 D$(tHSPA    H)Ѐ: AEŉD$(HxHD$0  HH  Hc0HShH+SPHH9u	  t$  |$(Ɖt$9  p  9Aĺ   HH{D$? D$ HD$0   |$8
uEtHt$01ҋ|$(9>	@t$ Lk`E1 HKhI9sLת7  HKhII9r|$ AE  |$?   EfD;d$  McIcC7 EA HD$0t$( )Hc׉|$ H)IHKh9dHHC`HCh1负{IR     H=J  6ID$1҃|$8ID$ IcLxHHEtL|$2tEIlHHCuIT$ |$(HBtHJHLH9H H)HHHBH$L A	  	    HAIf.     A~AF      H5{  H=  0HEXIT$HShA|$-   HChHKPHA    H)΀9 DDD  HChHChHHChH;Cx  8
HCpHCh HShHChHPHShH;Sx  :
HCpHChH蓠HShIT$HShAL$4   tj
2HHShLc`L;cP  EnD9l$=  A$McILchC7IcEA $HHSh    : uHHShH;SxuLA  JHx觞J<8^HH$ HsHH赜AT$IuHHcDH號HChD$ D$?D$  A1^LmI_hD$   Hct$LIFH?HSh&H.HShCHHChCIcG&ELH\$ IID|$D@ B 
IB  D9tDAE9A   HIcjЁD$   Hct$LHL$ NHL$ ID|$LIH\$ HPHShx
PHCIGh{
   Mwh$"H  \utIFhIFprNnwdH5  HcH>HBIFhB0<6w5H~   ~ Hs%HBIFhBHЀ6w   HH  IFpIFh]A9
  IVhHcBA,HcÉA 1IFhHPIVhx
uD$    HD$    HBD}IFhZE9  HcLE IcDA IVhIFhIvxHIFhH)HH  IVh
HЀd t̀
 _@ ;D$(R
  t$(A      H    >A   LT$IcDT$IPHHShMwhMwpCMwh{#  L    MwhHD$Mwhx  ; tHz  IGhHXI_hHcIw`HcT$HD$(HH)Ht$H9ZH)L   HD$ H% L        LLI   ^IM9uHD$ t$H

   D$Ht$IH|$(I)MwhMwpC<<   <
/LMHCh IT$HShA|$
HHCh*HHShQD$   Hct$L蝟Id   HT$1Ad   ^HT$IIHCxL{`L)HD  AMw<
!  ~E<  <'y  LshA'u6IDuL{hE9  HcIcA,'DA 딄<  Lsh1贗HI艙x"	  {b     H=8  $IEIE HcL`A      HhH$L(SHCIGh{
IGhHD$@D$  I_h{ tH{I_htHI_hHcIw`L$HD$HcD$LHt$(H)H9|SH)L   HT$ H L   LLI   IM9uHD$ t$H

   D$Ht$(IH|$I)8 tIWP1ۀ: u)L9;\$8  I`E1fD  HGIG`àu@I`I_hH9wAd  DeD9d$  HcIcAD-  DAD  IW`HAH|I`HbL{hHC`HKxHHChH)HCXH   V  %  	D  HCXA
  HChqLIVhIFh1LXLI-xB  {     H=ܙ  ȚIEIE Hc    L`HhH$L(sHA  RLshLspAG<  <   <
  Ls`LLHLHCPH;CHv   HCHHChI9  ILytLshUA9  AHcMA,HcA #ǃ     H{h?#t.  HC`HkhHH+CP   HHeHC`D LshA
zILshLspL;sx  LshALMMA}  ILkhL;kxuH:LkhD9(%  A  DE}MwhIGhHIGhI;Gx>  MwhA>
IGpIGhHH{X   HShӘ1    0HHD$LHL$HD$HʑE9j  D$CD= IcAD  HSh Lsh8   HAHC`H蟔xt   DHE1@ HGHC`#u<H{`L{hL9rA  DuE9  HcIcA, DA  HAHHC`IFhz
HIFhIFpI;FxX  IFh I_hHPHShHSp@<.h<_~a<YHChHsxHHChH)HH  HCh_   ;}π.9~HPHSh@<.<_~a<HKx<.|T<_~a<wIHHShH9uHHShHKxHPHKxHSh@HHShH9t%<	t< tHChZa}#H芓HShHKxHxHCh7I_h`A   LT$Ic T$IALcEd,CD5 
ICD5  D9k;l$|ށD$   Hct$L賗IA   LIc蜗I/   H5  H={  謏IE   H5֔  H=Z  苏IEL蚒MOhGLIHC`HCh1{I     H={  gID$1҃|$8ID$ Ic|$2LxHHwEnIlHHlu$D$   Hct$L螖IM8   HIF`Lxt   LuIVh|$H  D$   0IFhHSPE1: &AA)A   LIcIHChHHChH;Cx  LshA>
HCpHChA   LIcŕI|Hŕ   DHA  認O   H5  H=|  譍ID$H軐CL讐IFhHIFhI;Fx  IFh8
IFpIFhs   H5  H=  AID$LOA   LIcI5HcFt5A
HA D9LA9A   LHT$Ic蠔HT$IIVP1ۀ: )HChHx!Hsh   H+sPHdH藏?|$8
uE<AAn9l$w  IcHcHA
A/ HC`HCh1躌{I      H=P  <ID$1҃|$8ID$ |$2LxHhOIl/HHMuHI~`   D}IVhڑ1    0HHD$SHL$HHӊE9   HcIcA,DA IVh   H5  H=  GID$6HUHcLMID)Jv u  HDd I9r1Mc胋HS`HShHP LzLbt$L   Hc蕒IlA   LIc{I)ILMIFHHCh躕gE1HGIF`蓕ubIFhI~`HH9rA  ]A9   HcHcA, A A   LIcILMHAHIF`LHcLMID)Jv	   HDd I9rHcLMID)Jv	   HDd I9r{L萌A   LHD$Ic$HT$IA/DMHc݉D$A
HAA D9L$t0E9|A   LHT$IcDL$8̐HT$DL$8IBl=    fD  H5! HH8HG HtHWHD  HY  HWHG H@ HF0t t\t7uH驎f     H=!  
  Hf.     H=Y  Ԓ
  Hf.     H    H=  AUH)ATUH,SHH(dH%(   HD$1H#E  HHL$dH3%(   urH([]A\A]ÐLnIHHL$   H5! LHD$sHD$HtH|$ΊHD$HLhHpLLSI,w腉D  HHGhHu     Ht
u  HGPH5y  LGh   II)H  H81衆HHH5G! 1   s SHG  HHE     `HtH5! H   H11   [f.     ATIUSH   H=
! H]HHD	! 11H5
!    HH1ՈHI$HthHu3H}H~   H} HHGHcpHt6荋H[]A\D  ofoSPHS HP CHC     I$EtuHtH}H   Ht@ H5
! Hٺ   1"gff.     fSHH=  HHHɉ5   H=ݟ  HUHCH[ff.     AWIAVAUATUSH"   HH車H[ C  touHC HpHx豎IH{Ht5pML   H5	! HH1[]A\A]A^A_6fD  HL[]A\A]A^A_fD  #IHC Hx  ~1`H  LH0>H   H5>	! 1L1҆H53	! L   IH1趆MHC HH9h 31HHd   HHIQH5*! LI迋HfH5! L觋H   LLL0fD  H  LH0vHtLyHH  HHL$H0OHL$HtH5N! H11LI跌LMHI6H  LLH=       H5! LL1   臅fHC Hx#IHC Hx 1    HHMHLHHHC H9hff.     S"   H.HC [H@8HD ff.     @ UHSHH5! 藆H5x! HH腆H56! HHH[   1]馄fD  SHH   Ht'Hǃ       H[3 U1HSH,    HOfHHH   H  H`    @TH߾   H蔊HH[]f.     SH   H;輇H{資H{[驇f     USHHH   H?贊H{諊H} rH}iH}`H   Ht1H5K  &H   HtH1H5-  []fD  H[]f     UHSHHH5! HHHH   []f.     SHH5! H艋H[@ HHH5~! i   Hff.     @ AVI"   AUAHATUSHHdH%(   HD$1蚅Lc H=  I$   HE    jHEaHLDHEH$  1ur=H5! HHH$跊A$    H5!    H蛊H5!    H臊HHL$dH3%(   urH[]A\A]A^    H<$觀Ht	HE H5a! H<$8tH$fD  H<$   蚄H$H5! HKff.     fSHH5Y! HىH[@ SHH  HdH%(   HD$1HuQH$HH5! H膉H5!    HrHHL$dH3%(   u#H[f     H<$   H$'    SH蓉H5,! HHH[ff.     SHHH5>  iH[@ ATIHH5#  UHSH@LHH5  .HHH5  H[]A\@ UHHH5  SHHHHH5ٓ  ߃HH[]D  UHHH5  SHH豃HHH5  蟃HH[]D  AUIH5|  ATIUHSHHH ! cLHߺ   H5 ! 1*LHߺ   H5 ! 1HHߺ   H5 ! 1~HH[]A\A]f.     UH"   SHHHC HtlH9-  t3H9-  tzH9-  taH9-  txH9-  uH@      H@     HHH5  脂HH[]f.     H@      @ H@     @ H@     @ H@     @ ATUSHHHt$"   H|$Hk ~HD$Le HpHxNHT$HH5Ƒ  ID$HE HJ     HHÁHD$H[]A\D  AUI"   ATIUHSHH茀H  HH5w  vLHߺ   H5  1=}LHߺ   H5  1$}HHߺ   H5  1}HH[]A\A]ff.     fUH"   SHHHC H9-  H@ t%     HHH5Ԑ  ̀HH[]          UH"   SHHHC H9-  H@ t%     HHH5t  mHH[]          USHHHt$"   4Hk H}HtxHE    HT$Ht%H|$|HD$HpHxSHT$HEHH5  HD$H[]ff.     @ UHAUATI1SHHdH%(   HE1yH}HE|HMHHAHHH% H)HHH9tH   H$   H9u  ubLl$@   IfAE HQLHq{H߾   ByLLH   H]dH3%(   uHe[A\A]]D  H)HL @zUHSHHyHuHH[] Hx{HH{HHtHwHH[]f.     AVAUATA   USH"   HN}H[ H{Ht,{IċC]        HC HpHx+L,  IHC t5L  t)L  tL  tA   LD  H5J  [L   H=  ]1A\A]A^|y@    H[]A\A]A^    k1I6@ H   H~H1HIH}LLH|H6H9|HC A   8   H5  ML1H=     xH'  H5  HH|H[]A\A]A^f     H1&wHNI&f     HHwHLHH3HvH9|HC A   8tGH5   ML1H=A     7xH  H5E  HH>|H[]A\A]A^fL)      L  @ U1HSHuH-  HH
  HHxHH[]fD  U1HSHLuH  HH
  HHxHH[]fD  AUIATUSH"   HrzHMe yHHu%HLH57  K{HH[]A\A]D  LxH} ~1    HHHAuLHftH;]|ff.      AUATUHSHHH5  px"   HIyH5i  LLk -yu9HLsH5  H/xHH|HH[]A\A]fD  H5  HL1   7vHfU1HSHrHm  HH	  HH0wHH[]fD  AWIAVAUATUSHH(Ht$"   HT$HL$xI   LH  H     Lc }HH   H5  1H1vuHx I~=E1f     LLIsHHIuLLH|M;w|H  HH5:  9yHL$H1H5     tHL$H1H5m     tHL$H1H5b     tH(H[]A\A]A^A_H  H5ш  H81qff.      AVAUATIUHH5  SH/v"   HIwH5(  LLs vu8LHL{H5  HuLHHwH[]A\A]A^ÐH5  HL1   sL   LH5  H1sIfD  AWAVI"   AUATUSHHH|$vI   H{     LLk Hp  {IHt~LtH5  11L\sHx I~31HLHqLHHsHLHzI;_|H|$LH5  +wHL[]A\A]A^A_Hb  H5  H81oATIUSH"   HuH[ C   t1u"HC HsE1E11LppuXZ[]A\D  HC HsLqHC Hx  ~D1H1H#wLHhyH   HwLHHIyHC H9h [L]A\3{ HC HsLoHC Hx ~1HHHpLHxHC H9h[L]A\zSHH   HtGnHǃ       H[w U1HSHlz   HoufHHH   HO  HPH@     prH5  HHuH5o  HouH   1H5  H=  qH5  HHyHH[]fD  AVAUIATAHUSHH H5  dH%(   HD$1hrHyH5  HߍPHHcHT#yHL$LDLD$H  1%o"   HxsLc HL$M$   IM HtI}H5  1   &pHuvH5  HqH|$   H5~  H1oILLnHcH5  HHToxt;H\$dH3%(   LuCH []A\A]A^ I}Ht$joID  LLl1LqMu oAW"   AVAUATUSHHqrH  H[ 1H=M  HF  apIŋC      uHC HpHxqIE IHkHtH*nHH_rID$H[HtH	nHH>rID$M,$H5  L1H=B  H   []A\A]A^A_nf.     1)lIIE HC Hx h1HL5>  HHJm1HL1;nLHkHC H9h&1jIIE HC Hx  1L5  H   Hr1LH1mH1HL=  IHr1HL1mLLHBuHC H9h  UHSHH9t]HHt[@uU@tO?"uEH߾"   opH[ "   H^pHE o oKHoS P HH[]H  H52  H81jff.     @ USHHH?sCtDu0HC 1Hx ~#fHHHkHypHC H9hH[]     HC 1Hx  ~ H1HCqH;pH   H+qHHpHC H9h H[]ff.      HtHH*1H 1ff.     fHHjHtHxHpnHHlH=n  HlUHSHHHH5>  AnuHH[] H5!  1H1}k1H5  H    u8ckHkjHcH߾"   knHC Hh8HH[]f     +kHtHcff.      1D  SH   HXHt'u"t?uH[
kf.     HHqH[Hgf     AVIAUATIUSH.HsiHtMHE1@t)HSHsL1_rI$D[]A\A]A^    HtLm A   fH5  HltZH5  Hlu2H  HHLA   1qI$D[]A\A]A^D  H5Y  11HlH,  H5}  H81fff.     UHAVAUATSH HudH%(   HE1EqHuHHiH5  HAo1Hzp1Hpm1HqHNfHUHHnLmI}RhHHHH% H)HHH9tH   H$   H9u  ufLt$D
  IfAI~AF Iu"fHjpLiEtu	Hu1HMdH3%(   u*He[A\A]A^]@ H)HL D  H   gfATIUHShHHtH[]A\@ 3qLHHHkH[]A\f.     AWIIAVAUATUSHHdH%(   HD$81? t	H  HD$   IoA_I~  HD$   ]Le   tSLL)L9}HL\$+pL\$H 
IA$ÀuDXt
   1LL\$WjL\$Hl A\$Ml$A   t[LL)L9}PL\$oL\$H f     IA] ÀuDXt
   1LL\$iL\$Ld A]MuA   tTLL)L9}IL\$UoL\$H  IAÀuDXt
   1LL\$iL\$Ll A^MFA   toLL)L9}dL\$ LD$nLD$L\$ H f.     IAÀuDXtLǺ
   1L\$ LD$iL\$ LD$Lt IXHL)L9a  APE1Ҁ.u&      t+HHL)L94  BՃZuф  1
   HLT$}hLT$Li  t<:u
@ tH<:u<:  LT$HI1H  AV   AUH5  ATLD$0HL$(H; eH5  H 1HH1dLT$    HH5h      LT$8  dHiLT$L)LH`aHIUaH;M   H5#  H1ydG    E1L%aH5  I   PH&  AVAUATLD$0HL$(H814dH Ht$8dH34%(     HH[]A\A]A^A_D  L\$lL\$H @ H] ÀuDXt
   1HL\$fL\$HD HD$@ Ht$
   1fL\$HD HD$ cLT$HH{LT$
   1M   hfLT$HHH)M<Ix00  L\$(LD$ H|$D$10000fD$5D$7 kH|$LD$ HL\$(Hf.     HHDAuH)Hv-
   1L\$ LD$eLD$L\$ IAPLT$1H   L\$ LLD$eL\$ LD$HeLT$HHH)H    I) a@ AWAVAUATUSHHHoGH4$H     H=qv  HAA EEu=H    A   tEH$L HD[]A\A]A^A_@     tA   E1    H}     H=d  H      H=u  H   	   H=u  H      H=u  H =     H=u  H -     H=u  H 7     H=lu  H A     H=Yu  H      H=?u  H   
   H=.u  H r  
   H=u  H o     H=u  H      H5t  H[]  H5t  H4b  H5t  Hb  H5t  Hb  	   H5t  H\Z     H5t  H\h     H5t  H\)  HC 8L`HXZ  H5a  HaLH߅  fA   IPD    tChHC A   HpHxCfI A   A       A   gIHC Hx  1p    Hr  Hr     LfH   H5  H11^H5  L   IH1d^MHC HH9h j1HHc   HHIbH5  LImcH\H5  LUcH   LLL`@ L0`HtHHD$-^Hq     Hq  HeHtH5  1H1]LD$ILidLMHIcHi  LLH=  _f.     H5  LL1   7]fHG   H=_  H E1A) Hts   H=_  H E1AHC HxcIHC Hx 1 HH[HLHH[eHC H9h@ A   A   A       HC A   HpHxcH=^  HR]H=p  HC]I   HH5a  H1\H=Yw  ]H5L     HH1[H[IE1A   HA   \HC    HxT[IHA   \HC    Hx,[IHE1y\HC LpHhLI9s`A   I^H}I9G  }:tSH :tKHHGH9u
   12^IILHL)III9rOd$A   HH  HHA   [HC 
   HxgZIH[HC fLhHhLI9ssA   I]H}I9   }:tmHD  :tcHHGH9u1T$)XfLT$I*HL)IIYXL9wf(A   }`I0HH  HHHHfA   ^F`Ir  fA   ^#`IHHHGq  ^q  fWq  A   _IHA   tZHC 1Hx5W_IsHC A   HpHx1\IRHC 
   1HXC HH(\HHHaIHHuDBt
   H1[H{IU HHI HuDBt1
   [HHH=   H   H5;  MIHH=     1A   iXI|_E1IlH5  H=  1A   6XIIH5  H=  1A   XI&I;:It$H{A   $_H=m  HXH5>  IH=d  H   1WIH=`m  UH=l  YHH3  H8\H      ATUHSH"   HHdH%(   HD$1aZH[ 1HH[t$H$HT$dH3%(   u;H[]A\    H{L$$XM   HH5Y  H1VhV     AUIATI"   UHSHYH] H54  H\L9-        HZ   HU^ItOL9%  t61HZH5  H}]H5  HH[]A\A]tZ@    HYŐH5	  HWI@ H  H5  H1   UWfD  AVAUATUSHHk  H dH%(   HD$1Ll$LD$LdTH5=  HZ1H[UH5$  L%  HHbZLH7U"   HIwXLc LH1H[I$   LLUE8^H5A  HHE Z    LHEHD$HHDHERHL$dH3%(   uH []A\A]A^aTAVAUATIHh  USH dH%(   HD$1Ll$LD$LTSH5-  LuY1HKTH5  H  LHRYHH'T"   LIgWI\$ LHL1ZH   LHTH59  LEXHE    HEH5y  H|$H   1S\HHE P   uHL$dH3%(      uH []A\A]A^4S@ AUH5h  ATUSHH,  H([Hx ~OI1fD  HLHXHI9]~*HLQHZHHIOTuý   HH[]A\A]     AWAVAUATUHSHH(Ht$HtH|$SHx u<H5  HH1   RHD$Hu#HH(H[]A\A]A^A_ HD$HtH|$;SHx tH=g  SH=f  HD$wSH5  HIEWHt$HIRIIH   H5  LL$TL$t*HL$Iغ   LH5  1QH?@ H5  LL$}TL$I  I  H0  L9_  L/QHH5}  H=TU  HHd  HH0yTHHQ  H=  HHSf+RH|$H5e  H$fYI I|$  L|QH<$HULLRLHHPIH   H$MHx H5  LLT$dSLT$MׅH5  L11PLT$MHXH<$LRLT$   H5  H1LL$_PHH1LL$Hh  MIf     LHRHLOIH     H|$H5[d  XHHOHt$HU   HLTQH5m  IH=  H   1OH@ A   XD  LD$ILѺ   H5Q  L1gOH    
   H{OH HL$Iغ   HH5  1"OhHOHLIPIL   H5  H=  I1NH'H}  L9uL=  Hl$MH%  H5c  H81K@ ATUH"   SHQHC HHH5  L   WI4$Hu	[]A\@ I|$[H]A\7Q    UHHrc  SH(dH%(   HD$1HL$LD$LtxH\$WHL$Iٺ   H5  H=  I1MH5  HHOHH1QHPHHT$dH3%(   u"H([]     HD$      zM     UHHb  SH(dH%(   HD$1HL$LD$KtxH\$NHL$Iٺ   H5  H=  I1	MH5  HHNHH1JPHPHHT$dH3%(   u"H([]     HD$      z8L     UHHa  SH(dH%(   HD$1HLL$LD$*KteLL$LD$H$   1H5  H=:  =LH5N  HHMHH1~OHHT$dH3%(   uH([]@ HD$   A   zKf.     ATH=8a  USRH5/a  HI*SH="a  HLHH5a  H)TH     HH5`  NQH=a  rMH=`  H  _MH={b  H  LMH=`  H  9MH=`  -MH=`  H  MH=`  H  MH=`  H  LH=`  HV  LH=`  HS  LH=x`  H8  LH=l`  LH=g`  H	  LH=d`  H  LH=U`  H  vLH=K`  H  cLH=>`  WLH=7`  KLH=4`  H  8LH=&`  Hz  %LH=`  H  LH=`  HD  KH=`  H9  KH=_  H  KH=_  H  KH=_  H  KH=_  H  KH=_  HJ  KH=_  HO  zKH=_  H4  gKH=_  HA  TKH=_  H&  AKH=_  H  .KH=]  H  KH=_  H  KH=]  H  JH=\  JH=x_  JH=u_  Hg  JH=l_  H  JH=\  H  JH=M_  JH=\  H  JH=5_  H  rJH=)_  H  _JH=_  HI  LJH=_  H.  9JH=_  HHH  JH=^  HHHx  JH=J  HHHU  IH=^  HHH"  IH=nJ  HHH  IH=^  HHH  IH=^  HHH  |IH=k^  HHH  aIH=U^  HHH  FIH=B^  HHH`  +IH=-^  HHH=  IH-  HH5E^  HHU HH  GO      H5^]  HH  OH=  1H'H5,]  KHl  H=}     H5]  lKH  H=^     H5]  MKH  H=?     H5\  .KH߹  H=      H5[  KHX  H=     H5
\  JHq  H=     H5]  JH=  KH=Q\  GH=  1H1EH_     H5[  HHI  JH  H=6     H5I[  JH  H5\  HMH=   KH=[  WGH=0  1H1DEHM     H5&[  HH  "JH  HH5P\  MHU HH5M\  YM      H5v[  HH  	N   H=     H5a[  M   H=     H5h[  MH5h  H=y  |KH=m  HIH5Z  MIH=N     HH5[  .IH=/  1HH5[  IH  H=  H5[  HH  H=  H5e[  HH  H=     H5Z  HHU HH5B[  "LH     H5/[  HH  H   H=     H5Y  L   H=     H5Z  LH=o  1ɺ   H5nW  |LH=U  1ɺ   H56W  bLH=;  1ɺ   H5%W  HLH  H=     H5Y  GH=  1HyH5FY  GH  HH5\Z  'KH5x  HH  IH"  H=     H5Y  rGH;  H=|     H5/Y  SGH4  H=]     H5	Y  4GH]  HH5Y  JH5  HH-  IHQ  H=     H5X  FH  H=     H5X  FHӵ  H=     H5kY  FH\  H=     H5aX  FH  HH5:Y  IH5  HH  pHH  H=z     H5W  AFHJ  H=[     H5W  "FH  H=<     H5X  FH$  H=     H5W  EHU LH5X  QI      H5T  HH  J   H=     H5T  IH  H=~     H5W  uEHU LH56X  H      H5hT  HH7  I   H=&     H5IT  uI   H=	     H55T  XIH  H=     H5V  DHU LH5W  VH      H5S  HH  I   H=     H5S  HL%b  H=s     H5V  LwDH=X  L   H5U  \DHU HH5/W  G      H5IS  HH  yHH  H=     H5U  
DH  H=ܿ     H5T  CH=V  @H} HSDH=  HEHU HH5V  1GHU HH5V  Hl  GHU HH5V  HZ  F      H5T  HHr  GH  H=_     H5T  >CH  H=@  H5A  CH  H=!  H5@   CH  H=  H5T  BHU HH5U  NF      H5T  HH{  FH5W  H=h  DH  H=U  H5T  HyBH=:  HڹH5xU  ^BH  H=  H5_U  ?BH  H=     H5S   BHI  [   H=Խ  ]H5tS  A\Af.      AU	   ATI   USHH=SU  HH-  HM /DL9w9I)INlcL%2U       H} L   1H&DL9uHu H
   []A\A]=f     HcH  SHHЃ)   HT  1CH޿)   [=        HT  1CH޿)   [=ff.     @ H~( tEATUHHSHDHs(HID9IT$H߾   H8HC(    []A\fff.     @ UHAWAVAUATSHX  L%9  HA<$dH%(   HE1G  Hǅ   1LLǅ    LLMǅ    ǅHfAH?HTI9@  I)MIIH'  D  H='  '  HHFHHHD HH% H)HHH9tH   H$   H9u  t	H)HL HD$O|- HIHLHH=HHLHL46HIFIHHH=HHA4$N|9Nl/2  LM9rf   HMdH3%(     He[A\A]A^A_]D  HHA$tH{  پ   HlR  H81AH[  D4XA  A$    ǅ     HcH_  D  A  6  McHW  B0;  H,Y  F40EtbA4L
  A$S  HIUDǉIE  IIcމ  D  DE@  uDE  	  L5Q  f.     H9Z  Xt=  wHH=V  <  L;A$IIb  IHY  Xu@ HZ  A΅BHc   LE$HHH>[  40)HHcIt H    HH)I)HHE-  NwHHR  HcH>I}Iu 19IE HfE$EtHLHHHX  HHHLhHZ  0A7H  wHcH5fU  f4f9  HY  HIHHxD  Ha  L   1H8  H; >IGHT  H;4H3
   7A$IHL,    HYV  4x  A$1  HIǅ   IE .f.     ǅ    ǅ    H        H=N  H<1l       HH%7A$fD  ǅA4$L5  HN  H?7  1   I><I>I6
   {6fD  H        H=M  H0<SH  H   HkM  H817<LM9fHa  HM     H6  H81;H=  H8H(  
   H05#fD  HHX  HO     DXH  H81;HY  HX  HH	  H\Hw  LHIH HH  H5  I   H81+;IEyLHH}W     H8HH:  HL  H81:ANHP  AHcH>fH=dL  $;    H        H=K  HX: IIc9D  HS  $IEHIuIU H<3HpHI}Iu Pi4IE HIHcH5  HK  HH1     H819yIuIU H2HHxpI} X5I}IuH.IEHHI}Iu P3IE HLIu L/IuHL/HHv3HJHIu H.H/IuHO.I}Iu 0I} 8IE     IEHHǀ      HI] x     H=3  u4HCHIu H50H   H=2  85HHxB     H=3  4HC뜾   H=2  4HHx'     H=2  3HCLHL-Iu H1,HI]H{(H|  Iu -1-HI} w5HI}Iu N-IEH~Iu H-H65HZIu H,I}H,IEH.Iu H,HML-XM  IL;7A<$tH  HYH  H$1  1   H;6IH;At yH3
   \0Hs  H<H        H=H  H6H=?G  6   1I} 4HC(B   H51  H=0  +HCq   H50  H=i0  +HCP   H50  H=H0  y+HC-f.     S0   1XH     H@    H@    H@(    [ff.     S(   1@        HH@     H@   1@   HC11HC4HX [ff.     @ S    a1@        HH@    H@   >1   HC3HX [f.     S   1   H@    HH@         ~3HX [     AV1AAUIATUSH*H{L` H0HLI\$HE4$ID$/HE H@ H[]A\A]A^USHH+HHH[].f     AVAAUIATUHSH_ Ht.IH{Ht(I\$ HC    HC    HC    H}/HkHLD3HHC2/HC( []A\A]A^ÐATAUHHSH*DHH[H]A\3fATIUSHG HxHhH_HH߄t<,tHH߄u[]A\ÐID$ HHH)HHhH 1ff.      HG H@ UHSHH_ H{Ht'H] HC    H{Ht'H] HC    HC     @   HC   .@   HC.HCH[]     AUIATIUSHH_ Hk HsH{HEHC H9HCL,L$H[]A\A]     HHsH_/H{HCHCH4    F/H{HCff.     AT1IUHS&LHHH1H[]A\fUSHHn HE H~kH_ HS HKH{HH9~H)HHHtH9LHCLMLE1fD  I4H4I4HHS H4Hs HVHS H9M H[]    HsHc.H{HCHCH4    J.H}  HC~H{HS zfHG H@  HG uH@H H@Hff.     @ HG uH@H H@Hff.     @ UHSHH_ H{Ht!%H] HC    HC    @   HC   [,HCH[]ATIUSH_ HkHsHCHUHSH9L$[]A\    HHHsH$-HCL$[]A\    U1HSH%HHHN%HH[]@ HG H@ HG H@Hff.     @ HG H@Hff.     @ H   SGHt	tCu3H{ Ht*HGHtH#H{ HG    #HC     [f     HG HtHxHt#HC H@    HxHt#HC H@    Hk#HC     [Ðff.     @ SH%H{Ht5#HC    H{Ht#H[#fD  ?~w'HM  HcH> <  fD  H(  luH H(  Hl(  HO    WHO07  9  .uGHW<I  <itznH8(  jzf`HHE:  z H(  HOf.     WHO0    .G<I  <inH'  	  f.     G<Ntq"  <f  H'  f"       G<o\  <ulH`'  f.     WHD'  ftnnHZrVuH'    @ eH'  tfG<E  <eH&    sH H&  H8  HOÀalH&    @ G<R  <ruH&  C  f.     GHW<7  <0  <,  <.P  HO8  H7&  HD G<A4  <aLlH&    f.     G<U    <o  <ulH%  @ GHW<N  j  <if<nanHH~%  H7   HO     H\%  H7  HOÐ:HWrGHL  HcH>D  H %  9`  AHQ<:8HL  HcH>@ H$  9~ <n <:   B  <xJH$  H9?  0*    Hw6  Ð<FHv$  y  FH HW$  H>6  HO@ <IpB<NI  <nH*$  @ <OHHfH#           H<9	  <0}<,m  H         <.t4HH  H#  HDD  HHH    HHҀ7vfOHWȃ0	wHrRЃ0	  H,<zHK  HcH>fD   H$#  H5  HOf     SH#  $fD      LSH"  (  @ UH"    fD  À:H B<0<5D  <9HBHJ<.Z  <:tƄHp4  Hc"  HD    JH:wH54K  HcH>fD  HQIH14  PxVfD  LH!  U  G<A  <aH!    NCH     H3  WЃ0	  HWOHW0<7  9%D  H<,t0<	fHJR90I  H43  ^.NH<,t
  H3  H   HDBHH2   <Et<eJ+tH   -JH   Ht0	H
uHFE      ,H
AF~aq    eeHND  sMeCH0<	(EtÀzFH  WЃ0	  HWG<N  <nH    ÀLFHV<-2JH{  0	J0	z-J0	}J0	mJ9b  0WH1  HH 1  "  0H  	  J0	z:J0	J0	z:J0	J0	BHJ< t<.   <	H<+     <-  <Zvy H:  H0  HO    NH  ÀfCHH  H+0   HOH]OHw0|7~?93HrGHW<-&EÀFH  tOHW-3H< 0<	v<	< xA0	hQH,  0	XQHp/  EH  :5Q0	%QHq0	v2À	H
Tt2tJ0	v	H^B0	H  vJ0	   Àz	:J
0	J0	z:J0	rJ0	bHJR.t/|r@	F+/3H5E  HcH>QHJ0	   Ày H  H
.  HOqHH  0	q0	qH-  @Hs  @:q0	RH0	rÀz	:rJ
H/  0	[J0	Kz:AJ0	1J0	!HJR960.uQH+/H5TE  HcH>Zuۀy H,  H  HNHE  H+</HcH>D  ATAUHSGH`  t3Hl  t(H  uHG HpHxKH     H}HtHE    HAtHH[HE]A\     HމH=N  [HE]A\fD  H9   HtHu	1fD  ATUHSHH-HHbHIHHL#   LHHt  #   HHt  HLLD$(H D$H[]A\    f.     AVAUATUSH;H,O߀Yw[H5D  HcH>J0	w;J0	w/J-  J	0	wJ
0	w
z:  HމH=  []A\A]A^f     {HsWԀNwHE  HcH>@ SJԀNwH5F  HcH>     H{p[]A\A]A^@ {HsWԀNbHG  HcH>SHsp  -M1HH  HcH>    H{,NHI  HcH>@ HH~V HVH HLvMI)I}IUH  IHuLH!%tL  DHQHDʺ2   @ Hyaml.orgHL)IDA.H0LfPH@,200L)bLHH[]A\A]A^ HD  V0	V0	V0	V0	V-  /HLfMI)LIVH  HI_HLLL)LHGfD  HH=~I  LJ  VHNZ:A}0	7QHq,N#HcH>     _tav     HVHN-MIcL>@ SHs.R  /g`SHs.)  /:7Sу,bHSH=J  H5"L  ,NDHcH>f     H     SHs.  /3rSHs.  /
iSHs.X  /vfSHs./  /a=SHs.u  /tSHs.L  /feS	Hs	.#  /=:HH[]A\A]A^NJHH
-MHcH>J0	J0	J0	J0	J-+:jdH=gK  H5L  HJRZ   A}0	4HH
,NHcH>H
-MHcH> ,V0	V0	V-t2H/_haVV	0	uV
0	e~/[H@ AVAd   AUATA   USHd     IHkhHSxH)HH~A
tMttt`HHChE9   E CD%  CD%If.     HHCh
uHHChx
t^[L]A\A]A^fHkhL[]A\A]A^HPHShx
uHHCh     ALIcaIjf     H;CHvHCP   HCHf     AWAVAUIATUSHHH  H~h H0     t!ǃ       H[]A\A]A^A_fD  HpxIt*HChHSxH)HC`H  8D}  HC`HChL%K  H.xIƅu@   HChHSxH)HC`H  HP8cIw@IcL> HShpHH@
tX@upHKhx
  HHQ HSh

t*uGHPHShx
  HHRHSh

uHHAHKh/  HC`HChfHH    HShx
LxHuL{h8
  AFL  AF  Ѓ)Ѓ:   Dh    HHCh    H( HPHShHSpH
teHPHShx
SEL$HBHChEr  E$E3 HHCh    A6HShf     H߽  HC`HChfD  AFHSh?  v  tA6   H߃^H߽  HIE HHChx
5H;CH+HCP   HCHfD  HShH
  &HPHShx
HHChAFf  uAVQ
  HH>
P*    HCh  x
MHShH
  HPHShx
OHANAVHChur1@Ń      A6   H߃HChx
U  9    D  AFHSh      A6   H߃H߽  HIE HChx
HHChwfD  HShH
  HPHShx
?HANAVHChur1@Ń      A6   H߃HCh@ HShHCxL{`L)H  AIW<
  <    HShIfD  AFHShO  v  tA6   H߃nHIHChx
%  A<$!  A|$ L6    -@ AFHSh  N  5  A6   H߃L{hd   d     IHSxLL)H~\
  D    HHChDeD9G  AHSxHcL{hA.IcDL)A LHH߉$HCh$f     HHYHPHShHSp@<.   <_~a<   HCxHHShH)H  <_#  <;}<.   <9~HJHKhB<.   <_  HCxHHKhH)H#  <_  <.}<
t<uGHAHChy
u9HShHBHChfD  :
p  HSxHC`H)H  8VHC`
  HChH    AFA6   H߽-   #HC`HChfD  HShz
\H9SHRHSP   HSH>@ L{h1Hc~HHP Hj  LrIE 
{sI} fD  L9{HL{P   L{HfHPHShx
L`Lch@<NtW<Z
  <C^ILchA?
P  MGH߉$ULch$fD  A$0	  ILchL;cxu    L`Lch@<NufD  H L{h    HShA
IWHSh@ Me   fH7    H    Hw    LHc$/	$I@ H;CHHCP   HCHfAFfD  AFfD  AF   9 AFfD  AF    AFǃ     ?   H9CHHCP   HCHAN=A?
  IL9s  U9  HcHcMA.
A cILchA?
0  U9  HcHcMA. A ,HHA|$^LcH  M|$MLfD  {^5  HHkI9wL  HuLIE H  LHHLyǃ     ANHC`AF   [   ǃ   ]   HCh:AF   +ANAF   ANH;CHHCP   HCHra<a<u@Ѓ)Ѓ9ǃ   :   	HHCh/HzH$I)HLL)H$HHBs I<*H$  HIE HrIVHsHHϽ  LLT$Hc$T$$IIL;{HL{P   L{HIGMH;CHHCP   HCHIGH;CH7HCP   HCH#LT$Hc$lT$$IHC`AF   {   ǃ   }   HChJ  @HxH$BJ<0H$  HIE HrRUIt$HHcH7 HSh1$Lc$,D<(3C&
IC& D9t 9LHc$$IL{hHHKh   HH                   
Assertion failed: %s, line %u
 Error at [Line %d, Col %d]: %s
 yaml2byte.c str && HASH == str->hash str->buffer ext && HASH == ext->hash       (str->buffer + str->length) - str->remaining    ext->buffer[0] ==YAMLBYTE_ANCHOR                bytestring_extend               bytestring_append --- %%YAML:%d.%d  ---  &%s  *%s !  tag: yaml.org,2002 / x-private: !! --- 

 \" \\ \0 \a \b \f \r \t \v \e \n | + ~ tag:yaml.org,2002:null tag:yaml.org,2002:str ?  tag:yaml.org,2002:seq [ tag:yaml.org,2002:map { []
 {}
 :
 id%03d                         3111111`383322`282111111111111121111111111111111111111111111111111111111111111111111111111111111`1688,99L9<<;;T<;;;;;            ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/                0123456789ABCDEF    4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<ALAAA\AlAAAAAAAA|AAAAAAAAA BHHHHHHHH BFHHXGHHHHHHHHHHHHHHHHHH BDGGHHH`BHHBHBFHHHHHHHHHHHHBHHHpEFHHHHHHHHHHHHHHHHHHHHHHHHHHHEHFHHHHHHHHHHHHHHHHHHHHHHHHHHHHHFpEFMFFFFFFFFLLFFLFFFFFFFFFFFFFFFFFFLFFKFFFFFFFFF`KJLL@L@LLLLLLLLLLL@L@L@L@L@L@L@LLLLLLLLLLLLLLLLLLLLLLLLLLL@L@L@L@LL@LLLLLLLLLLLLLLLLLLLLLLLLLLD??L??????????????????A??????????$L?$L??$L$L$L$L$L$L$L$L$L$LLT>T>LLLLLLLLLLT>T>T>T>T>T>T>LLLLLLLLLLLLLLLLLLLLLLLLLLT>T>T>T>LT>LLLLLLLLLLLLLLLLLLLLLLLLLLKMKMKMKMKMKMKMKMKMKMKMKMKMKKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKMKKMKMKMKMKKKMKMKKKMKMKMKMKMKMKMKKMKMKMKKMKKMKKMKJDHHHHHHHHHDHHDHHHHHHHHHHHHHHHHHHHHHDHHHHHHHHHCGXHXHGGGGGGGGGGXHXHXHXHXHXHXHGGGGGGGGGGGGGGGGGGGGGGGGGGXHXHXHXHGXHGGGGGGGGGGGGGGGGGGGGGGGGGG?FFFFFFFFFFFFFFFFFFFFF<FFFFFFFFFFFFFFFFFFFFFFFFFPGzGzGPGPGPGPGPGPGPGPGPGPGzGzGzGzGzGzGzGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGzGzGzGzGPGzGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGPGQWQWQQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQQWQQWQWQWQWQWQWQWQWQWQWQWQWQWQQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQWQQWQWQWQWQQQWQWQQQWQWQWQWQWQWQWQQWQWQWQQWQQWQQWQQ    UTF-16 is not currently supported in Syck.
Please contribute code to help this happen!  UTF-32 is not currently supported in Syck.
Please contribute code to help this happen! %s on line %d, col %d: `%s' to_hash Hash @name @domain @type_id @value @class @ivars @kind @style wrong argument type 1& instance of IO needed tag:yaml.org,2002: binary 
	  bool#yes bool#no int#hex int#oct int#base60 int float#base60 float#nan float#inf float#neginf float timestamp#iso8601 timestamp#spaced timestamp#ymd Date timestamp merge default tag:ruby.yaml.org,2002:sym 11 :: x-private invalid subclass 21 YAML Syck 0.60 VERSION compile utc to_f to_i read binmode transfer call <=> intern update detect_implicit dup default= match push has_key? keys node_import tr! unpack write yaml_tag_read_class yaml_tag_subclasses? emitter set_resolver node_export to_yaml transform yaml_new yaml_initialize @tags @options type_id= @resolver @level style= value= @out @input Model Generic bytecode scalar quote1 quote2 fold literal plain inline add_type use_types_at tagurize DefaultResolver GenericResolver Parser bufsize= bufsize load load_documents Node initialize_copy Scalar Seq add Map PrivateType DomainType Object BadAlias Comparable MergeKey DefaultKey Out Emitter reset emit tag:ruby.yaml.org,2002:object:YAML::Syck::BadAlias                    ?                       Stack now  %d token %s ( nterm %s ( Starting parse
 parser stack overflow Stack size increased to %lu
 Entering state %d
 Reading a token:  Now at end of input.
 Next token is Shifting token %s,  -> %s
 syntax error Error: popping Error: discarding Shifting error token,  $end $undefined YAML_ANCHOR YAML_ALIAS YAML_TRANSFER YAML_TAGURI YAML_ITRANSFER YAML_WORD YAML_PLAIN YAML_BLOCK YAML_DOCSEP YAML_IOPEN YAML_INDENT YAML_IEND '-' ':' '[' ']' '{' '}' ',' '?' $accept doc ind_rep atom_or_empty indent_open indent_end indent_sep indent_flex_end word_rep struct_rep basic_seq top_imp_seq in_implicit_seq in_inline_seq inline_seq_atom top_imp_map complex_key complex_value complex_mapping in_implicit_map basic_mapping in_inline_map inline_map_atom      Reducing stack by rule %d (line %u),                            HH?HHHHH;HHHHHH;UHHHHHH]mִHHff]HHHN;HثdTTkثdثdOTTTƳJ!ث߰dDYTT1v**J!ث߰dTqűTqTձ         	
!"#'*1!!!!()0023 !$%&+,./!%+%+%+  )3!&/&/&/ $-$.9;  i?@mC567QP "#$%S)	cMNOk567WUmZ] :"#$%HIJ)LMNOUWZ9S]UWZ]HIJmLMNOQ"#$W)Z]567567567?kCm"#$%)MNOMNOMNO	aHIJLMNOstuvwx	
	
	
	
	
	
	
	
	
				                   `!d14{hjf~l<TUR+0SX[^oQnDk!V p<9)VbzX[^Vf|squ  w    a)))L)D1   r  r)+r0  t; v  x  LLLrL))) )    ;    WZ]Y\_ i  )m EFGK   PWZ]Y\_   
y 9      :EFG PEFGimimim567 
8 9    :MNO% 
8 9    : 
     /	
      
    *567 
V    MNO% 
V     
     "#$% 
       
8HIJ%  
8  
HIJ%  
   Qm!JԟM	                    >>>vO   vvv`OOO 
   
 O>  $  $  k---O>>      O       &'(gce=>?,-@A}BC.23        "    #$%&
	    47 58KNO L     A0    E   3 J  /@ +< ->)  !'(29:HI6MA.?*;,=B1CDFG                      !!!!!!!!"""""##$%%%%%%&&&''(())**++++++,,-.////0112233                  8 8 < A F G J K P U ^ d e h m q y ~                           $(.29:@ELQV[`djkq{ !"  !!!!	! 
#'*1%&&%&%&%$&$&()()0+//+/+/+!,-./$/./23230                              	 $%(+.1368:<?BEHKMOQUWY[]_cgjnqux|                 	
float#exp float#fix   LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLTL̵̵̵̵̵̵̵̵̵LL<LLLLLLLLLLLLLLLlLLLL|LLLLLLLLLLLLLLLL\LLLLLLL̳LLLLLLLLLLLL`PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP(Phhhhhhhhhhxtddddddddddddddddddddddddddddddddddddddddddddd<dddddddddddPxPxPPPPPPPPPP!<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<dcPcPP1111111111PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPLպպպպպպպպպЫЫЫѹЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫnnnnnnnnnnnnnnnnnnnnnnnnnn+;@|ʸʸʸʸʸʸʸʸʸʸʸʸ+øwRRggggggggggRRRRRRRggggggggggggggggggggggggggRRRRgRgggggggggggggggggggggggggg<L,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,е޳޳޳޳޳޳޳޳޳޳޳޳kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkj~~~~~~~~~~jjjjjjj~~~~~~~~~~~~~~~~~~~~~~~~~~jjjj~j~~~~~~~~~~~~~~~~~~~~~~~~~~O..BBBBBBBBBB.......BBBBBBBBBBBBBBBBBBBBBBBBBB....B.BBBBBBBBBBBBBBBBBBBBBBBBBB7ŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴŴ̶lllllllllllԵlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll<$lllllllllllllll;     D$  4L  d  t      4   t(  H  \  t        $  4  D   T  d(  <  P  T        	  L	  t	  	  $	  d
  <
  th
  
  
  $
  $
  $  `  T      $  t0  l      t,  D  D    d        L  T  $  4  D      d(  4d  D  d  4  D  D    `      |       th  t         4  H  D5  T5  5  6  $6   6<  D7P  d7d  7  8  9  ;0  ;L  4<t  d<  <  =  =  =0  =L  $>d  ?  ?  D@  t@  @   @L  $At  dA  A  B   DC0  Ch  DD  D  4E  $F  FH  H  $I  dI  JL  J  J  DL  M<  M  O  DO  O  dQ`  DS  S  T  T(  UH  U  U  4V  4W  X0  Xh  ^  di,   j`   j   l   4m$!  m\!  4r!  r!  ds"  4t8"  td"  ă"  T"  Ą"  $#  ĒL#  h#  d#  #  #  T#   $  \$  4$  $  $  4$  Ė,%  X%  ė%  ԗ%  %  4%  %   &  H&  $\&  Dp&  d&  $&  d&  &  '  tD'  '  Ĳ(         zR x  $         FJw ?:*3$"       D             8   \   h    FDD O
ABHL
ABI   $      3    EKG YAA       #    NN       E    FDF $      ,3    EHL WAA       D    Em
F      @  	           T  X    EG a
CH     x              l    Ef       L	            H            D            @	            <	            8             4          4  @1       0   H  l    EAG }
AADwAA    |      E  8     L    FEA C(G0o
(A ABBE      2    El            E  4     x`    FDD u
ABJLAB   H   D  ~    FED D(G0@
(A ABBHO(A ABB  (     .    FDG RDB   4     {    FAA c
ABBDAE        8       (     L|    EAG 
DAG  (   4      EDG {
DAH     `  "    E\      |  (           $     0H    EG Y
AJVA0     X    FDD G@
 AABD (     $    EDG@l
AAB 8     '   FBD D(D@w
(A ABBG 4   X  U    FDH _
ABDRDB   $     L    EGI tAA 8     a    FEE A(D0D(A BBB       
                G    EA  8   (  <   FBA A(D@
(A ABBF 8   d     FAA 
ABEi
FBG   H        FBB E(A0A8G`
8A0A(B BBBG4         FAD D0
 AABA        $  @#    MN D   <  X   MQN 
AAB@
AAF_
AAG   (        EDG 
AAA     D^    EX                               1       8         FEA C(G0v
(A ABBF 0   D  `    EAG }
AAD~AA    x      E       	            |	            xc    EY       D    E`
K(      U    EDG y
AAE  8    	  4    FED A(G0v
(A ABBE  @   \	     FBB A(D0GP
0A(A BBBK P   	     OBB A(D0p
(A BBBA`H0  4   	  `    FDA c
ABGIDB  H   ,
  C   OEA A(
 ABBH H(  D   x
      OBI E(D0s
(A BBBCP  H   
  tv   FBL B(A0D8GP}
8I0H(B BBBH H        FBJ H(K0D8DPu
8I0H(B BBBE L   X  \	   FLE D(A0
(A BBBFL
(D BBBJ `        FBE L(D0D8GP
8A0A(B BBBAO
8D0A(B BBBJ d     h   FBB B(D0A8F`
8A0A(B BBBA
8I0H(B BBBK  L   t      FBB D(C0G
(A BBBA]
(A BBBD L          FBB D(C0G
(A BBBA]
(A BBBD H     p   FBB E(D0A8D@_
8A0A(B BBBO @   `      EAG t
DAJf
AAHD
IHK  <     v   FBA D(GP
(A ABBB               E
B                    ,          ,  	       H   @  M-   FBB B(A0A8G
8D0A(B BBBE      
             <       ,      y    HZ
NU
KU
KD             !       8     !    FEA E(GPp
(A ABBB     4  !_    H   H  !          \  !F    E@  ,   x  ,"   FDA |
ABF        #D    E~   `     @#   FEB B(A0A8OPV
8F0A(B BBBKD
8D0A(B BBBG    (  |%!    ER   $   D  %J    EDD iGH    l  %-    Ec   $     %f    EFD QDA     &'    E]   0     (&    EAG ]
JAKDAA$      &6    EDG ^FA    (  &    EV      D  &!    HX @   \  &S   FJH A(A0G@
0A(A BBBH      '    EV         '    EN b
AJ      T($    E^        h(    EV   (     l(L    FND pAB   $   D  (;    ENG [DA $   l  (;    ENG [DA 4     (    FLD D(G0[(D ABB(     )    EIG k
DAK ,     ){    FAA G0g AAB4   (  *    FJD D(G0j(D ABB(   `  t*X    EIG r
DAD  (     *X    EIG r
DAD  $     *    EAG0qAA(     D+    ECDF
F   0     ,V    EDG O
DADhDA t   @  4,\   FBB G(A0
(P DBBII
(A BBBH
(A BBBJ
(A BBBC   $     .:    EFD hAA $     4.:    EFD hAA 8     L.    FEA A(L0p
(D ABBF  8   D  .    FBA D(G0\
(D ABBG $     /:    EFD hAA H     ,/R   FEB B(A0A8G`
8D0A(B BBBA<     @0    FBB D(K0^
(A BBBB   H   4  0    FBJ B(A0A8GP
8D0A(B BBBA L     d1    FDA (C0H(A A
ABFb
DBHEDB      42-    Ec   $     H2    EFD DA@     2p   FBE G(A0GP
0A(A BBBDH   X  3   FGB B(A0A8G@
8F0A(B BBBO (     5    EDD f
DAA 4     6    EAG H
AAIOAA        6#    NN       6@    H_
IK   4   @  6    EDJ T
DADQ
DAJ    x  <7            87W    El
OO L     x7    FEB D(A0w
(A BBBHc
(A BBBF (     (8N   ECK
E 4   (  L9F    FDD R
ABEZAB   t   `  d9   FHB B(A0A8DNGI]IBBXX
8A0A(B BBBF  H     >
   FBB B(A0A8GPa
8D0A(B BBBE 0   $  0I    FAD O0B
 AABH 8   X  I    FEI D(D0r
(D ABBI @     PJ   FBB A(A0NP
0A(A BBBA @     K,   FBB K(A0DP
0A(A BBBA4     L    FIA A(D0i(D ABBH   T  `Ll   FBB B(A0D8G`G
8D0A(B BBBD 4     PY    FAI p
ABEFDB   (     P    EKD@
AAI (     PQ    EKD@
AAI (   0  Q    EKD@
AAE ,   \  R   FHA MI     4     (a    BGI A(N0V(F ABB     aa    Kh
M\ ,     aQ    MAG uABC   ,      b   ECP
F      D  po5    Eo      `  oQ    EK     |  oF    E@       p8    Er   8     0p`    FGE A(A0D(A BBB  $     Tp'    ECG IIA 8     \p    FEE A(D0b(A BBB  (   T  p.    FDG RDB   (     pb    FDA p
ABB     p       $     px    EDD hAA8     <q    FED A(D0m
(A ABBI  (   $  q.    FFD ZAB   (   P  q    EAD |
AAH    |  8r            4r!            Pr!       $     lrP    EDD @AA4     rY    FDA b
ABH]AB   $      r,    EFD WDA    @   r          T   r          h   r           |   r    NH
JNB       ts:    Ep         s      4      $    FDD r
EBIREB  0   !      bAD G0z AABDt   <!  (,   FBB A(A0
(A BBBNX
(A BBBIU
(A BBBD
(A BBBEL   !     FHB G(A0
(D BBBCH
(A BBBA H   "     FBB E(A0A8GPm
8C0A(B BBBG               GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      t      s      !                                  b                    ǃ     Ճ                                   '     3     =     A     E     I     M     Q     U     Y     ]     e     v     i     q     y                                   ބ     ń     τ     ۄ                    B     	          !     /     ?     O     `     ]     k                    s                                                                                                        xY             j            !                          !                   o    `             #                   
       A                            !            P                           (F             9             `      	              o    h9      o           o    7      o    7                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               h!                     Y      Y      Y      Y      Y       Z      Z       Z      0Z      @Z      PZ      `Z      pZ      Z      Z      Z      Z      Z      Z      Z      Z       [      [       [      0[      @[      P[      `[      p[      [      [      [      [      [      [      [      [       \      \       \      0\      @\      P\      `\      p\      \      \      \      \      \      \      \      \       ]      ]       ]      0]      @]      P]      `]      p]      ]      ]      ]      ]      ]      ]      ]      ]       ^      ^       ^      0^      @^      P^      `^      p^      ^      ^      ^      ^      ^      ^      ^      ^       _      _       _      0_      @_      P_      `_      p_      _      _      _      _      _      _      _      _       `      `       `      0`      @`      P`      ``      p`      `      `      `      `      `      `      `      `       a      a       a      0a      @a      Pa      `a      pa      a      a      a      a      a      a      a      a       b      b       b      0b      @b      Pb      `b      pb      b      b      b      b      b      b      b      b       c      c       c      0c      @c      Pc      `c      pc      c      c      c      c      c      c      c      c       d      d       d      0d      @d      Pd      `d      pd      d      d      d      d      d      d      d      d       e      e       e      0e      @e      Pe      `e      pe      e      e      e      e      e      e      e      e       f      f       f      0f      @f      Pf      `f      pf      f                  GA$3a1 xY      j              GA$3p1067  0t      Z               GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign             GA$3p1067  0~      j               GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY     0t      \              GA+GLIBCXX_ASSERTIONS   syck.so-1.8.7-16.el8.x86_64.debug   䮃7zXZ  ִF !   t/(	"] ?Eh=ڊ2N%{VΤ3=0T%kq,+kg~{?`k)^K~|#G8(D(M
pDq։؎xUܐ1hħ̼E7Te
)-
?χ (,kD.Aէy[8KɁ XEI0{i*3)aʜm~~wJvL[	3='rD
"cE,l+k􌤛xXe(ux=/aOkN((u5f5!I൪:so;|πWL;s 8/#ȃwnvsx!2%ciVl2 @"|AhwU-Iy87=q|gM)p*ϝxF<1̚;D=fڥ'$9v6tuR`mb%Hz)!s`Af;t2\.MI@mq&b(d!*%(NL<]8j(buhRY>@Rnׁ, :G7JȘ1r@IcSSCM>ZP߿ޕ÷4iC]reO^w<hDbifјVpس=xX@yQa3	sOϭ%~u@^zX\nc~:>b<wc		4<.};_ʲl0&\E=YJ:4Bi]6٧.`ԓ35xqc:|W]?YJ9Pv/I
:) 38'dxB*̠YHiYk< k^rJ~ѐ2LVAJwk<1?Ԃ[-崊o"VRE&mzZ gQYQeʸt"_>}PN옓ɧ+\L%ߵp*mZɄ5"a|]V$H"1MY1Q*IYbg Y638ez,8{PUO"sNukoW,fn妃 s-}Z
ƾo|rIEAiå	J GO;:-Tjdز֝E"6ltU~A䶁udkd,6?hvo./)aO	cFXk;?M4ɟ2;eiSOvq'#:xy]40k v|0qe1M"EdWhjg(Z3'(܈N4.Sf_w1){.t^BN1l_sIw~qN8+>B#U?73l['hnoJ}C?ˬ(84@DWh㥀pZPf(J2ƏPlR0b??+Xah?E\`
<7E]Ә~B6}A4pƌQ`IA.<?A?uvU
16wgmgZYJ/%m^ jҫSM4LK8.=wb^n %l2ѼsIO0+_Zruo(P|0vF{eCqmgbK<k#ଌ'Y+3Tvo?{!At	Q2> ׾#_[i}.AX!c0
sI"aجfzO.E} ff6Q}P'Rl7:,P7Ruau9aǾ.Ҩ%!݆nM~Qc-SjBVOMOtTUn[(UfM	fHl\ÅkdX,܈N9jEu8wsL996GI=\ZsV.2L{iަ
BYz[9x+ޅvB^78	6/aDI>F¦-W'q~W}KGGhx
i
ѬMoZt4UEɁU~ȸ3=~%?p~EP>i-cL.a0B$BZ	Ť1Kb!X㩚9*dQby5NMnGr'Y*.qvu3ja    	0 Q  @Lg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                 8      8      $                                 o       `      `                                  (                                                   0             #      #      A                             8   o       7      7      T                           E   o       h9      h9      `                            T             9      9      `                           ^      B       (F      (F      P                          h             xY      xY                                    c             Y      Y                                  n             f      f                                  w             ps      ps      m                             }             j     j                                                 k      k     \>                                           \     \                                               h     h     P"                                                                                                !                                                    !                                                    !                                                     h!     h     0                                        !          h                                          !                                                    !                                                     !          P                                            a                                                                 (                              "                          d	                                                   4     1                             PK     Y\xJHM  HM    x86_64-linux/intern.hnu [        /**********************************************************************

  intern.h -

  $Author: shyouhei $
  $Date: 2011-05-23 13:49:40 +0900 (Mon, 23 May 2011) $
  created at: Thu Jun 10 14:22:17 JST 1993

  Copyright (C) 1993-2003 Yukihiro Matsumoto
  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
  Copyright (C) 2000  Information-technology Promotion Agency, Japan

**********************************************************************/

/* 
 * Functions and variables that are used by more than one source file of
 * the kernel.
 */

#define ID_ALLOCATOR 1

/* array.c */
void rb_mem_clear _((register VALUE*, register long));
VALUE rb_assoc_new _((VALUE, VALUE));
VALUE rb_check_array_type _((VALUE));
VALUE rb_ary_new _((void));
VALUE rb_ary_new2 _((long));
VALUE rb_ary_new3 __((long,...));
VALUE rb_ary_new4 _((long, const VALUE *));
VALUE rb_ary_freeze _((VALUE));
VALUE rb_ary_aref _((int, VALUE*, VALUE));
void rb_ary_store _((VALUE, long, VALUE));
VALUE rb_ary_dup _((VALUE));
VALUE rb_ary_to_ary _((VALUE));
VALUE rb_ary_to_s _((VALUE));
VALUE rb_ary_push _((VALUE, VALUE));
VALUE rb_ary_pop _((VALUE));
VALUE rb_ary_shift _((VALUE));
VALUE rb_ary_unshift _((VALUE, VALUE));
VALUE rb_ary_entry _((VALUE, long));
VALUE rb_ary_each _((VALUE));
VALUE rb_ary_join _((VALUE, VALUE));
VALUE rb_ary_print_on _((VALUE, VALUE));
VALUE rb_ary_reverse _((VALUE));
VALUE rb_ary_sort _((VALUE));
VALUE rb_ary_sort_bang _((VALUE));
VALUE rb_ary_delete _((VALUE, VALUE));
VALUE rb_ary_delete_at _((VALUE, long));
VALUE rb_ary_clear _((VALUE));
VALUE rb_ary_plus _((VALUE, VALUE));
VALUE rb_ary_concat _((VALUE, VALUE));
VALUE rb_ary_assoc _((VALUE, VALUE));
VALUE rb_ary_rassoc _((VALUE, VALUE));
VALUE rb_ary_includes _((VALUE, VALUE));
VALUE rb_ary_cmp _((VALUE, VALUE));
VALUE rb_protect_inspect _((VALUE(*)(ANYARGS),VALUE,VALUE));
VALUE rb_inspecting_p _((VALUE));
VALUE rb_check_array_value _((VALUE));
VALUE rb_values_at _((VALUE, long, int, VALUE*, VALUE(*) _((VALUE,long))));
/* bignum.c */
VALUE rb_big_clone _((VALUE));
void rb_big_2comp _((VALUE));
VALUE rb_big_norm _((VALUE));
VALUE rb_uint2big _((unsigned long));
VALUE rb_int2big _((long));
VALUE rb_uint2inum _((unsigned long));
VALUE rb_int2inum _((long));
VALUE rb_cstr_to_inum _((const char*, int, int));
VALUE rb_str_to_inum _((VALUE, int, int));
VALUE rb_cstr2inum _((const char*, int));
VALUE rb_str2inum _((VALUE, int));
VALUE rb_big2str _((VALUE, int));
VALUE rb_big2str0 _((VALUE, int, int));
long rb_big2long _((VALUE));
#define rb_big2int(x) rb_big2long(x)
unsigned long rb_big2ulong _((VALUE));
#define rb_big2uint(x) rb_big2ulong(x)
#if HAVE_LONG_LONG
VALUE rb_ll2inum _((LONG_LONG));
VALUE rb_ull2inum _((unsigned LONG_LONG));
LONG_LONG rb_big2ll _((VALUE));
unsigned LONG_LONG rb_big2ull _((VALUE));
#endif  /* HAVE_LONG_LONG */
void rb_quad_pack _((char*,VALUE));
VALUE rb_quad_unpack _((const char*,int));
void rb_big_pack(VALUE val, unsigned long *buf, long num_longs);
VALUE rb_big_unpack(unsigned long *buf, long num_longs);
VALUE rb_dbl2big _((double));
double rb_big2dbl _((VALUE));
VALUE rb_big_plus _((VALUE, VALUE));
VALUE rb_big_minus _((VALUE, VALUE));
VALUE rb_big_mul _((VALUE, VALUE));
VALUE rb_big_divmod _((VALUE, VALUE));
VALUE rb_big_pow _((VALUE, VALUE));
VALUE rb_big_and _((VALUE, VALUE));
VALUE rb_big_or _((VALUE, VALUE));
VALUE rb_big_xor _((VALUE, VALUE));
VALUE rb_big_lshift _((VALUE, VALUE));
VALUE rb_big_rand _((VALUE, double*));
/* class.c */
VALUE rb_class_boot _((VALUE));
VALUE rb_class_new _((VALUE));
VALUE rb_mod_init_copy _((VALUE, VALUE));
VALUE rb_class_init_copy _((VALUE, VALUE));
VALUE rb_singleton_class_clone _((VALUE));
void rb_singleton_class_attached _((VALUE,VALUE));
VALUE rb_make_metaclass _((VALUE, VALUE));
void rb_check_inheritable _((VALUE));
VALUE rb_class_inherited _((VALUE, VALUE));
VALUE rb_define_class_id _((ID, VALUE));
VALUE rb_module_new _((void));
VALUE rb_define_module_id _((ID));
VALUE rb_mod_included_modules _((VALUE));
VALUE rb_mod_include_p _((VALUE, VALUE));
VALUE rb_mod_ancestors _((VALUE));
VALUE rb_class_instance_methods _((int, VALUE*, VALUE));
VALUE rb_class_public_instance_methods _((int, VALUE*, VALUE));
VALUE rb_class_protected_instance_methods _((int, VALUE*, VALUE));
VALUE rb_big_rshift(VALUE, VALUE);
VALUE rb_class_private_instance_methods _((int, VALUE*, VALUE));
VALUE rb_obj_singleton_methods _((int, VALUE*, VALUE));
void rb_define_method_id _((VALUE, ID, VALUE (*)(ANYARGS), int));
void rb_frozen_class_p _((VALUE));
void rb_undef _((VALUE, ID));
void rb_define_protected_method _((VALUE, const char*, VALUE (*)(ANYARGS), int));
void rb_define_private_method _((VALUE, const char*, VALUE (*)(ANYARGS), int));
void rb_define_singleton_method _((VALUE, const char*, VALUE(*)(ANYARGS), int));
VALUE rb_singleton_class _((VALUE));
/* compar.c */
int rb_cmpint _((VALUE, VALUE, VALUE));
NORETURN(void rb_cmperr _((VALUE, VALUE)));
/* enum.c */
VALUE rb_block_call _((VALUE, ID, int, VALUE*, VALUE (*)(ANYARGS), VALUE));
/* enumerator.c */
VALUE rb_enumeratorize _((VALUE, VALUE, int, VALUE *));
#define RETURN_ENUMERATOR(obj, argc, argv) do {				\
	if (!rb_block_given_p())					\
	    return rb_enumeratorize(obj, ID2SYM(rb_frame_this_func()),	\
				    argc, argv);			\
    } while (0)
/* error.c */
RUBY_EXTERN int ruby_nerrs;
VALUE rb_exc_new _((VALUE, const char*, long));
VALUE rb_exc_new2 _((VALUE, const char*));
VALUE rb_exc_new3 _((VALUE, VALUE));
NORETURN(void rb_loaderror __((const char*, ...)));
NORETURN(void rb_name_error __((ID, const char*, ...)));
NORETURN(void rb_invalid_str _((const char*, const char*)));
void rb_compile_error __((const char*, ...));
void rb_compile_error_append __((const char*, ...));
NORETURN(void rb_load_fail _((const char*)));
NORETURN(void rb_error_frozen _((const char*)));
void rb_check_frozen _((VALUE));
/* eval.c */
RUBY_EXTERN struct RNode *ruby_current_node;
void ruby_set_current_source _((void));
NORETURN(void rb_exc_raise _((VALUE)));
NORETURN(void rb_exc_fatal _((VALUE)));
VALUE rb_f_exit _((int,VALUE*));
VALUE rb_f_abort _((int,VALUE*));
void rb_remove_method _((VALUE, const char*));
#define rb_disable_super(klass, name) ((void)0)
#define rb_enable_super(klass, name) ((void)0)
#define HAVE_RB_DEFINE_ALLOC_FUNC 1
void rb_define_alloc_func _((VALUE, VALUE (*)(VALUE)));
void rb_undef_alloc_func _((VALUE));
void rb_clear_cache _((void));
void rb_clear_cache_by_class _((VALUE));
void rb_alias _((VALUE, ID, ID));
void rb_attr _((VALUE,ID,int,int,int));
int rb_method_boundp _((VALUE, ID, int));
VALUE rb_dvar_defined _((ID));
VALUE rb_dvar_curr _((ID));
VALUE rb_dvar_ref _((ID));
void rb_dvar_asgn _((ID, VALUE));
void rb_dvar_push _((ID, VALUE));
VALUE *rb_svar _((int));
VALUE rb_eval_cmd _((VALUE, VALUE, int));
int rb_obj_respond_to _((VALUE, ID, int));
int rb_respond_to _((VALUE, ID));
void rb_interrupt _((void));
VALUE rb_apply _((VALUE, ID, VALUE));
void rb_backtrace _((void));
ID rb_frame_last_func _((void));
ID rb_frame_this_func _((void));
VALUE rb_obj_instance_eval _((int, VALUE*, VALUE));
VALUE rb_mod_module_eval _((int, VALUE*, VALUE));
void rb_load _((VALUE, int));
void rb_load_protect _((VALUE, int, int*));
NORETURN(void rb_jump_tag _((int)));
int rb_provided _((const char*));
void rb_provide _((const char*));
VALUE rb_f_require _((VALUE, VALUE));
VALUE rb_require_safe _((VALUE, int));
void rb_obj_call_init _((VALUE, int, VALUE*));
VALUE rb_class_new_instance _((int, VALUE*, VALUE));
VALUE rb_block_proc _((void));
VALUE rb_block_dup _((VALUE, VALUE, VALUE));
VALUE rb_method_dup _((VALUE, VALUE, VALUE));
VALUE rb_f_lambda _((void));
VALUE rb_proc_call _((VALUE, VALUE));
VALUE rb_obj_method _((VALUE, VALUE));
VALUE rb_protect _((VALUE (*)(VALUE), VALUE, int*));
void rb_set_end_proc _((void (*)(VALUE), VALUE));
void rb_mark_end_proc _((void));
void rb_exec_end_proc _((void));
void ruby_finalize _((void));
NORETURN(void ruby_stop _((int)));
int ruby_cleanup _((int));
int ruby_exec _((void));
void rb_gc_mark_threads _((void));
void rb_thread_start_timer _((void));
void rb_thread_stop_timer _((void));
void rb_thread_schedule _((void));
void rb_thread_wait_fd _((int));
int rb_thread_fd_writable _((int));
void rb_thread_fd_close _((int));
int rb_thread_alone _((void));
void rb_thread_polling _((void));
void rb_thread_sleep _((int));
void rb_thread_sleep_forever _((void));
VALUE rb_thread_stop _((void));
VALUE rb_thread_wakeup _((VALUE));
VALUE rb_thread_wakeup_alive _((VALUE));
VALUE rb_thread_run _((VALUE));
VALUE rb_thread_kill _((VALUE));
VALUE rb_thread_alive_p _((VALUE));
VALUE rb_thread_create _((VALUE (*)(ANYARGS), void*));
void rb_thread_interrupt _((void));
void rb_thread_trap_eval _((VALUE, int, int));
void rb_thread_signal_raise _((int));
void rb_thread_signal_exit _((void));
int rb_thread_select _((int, fd_set *, fd_set *, fd_set *, struct timeval *));
void rb_thread_wait_for _((struct timeval));
VALUE rb_thread_current _((void));
VALUE rb_thread_main _((void));
VALUE rb_thread_local_aref _((VALUE, ID));
VALUE rb_thread_local_aset _((VALUE, ID, VALUE));
void rb_thread_atfork _((void));
VALUE rb_exec_recursive _((VALUE(*)(VALUE, VALUE, int),VALUE,VALUE));
VALUE rb_funcall_rescue __((VALUE, ID, int, ...));
/* file.c */
VALUE rb_file_s_expand_path _((int, VALUE *));
VALUE rb_file_expand_path _((VALUE, VALUE));
void rb_file_const _((const char*, VALUE));
int rb_find_file_ext _((VALUE*, const char* const*));
VALUE rb_find_file _((VALUE));
char *rb_path_next _((const char *));
char *rb_path_skip_prefix _((const char *));
char *rb_path_last_separator _((const char *));
char *rb_path_end _((const char *));
VALUE rb_file_directory_p _((VALUE,VALUE));
/* gc.c */
NORETURN(void rb_memerror __((void)));
int ruby_stack_check _((void));
size_t ruby_stack_length _((VALUE**));
int rb_during_gc _((void));
char *rb_source_filename _((const char*));
void rb_gc_mark_locations _((VALUE*, VALUE*));
void rb_mark_tbl _((struct st_table*));
void rb_mark_set _((struct st_table*));
void rb_mark_hash _((struct st_table*));
void rb_gc_mark_maybe _((VALUE));
void rb_gc_mark _((VALUE));
void rb_gc_force_recycle _((VALUE));
void rb_gc _((void));
void rb_gc_copy_finalizer _((VALUE,VALUE));
void rb_gc_finalize_deferred _((void));
void rb_gc_call_finalizer_at_exit _((void));
VALUE rb_gc_enable _((void));
VALUE rb_gc_disable _((void));
VALUE rb_gc_start _((void));
/* hash.c */
void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long));
void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE));
VALUE rb_hash _((VALUE));
VALUE rb_hash_new _((void));
VALUE rb_hash_freeze _((VALUE));
VALUE rb_hash_aref _((VALUE, VALUE));
VALUE rb_hash_lookup _((VALUE, VALUE));
VALUE rb_hash_aset _((VALUE, VALUE, VALUE));
VALUE rb_hash_delete_if _((VALUE));
VALUE rb_hash_delete _((VALUE,VALUE));
int rb_path_check _((const char*));
int rb_env_path_tainted _((void));
/* io.c */
#define rb_defout rb_stdout
RUBY_EXTERN VALUE rb_fs;
RUBY_EXTERN VALUE rb_output_fs;
RUBY_EXTERN VALUE rb_rs;
RUBY_EXTERN VALUE rb_default_rs;
RUBY_EXTERN VALUE rb_output_rs;
VALUE rb_io_write _((VALUE, VALUE));
VALUE rb_io_gets _((VALUE));
VALUE rb_io_getc _((VALUE));
VALUE rb_io_ungetc _((VALUE, VALUE));
VALUE rb_io_close _((VALUE));
VALUE rb_io_eof _((VALUE));
VALUE rb_io_binmode _((VALUE));
VALUE rb_io_addstr _((VALUE, VALUE));
VALUE rb_io_printf _((int, VALUE*, VALUE));
VALUE rb_io_print _((int, VALUE*, VALUE));
VALUE rb_io_puts _((int, VALUE*, VALUE));
VALUE rb_file_open _((const char*, const char*));
VALUE rb_gets _((void));
void rb_write_error _((const char*));
void rb_write_error2 _((const char*, long));
/* marshal.c */
VALUE rb_marshal_dump _((VALUE, VALUE));
VALUE rb_marshal_load _((VALUE));
/* numeric.c */
void rb_num_zerodiv _((void));
VALUE rb_num_coerce_bin _((VALUE, VALUE));
VALUE rb_num_coerce_cmp _((VALUE, VALUE));
VALUE rb_num_coerce_relop _((VALUE, VALUE));
VALUE rb_float_new _((double));
VALUE rb_num2fix _((VALUE));
VALUE rb_fix2str _((VALUE, int));
VALUE rb_dbl_cmp _((double, double));
/* object.c */
int rb_eql _((VALUE, VALUE));
VALUE rb_any_to_s _((VALUE));
VALUE rb_inspect _((VALUE));
VALUE rb_obj_is_instance_of _((VALUE, VALUE));
VALUE rb_obj_is_kind_of _((VALUE, VALUE));
VALUE rb_obj_alloc _((VALUE));
VALUE rb_obj_clone _((VALUE));
VALUE rb_obj_dup _((VALUE));
VALUE rb_obj_init_copy _((VALUE,VALUE));
VALUE rb_obj_taint _((VALUE));
VALUE rb_obj_tainted _((VALUE));
VALUE rb_obj_untaint _((VALUE));
VALUE rb_obj_freeze _((VALUE));
VALUE rb_obj_id _((VALUE));
VALUE rb_obj_class _((VALUE));
VALUE rb_class_real _((VALUE));
VALUE rb_class_inherited_p _((VALUE, VALUE));
VALUE rb_convert_type _((VALUE,int,const char*,const char*));
VALUE rb_check_convert_type _((VALUE,int,const char*,const char*));
VALUE rb_check_to_integer _((VALUE, const char *));
VALUE rb_to_int _((VALUE));
VALUE rb_Integer _((VALUE));
VALUE rb_Float _((VALUE));
VALUE rb_String _((VALUE));
VALUE rb_Array _((VALUE));
double rb_cstr_to_dbl _((const char*, int));
double rb_str_to_dbl _((VALUE, int));
/* parse.y */
RUBY_EXTERN int   ruby_sourceline;
RUBY_EXTERN char *ruby_sourcefile;
int ruby_yyparse _((void));
ID rb_id_attrset _((ID));
void rb_parser_append_print _((void));
void rb_parser_while_loop _((int, int));
int ruby_parser_stack_on_heap _((void));
void rb_gc_mark_parser _((void));
int rb_is_const_id _((ID));
int rb_is_instance_id _((ID));
int rb_is_class_id _((ID));
int rb_is_local_id _((ID));
int rb_is_junk_id _((ID));
int rb_symname_p _((const char*));
int rb_sym_interned_p _((VALUE));
VALUE rb_backref_get _((void));
void rb_backref_set _((VALUE));
VALUE rb_lastline_get _((void));
void rb_lastline_set _((VALUE));
VALUE rb_sym_all_symbols _((void));
/* process.c */
int rb_proc_exec _((const char*));
VALUE rb_f_exec _((int,VALUE*));
int rb_waitpid _((int,int*,int));
void rb_syswait _((int));
VALUE rb_proc_times _((VALUE));
VALUE rb_detach_process _((int));
/* range.c */
VALUE rb_range_new _((VALUE, VALUE, int));
VALUE rb_range_beg_len _((VALUE, long*, long*, long, int));
VALUE rb_length_by_each _((VALUE));
/* random.c */
unsigned long rb_genrand_int32(void);
double rb_genrand_real(void);
void rb_reset_random_seed(void);
/* re.c */
int rb_memcmp _((const void*,const void*,long));
int rb_memcicmp _((const void*,const void*,long));
long rb_memsearch _((const void*,long,const void*,long));
VALUE rb_reg_nth_defined _((int, VALUE));
VALUE rb_reg_nth_match _((int, VALUE));
VALUE rb_reg_last_match _((VALUE));
VALUE rb_reg_match_pre _((VALUE));
VALUE rb_reg_match_post _((VALUE));
VALUE rb_reg_match_last _((VALUE));
VALUE rb_reg_new _((const char*, long, int));
VALUE rb_reg_match _((VALUE, VALUE));
VALUE rb_reg_match2 _((VALUE));
int rb_reg_options _((VALUE));
void rb_set_kcode _((const char*));
const char* rb_get_kcode _((void));
void rb_kcode_set_option _((VALUE));
void rb_kcode_reset_option _((void));
/* ruby.c */
RUBY_EXTERN VALUE rb_argv;
RUBY_EXTERN VALUE rb_argv0;
void rb_load_file _((const char*));
void ruby_script _((const char*));
void ruby_prog_init _((void));
void ruby_set_argv _((int, char**));
void ruby_process_options _((int, char**));
void ruby_load_script _((void));
void ruby_init_loadpath _((void));
void ruby_incpush _((const char*));
/* signal.c */
VALUE rb_f_kill _((int, VALUE*));
void rb_gc_mark_trap_list _((void));
#ifdef POSIX_SIGNAL
#define posix_signal ruby_posix_signal
void posix_signal _((int, RETSIGTYPE (*)(int)));
#endif
void rb_trap_exit _((void));
void rb_trap_exec _((void));
const char *ruby_signal_name _((int));
void ruby_default_signal _((int));
/* sprintf.c */
VALUE rb_f_sprintf _((int, VALUE*));
VALUE rb_str_format _((int, VALUE*, VALUE));
/* string.c */
VALUE rb_str_new _((const char*, long));
VALUE rb_str_new2 _((const char*));
VALUE rb_str_new3 _((VALUE));
VALUE rb_str_new4 _((VALUE));
VALUE rb_str_new5 _((VALUE, const char*, long));
VALUE rb_tainted_str_new _((const char*, long));
VALUE rb_tainted_str_new2 _((const char*));
VALUE rb_str_buf_new _((long));
VALUE rb_str_buf_new2 _((const char*));
VALUE rb_str_tmp_new _((long));
VALUE rb_str_buf_append _((VALUE, VALUE));
VALUE rb_str_buf_cat _((VALUE, const char*, long));
VALUE rb_str_buf_cat2 _((VALUE, const char*));
VALUE rb_obj_as_string _((VALUE));
VALUE rb_check_string_type _((VALUE));
VALUE rb_str_dup _((VALUE));
VALUE rb_str_locktmp _((VALUE));
VALUE rb_str_unlocktmp _((VALUE));
VALUE rb_str_dup_frozen _((VALUE));
VALUE rb_str_plus _((VALUE, VALUE));
VALUE rb_str_times _((VALUE, VALUE));
VALUE rb_str_substr _((VALUE, long, long));
void rb_str_modify _((VALUE));
VALUE rb_str_freeze _((VALUE));
void rb_str_set_len _((VALUE, long));
VALUE rb_str_resize _((VALUE, long));
VALUE rb_str_cat _((VALUE, const char*, long));
VALUE rb_str_cat2 _((VALUE, const char*));
VALUE rb_str_append _((VALUE, VALUE));
VALUE rb_str_concat _((VALUE, VALUE));
int rb_str_hash _((VALUE));
int rb_str_cmp _((VALUE, VALUE));
VALUE rb_str_upto _((VALUE, VALUE, int));
void rb_str_update _((VALUE, long, long, VALUE));
VALUE rb_str_inspect _((VALUE));
VALUE rb_str_dump _((VALUE));
VALUE rb_str_split _((VALUE, const char*));
void rb_str_associate _((VALUE, VALUE));
VALUE rb_str_associated _((VALUE));
void rb_str_setter _((VALUE, ID, VALUE*));
VALUE rb_str_intern _((VALUE));
/* struct.c */
VALUE rb_struct_new __((VALUE, ...));
VALUE rb_struct_define __((const char*, ...));
VALUE rb_struct_alloc _((VALUE, VALUE));
VALUE rb_struct_aref _((VALUE, VALUE));
VALUE rb_struct_aset _((VALUE, VALUE, VALUE));
VALUE rb_struct_getmember _((VALUE, ID));
VALUE rb_struct_iv_get _((VALUE, const char*));
VALUE rb_struct_s_members _((VALUE));
VALUE rb_struct_members _((VALUE));
/* time.c */
VALUE rb_time_new _((time_t, time_t));
/* variable.c */
VALUE rb_mod_name _((VALUE));
VALUE rb_class_path _((VALUE));
void rb_set_class_path _((VALUE, VALUE, const char*));
VALUE rb_path2class _((const char*));
void rb_name_class _((VALUE, ID));
VALUE rb_class_name _((VALUE));
void rb_autoload _((VALUE, ID, const char*));
VALUE rb_autoload_load _((VALUE, ID));
VALUE rb_autoload_p _((VALUE, ID));
void rb_gc_mark_global_tbl _((void));
VALUE rb_f_trace_var _((int, VALUE*));
VALUE rb_f_untrace_var _((int, VALUE*));
VALUE rb_f_global_variables _((void));
void rb_alias_variable _((ID, ID));
struct st_table* rb_generic_ivar_table _((VALUE));
void rb_copy_generic_ivar _((VALUE,VALUE));
void rb_mark_generic_ivar _((VALUE));
void rb_mark_generic_ivar_tbl _((void));
void rb_free_generic_ivar _((VALUE));
VALUE rb_ivar_get _((VALUE, ID));
VALUE rb_ivar_set _((VALUE, ID, VALUE));
VALUE rb_ivar_defined _((VALUE, ID));
VALUE rb_iv_set _((VALUE, const char*, VALUE));
VALUE rb_iv_get _((VALUE, const char*));
VALUE rb_attr_get _((VALUE, ID));
VALUE rb_obj_instance_variables _((VALUE));
VALUE rb_obj_remove_instance_variable _((VALUE, VALUE));
void *rb_mod_const_at _((VALUE, void*));
void *rb_mod_const_of _((VALUE, void*));
VALUE rb_const_list _((void*));
VALUE rb_mod_constants _((VALUE));
VALUE rb_mod_remove_const _((VALUE, VALUE));
int rb_const_defined _((VALUE, ID));
int rb_const_defined_at _((VALUE, ID));
int rb_const_defined_from _((VALUE, ID));
VALUE rb_const_get _((VALUE, ID));
VALUE rb_const_get_at _((VALUE, ID));
VALUE rb_const_get_from _((VALUE, ID));
void rb_const_set _((VALUE, ID, VALUE));
VALUE rb_mod_constants _((VALUE));
VALUE rb_mod_const_missing _((VALUE,VALUE));
VALUE rb_cvar_defined _((VALUE, ID));
#define RB_CVAR_SET_4ARGS 1
void rb_cvar_set _((VALUE, ID, VALUE, int));
VALUE rb_cvar_get _((VALUE, ID));
void rb_cv_set _((VALUE, const char*, VALUE));
VALUE rb_cv_get _((VALUE, const char*));
void rb_define_class_variable _((VALUE, const char*, VALUE));
VALUE rb_mod_class_variables _((VALUE));
VALUE rb_mod_remove_cvar _((VALUE, VALUE));
/* version.c */
void ruby_show_version _((void));
void ruby_show_copyright _((void));
PK     Y\ʏ      x86_64-linux/re.hnu [        /**********************************************************************

  re.h -

  $Author: shyouhei $
  $Date: 2011-05-21 07:29:10 +0900 (Sat, 21 May 2011) $
  created at: Thu Sep 30 14:18:32 JST 1993

  Copyright (C) 1993-2003 Yukihiro Matsumoto

**********************************************************************/

#ifndef RE_H
#define RE_H

#include <sys/types.h>
#include <stdio.h>

#include "regex.h"

typedef struct re_pattern_buffer Regexp;

struct RMatch {
    struct RBasic basic;
    VALUE str;
    struct re_registers *regs;
};

#define RMATCH(obj)  (R_CAST(RMatch)(obj))
#define RMATCH_REGS(obj)  (R_MATCH(obj)->regs)

VALUE rb_reg_regcomp _((VALUE));
long rb_reg_search _((VALUE, VALUE, long, long));
VALUE rb_reg_regsub _((VALUE, VALUE, struct re_registers *));
long rb_reg_adjust_startpos _((VALUE, VALUE, long, long));
void rb_match_busy _((VALUE));
VALUE rb_reg_quote _((VALUE));

RUBY_EXTERN int ruby_ignorecase;

int rb_reg_mbclen2 _((unsigned int, VALUE));
#define mbclen2(c,re) rb_reg_mbclen2((c),(re))
#endif
PK     Y\O        x86_64-linux/dln.hnu [        /**********************************************************************

  dln.h -

  $Author: shyouhei $
  $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
  created at: Wed Jan 19 16:53:09 JST 1994

  Copyright (C) 1993-2003 Yukihiro Matsumoto

**********************************************************************/

#ifndef DLN_H
#define DLN_H

#ifdef __cplusplus
# ifndef  HAVE_PROTOTYPES
#  define HAVE_PROTOTYPES 1
# endif
# ifndef  HAVE_STDARG_PROTOTYPES
#  define HAVE_STDARG_PROTOTYPES 1
# endif
#endif

#undef _
#ifdef HAVE_PROTOTYPES
# define _(args) args
#else
# define _(args) ()
#endif

char *dln_find_exe _((const char*,const char*));
char *dln_find_file _((const char*,const char*));

#ifdef USE_DLN_A_OUT
extern char *dln_argv0;
#endif

void *dln_load _((const char*));
#endif
PK     Y\39
  
    x86_64-linux/missing.hnu [        /************************************************

  missing.h - prototype for *.c in ./missing, and
  	      for missing timeval struct

  $Author: shyouhei $
  $Date: 2010-11-22 16:21:27 +0900 (Mon, 22 Nov 2010) $
  created at: Sat May 11 23:46:03 JST 2002

************************************************/

#ifndef MISSING_H
#define MISSING_H

#if defined(HAVE_SYS_TIME_H)
#  include <sys/time.h>
#elif !defined(_WIN32)
#  define time_t long
struct timeval {
    time_t tv_sec;	/* seconds */
    time_t tv_usec;	/* microseconds */
};
#endif
#if defined(HAVE_SYS_TYPES_H)
#  include <sys/types.h>
#endif

#if !defined(HAVE_STRUCT_TIMEZONE)
struct timezone {
    int tz_minuteswest;
    int tz_dsttime;
};
#endif

#ifndef HAVE_ACOSH
extern double acosh _((double));
extern double asinh _((double));
extern double atanh _((double));
#endif

#ifndef HAVE_CRYPT
extern char *crypt _((const char *, const char *));
#endif

#ifndef HAVE_DUP2
extern int dup2 _((int, int));
#endif

#ifndef HAVE_EACCESS
extern int eaccess _((const char*, int));
#endif

#ifndef HAVE_FINITE
extern int finite _((double));
#endif

#ifndef HAVE_FLOCK
extern int flock _((int, int));
#endif

/*
#ifndef HAVE_FREXP
extern double frexp _((double, int *));
#endif
*/

#ifndef HAVE_HYPOT
extern double hypot _((double, double));
#endif

#ifndef HAVE_ERF
extern double erf _((double));
extern double erfc _((double));
#endif

#ifndef HAVE_ISINF
# if defined(HAVE_FINITE) && defined(HAVE_ISNAN)
# define isinf(x) (!finite(x) && !isnan(x))
# else
extern int isinf _((double));
# endif
#endif

#ifndef HAVE_ISNAN
extern int isnan _((double));
#endif

/*
#ifndef HAVE_MEMCMP
extern int memcmp _((char *, char *, int));
#endif
*/

#ifndef HAVE_MEMMOVE
extern void *memmove _((void *, void *, int));
#endif

/*
#ifndef HAVE_MODF
extern double modf _((double, double *));
#endif
*/

#ifndef HAVE_STRCASECMP
extern int strcasecmp _((char *, char *));
#endif

#ifndef HAVE_STRNCASECMP
extern int strncasecmp _((char *, char *, int));
#endif

#ifndef HAVE_STRCHR
extern char *strchr _((char *, int));
extern char *strrchr _((char *, int));
#endif

#ifndef HAVE_STRERROR
extern char *strerror _((int));
#endif

#ifndef HAVE_STRFTIME
extern size_t strftime _((char *, size_t, const char *, const struct tm *));
#endif

#ifndef HAVE_STRSTR
extern char *strstr _((char *, char *));
#endif

/*
#ifndef HAVE_STRTOL
extern long strtol _((char *, char **, int));
#endif
*/

#ifndef HAVE_STRTOUL
extern unsigned long strtoul _((char *, char **, int));
#endif

#ifndef HAVE_VSNPRINTF
# ifdef HAVE_STDARG_PROTOTYPES
#  include <stdarg.h>
# else
#  include <varargs.h>
# endif
extern int snprintf __((char *, size_t n, char const *, ...));
extern int vsnprintf _((char *, size_t n, char const *, va_list));
#endif

#endif /* MISSING_H */
PK     Y\mɐ      x86_64-linux/bigdecimal.sonu ȯ        ELF          >    p      @                 @ 8 	 @                                                           `      `      `      8                          x      x      x      0      0                   8      8      8      $       $                                                             Std                                            Ptd   0      0      0                         Qtd                                                  Rtd   `      `      `                                  GNU 1<knv       4         @(@@ 4   9       BE|X=|/\9wqX                        2                                                                Q                                            b                                                                                                                                !                                                               i                                                                                      @                                          Z                                                                                                                                                       ?                                                                                                          #                                                                v                     +                     i                                                                                    ,                                            w                                          F   "                                                                                   L                                                                                                               v                  U                                     __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize gOne_ABCED9B4_CE73__00400511F31D gZero_ABCED9B1_CE73__00400511F31D ruby_xfree rb_fatal rb_eFloatDomainError rb_raise ruby_xmalloc memset strlen __ctype_b_loc memmove rb_scan_args rb_check_type rb_fix2int __stack_chk_fail rb_eTypeError rb_str_new2 __sprintf_chk rb_str_tmp_new rb_str_resize rb_warn rb_cBigDecimal rb_data_object_alloc memcpy rb_string_value rb_check_safe_obj rb_bug rb_int2inum rb_eArgError rb_big2str rb_obj_classname rb_inspect rb_str_new rb_assoc_new rb_num_coerce_relop rb_num_coerce_cmp __errno_location strtod rb_float_new rb_num_coerce_bin rb_ary_new2 rb_ary_push rb_cstr2inum sqrt Init_bigdecimal rb_cNumeric rb_define_class rb_define_global_function rb_define_singleton_method rb_define_const rb_define_method libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 GLIBC_2.3.4 GLIBC_2.3 GLIBC_2.14 GLIBC_2.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                  w         ui	                `   ti	        ii                ii        ui	           C         ui	         `             @      h                    p             p                                                       	                    5           ȿ         9           п                    ؿ                             *                    -                    8                    .                                                    (                    0                    8                    @                    H         
           P                    X                    `                    h                    p                    x                                                                                                                                                                                                                                                                                                                      !                    "                     #                    $                    %                    &                     '           (         (           0         )           8         +           @         ,           H         .           P         /           X         0           `         1           h         2           p         3           HH	  HtH             5"  %#   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1%]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %ݩ  D  %թ  D  %ͩ  D  %ũ  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %}  D  %u  D  %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %   H%    f.     fH=  H  H9tH  Ht	        H=Ѩ  H5ʨ  H)HHH?HHtH  HtfD      =   u+UH=   HtH=N  de  ]     w    !   fD  H     Bf  f   f   fU  f   HJfH    Ht0f*J Y  XHvf*J(Y  XRHcHffW     H    1H        p  f.  z,u*H   H  ^fW  :     H    f       ff.ztJ  H%  f. z%u#H6  ^fWF  Φ  ^  1H    @   f.Ѕ  `ZH   HҤ  ^z  3u  f.  zuH   ^N  H    ff.     fHtfff.     @ GfttRHft&vftf tH=x  1L@ fuH  HH5x  H81    f=  u1@ UHSHHHtHH1MH[]fD     H57x  @   J     AWAVAUATUSHt$~   HIHtn] tfE1E17fD  .   EtJAMeD9|$|SM9v6H] Mt'ÀuUH DP uCըuMeM9wH[]A\A]A^A_f     IH}HE1LL)WE  뎐MeE1    H(HNw  dH%(   HD$1HL$LD$u	HD$   H|$
   eH|$t_HL$  H   H   t׉փHDf5     ѣ  HD *    H=      H|$Hu!Hz  HD HT$dH3%(   u_H(þ
   H|$H|$H;  HD @ ЃHEfB  lD  HD H  H5y  H81H  H5y  H81H=u  HtSGPfwI       HsD  HW>FHDuOHDx9~)эHcHfD     fHcH@ ftftEftO1ftfNaN    @ fuJ   t|0.0    Ãt[u+HHInfinityF H        -0.0   F H-InfinitHy   fF   @  H    +0.0   F  0.0   F AWIAAVAUATUSHH(H<$T$Ht$u-f{ ~5A  HD$Au(HH@+D  H([]A\A]A^A_A-IA0.  Lx   E1IfH$H@HD$HJ  D  H$	    Nl   L1HHIIHHtKHt
   I9rL1Hs  LH   HI1L1ID  IL9d$qH4$AFHN DMcHw$H̺ fHIHHH9r@0u    IA A0tHr  HL1   tD$t$H|$H([]A\A]A^A_\Ht$HF H4$.   FHN DMcHFD  G0~9~NW   D  9}yf HG     HG   ~Y   fw1H5r     D  f ~A   HG     HG   fW1H5q     D  fOD  HG     HG   fGff.     fOAfw#]   HsHG     1HG   ÐHWf.     HBH|  u,HHuHG     HG   f~_   1fW USHHo HWHth HHuH|  t   HtH)HHWvuH[] fG1HCHt(H{ H       ɸ   @ HWAWH88HAVHAUATUSHHBHHL%  HD$H  .H@ŀu%H H+@ŀu@DA u@#  M]  HE1E1Hx   HhHD$IHHHDdEe EtMAĀu&HL$MAHL$H Pf% fIA_t#IN,1HDdEe EuH MuAE  HMIt3B\5Àu(BD%  ItB\% Àu
HDZ u߹
   H=Wo  H   	   H=:o  H {  
   H=%o  H      H=p  H   E <-  E1<+A   AFd5 E-  AĀA  E1H&fD  IIIFd5 Eq  IAĀuADBuA.  HD$0    BT5 LE1H88JHPHHHH!     IHHH      HH!   I~LT= AHՁ   u
BD5I~H|$8q  DAƀc  HT$(1LL$ LT$H|$8LT$H0LL$ HD= HT$(f     HD4EtAƀuBDvu@ HD$LL$(LT$ H9ILBJ(   HHT$AHT$LT$ ILxLL$(H@     H@   r     fHH(1I~ LL$LT$HLL$2  LT$A<-     1<+uABH   0Ay!K   ACDHD92  AHH9rDE <-  <+>  LA   1E1A98     EEADD1D)׉A9
  DE1AD)H9b   OIA     Hw4H9v/1    H<HD HHHDxIA HwH9rH9  HMtfHt$0OL 1LT5      I9  H  I	H    I<HHHHLOI	HwI9wI9C  M9|  MGHw%KHA      HHHH	uHA AM~LAVfAF5H|$1yo    IHt$H88LHHHBH9HFHD$qfD  0   A   H@   IH@     H@   fD@HHL[]A\A]A^A_fD  H    AA   s    IM9v51     H    II1M9]HH=m  1LD$T$LD$HދT$M9MxD  H\     E1&     fAFH<0   A   IHD$IF     IFIF   fEN    0   IH@   H@     H@   fxD  IQ	II1H88HE1HD$0    HHHsIqA   l0   1IH@   H@     H@   fp'BT5I^H\$0upLE1H88HHHHHI11H5oh     SHAB   xIqA         LL$ IE1T$_T$LL$ H IIBT5 tuDPuK!BT5 mK4K[MHA   Tf.     I   E11HD$0    E1E11LLt$0E1 SH1HHH$  H8HH[@ SHH   HGHpHtRHHA HPHQ Hɚ;vuH"    HD HPHT HHɚ;vMH-ɚ;HD(HuԾ   HtHC       HC   [@ Hy    H   [f     AWAAVAUATUSH8GD$A  D98LGD)1HcIH\$L9D  ۍKL\ D)LcDhH   HD$E  E1   1@ HH4D9|HL1EHHHL1HHHIHHHHHHH)Ht$M  M9  HcHt HSZ/D HH	HHHHi ʚ;H9  Hc+Ht HHH	HHHHi ʚ;H9  AI9wHD$M)1DL$$J    H| DL$$A    At2Au,H|$  uA  H؃HHfD  ExA1D  HHD9uHɚ;  ES  f} EHE   HE    %     fMEEtWD98UA)t@HSZ/D HU 1fHHHɚ;vH	EHHHA9uHU    H8[]A\A]A^A_fD  F  LG1MtAL_ A   E1HD$      A   HD$        HD$M)1DL$$J    L\$(H| DL$$AHh  L\$(JcH>D  fUf.     Hg    H|$HQAFH|$H7M.1f} H@ J\ HhfD  f HG     HG      A   1fDGH8[]A\A]A^A_AfD  HD$M)1DL$$J    H| DL$$AHg  JcH>    JD     Ht$HD  1fw     EL޻
   E1E11f} HAEAFHHD HHff.     LW MtWI̋G)LAIHHI	w
D  HHAIHH	wAP     1ff.     fATIUH-  SH*tfHtQHt<HH88HUHH1HH9w+5s  [L]A\5D  I\$f     1[]A\f     f     AUIATIUHSHcHHRu>Mt9H=  w/H  H	f  HcH>    Ivf} ~ H[]A\A]D  Ivf} ~HHHH[]A\A] IE#wD  IdwD  IE#wI eIwAt    Iwjf.     AVAUATUSFHf   Af   f   Pf  VLnHH Hv WDfAOąL9oLFoLoN4    fGLA
t+L9m   L1HM MtHUDHCLkCD []A\A]A^ÐDHC     fHC   DNE~?   1fs[]A\A]A^ HG     1HG   1f{[]A\A]A^    1fK DHG     fHG   DNE~/      fWR@ 1HLk6D  fG   #ff.     fATAUպ
   SH:~DH[]A\4@ [1]A\f     H~  tyHcF~qHVNH9stH)HGG    H9HG1fHWfGHcFHt"HHHLfHL IL HH9uH        fD  HG     HG   f~   fWÐfGfD  SHftftQft+H[fD  1H5`     ]H[     1H5`     =H[     1H5`     H[     AVAUATIUSH0Ht$H|$dH%(   HD$(1H|$4HD$LpA   I:   @ŀ   0E1H     I:t0@ŀ   DZ   0AKD HcLlE uI	IELLGLH1LHH9HHD$Iv"H88LHHH9SvHHSsH]HL$(dH3%(   uPH0[]A\A]A^L16H1LHHHHD$H  H5__  H81     f   f   ffAD	ftcft]      C    f   A   HG     HG   fDG1H5u^      t\   t  f   f~W1HG     1H5
Z  HG   fO   f.        tRfXf     HG     HG   fwLf   f.     VfkfffD  fCf.     Pf+f~Lf~L   HG     HG   fW     f~ff4f~HG     HG   fGvff.     AWE1IAVAUATIUHSHHXHF     HF   fDVAwHT$@HQ      AWAL$rAf   f;  f  f     HE     HE   fEHt$@AD$f~ %  f     HC     HC   fSHEHX[]A\A]A^A_f(  ID$HD$HH  HEH|$@HD$0HwHCHD$H9  HC     H  HV   HHLHL HHH9uHD$H9T$vfD  HHD    H9u1H|$0 HT$0l   HHD    H9uID$ HD$8Hi ʚ;H|$HHD$ HD$v(ID$(HD$8HD$ 1Ht$ H|$HHHD$HD$Ht$0HH9HGHD$H  HD$HA   ISZ/D H4    LpHt$(f     J    IuH<HG H  Hi ʚ;HG(H9D$   H9D$  H;t$04  1Ht$8HD(ML$MIL;L$u  Ht$(LJL E1HLLMlfD  HH	HIHHi ʚ;H)H9A  H ʚ;NDH)HL(HL L9   H ʚ;L)A   HL LH)I9r<I|HIHɚ;wH9  H)HL(MuLHL H)I9sL)HL JD JTH=ɚ;v&@ H- ʚ;HHBHBHHBH=ɚ;wL;l$HD$0   HHEHD$@@E"|  HX1[]A\A]A^A_f     L)E1HL IL;l$"1Ht$HD IID$MLbfLT$HIUIv<H0I9|$0 r+MK<*IOM\ L9\ w	HH9uID$LPOL L9L$|  L)L1M(fD  H ʚ;   L)HD HLH)L9w&I|HD L7L9rH)1H)f     HHA HHA kfa  fa  A   HE     HE   fDE1H5S     HX[]A\A]A^A_At$HmHt$@AD$f~ K  ffEH%HD$L|$@H߾   HCAGC31fA HfCf{HE     HE   fuvI|$ AT$fL|$@HNLfA THC     HC   fKOfHE     HE   f}E11H5&R     HE     HE   fDMff   ]ID$ HD$8Hi ʚ;H|$HHD$ H=9V  11H)IHL(ff.     GPfwI   HHsFPfvKWNHGH9FHCF9tۉ))HHcHsH1ҿ   H5P  HHD  I   HHsD  AW   AVAUATIUHSHHH(v  AD$KPfG  Qf9  Mt$I  L{I  M9d  HEO,7HD$    I}HH<$H9  CHEAt$j  f{ AD$<  ffEJ    1H} HHL$bH<$ LmHL$-  I}Hl$IFIH|$LLE1IISZ/D  M9  MLM)LL9   M\ D  J| I;HHH	HIHHHi ʚ;H)IqIqHɚ;!  HH	HIHHHi ʚ;H)IqIILIIHɚ;v: HHH	HIHHi ʚ;H)HNHNHHNHɚ;wIII9@IIL94$Hl$H|$   HH|$   HHHD$H@H([]A\A]A^A_     f   f      HE        HE   fUH([]A\A]A^A_ÐH(1[]A\A]A^A_LMIHLII|$ bAT$TfHHNHl$;fD  H{ 1S%fɸLHNHl$f)HE     fE   HE   H([]A\A]A^A_K| H5{M  9Hl$H@ Hɚ;BfD  HD$L)M9rMHM)WD  HE1Sf1HHl$9ff.     ATUHSHH=Xy  dH%(   HD$1#HHIHL  1jt%HT$dH3%(   Lu>H[]A\f     H<$HtѾ
   H<$SxHHx  /Hv  H5DL  H81    AWAAVIAUATIUSHH8vHɃtMANA|$QGfuFf  HC     HC   f  A      fDSH8[]A\A]A^A_D  f  AvE\$A   DEMnIT$D9     L9MLFMt5ID$ I9F w  1D  MD M9D wd  HI9uL9rPz  E1DfAfAOBDPMu+A   HC     	   HC   fDK MfDHkA   ffDCAOH}HC     DLHLD)LcJL9HCI$EtmH9  E1L9wM|IH9  ICH9  L)HMt   fD  DfDNAVfD{   W H9   1L9wILIH9  ICH9  L)ID HHD$(wDLHHCH8[]A\A]A^A_@ HLMMIŉDA@    LHxHC@ HD$(    Hi1ɉsH߾   HkLT$HL$ L\$HT$LT$d  <$ HT$L\$HL$ K  H  HD$(H9  H$       IL9   ʚ;"fHI+L JHL    L9p  HHH)HHuILD  HiE1E1sH߾   HkDL$L\$ HT$LT$>DL$  <$ LT$HT$L\$   H  K7H$IL9   IsHHHt(     HIL HL I9s_HHHuHD     LHL)HtL9  HHD     H9u1       IHKL HL I9wH  LH|HH)M1f.     H1HHt2ILHIL HH=ɚ;vH- ʚ;H   f     HI)H)MtEHLL     H1HHt"HID H=ɚ;vH- ʚ;H   ֐L)HuH1AfCHSHtHTH$H1HCH8[]A\A]A^A_fHDf     H)H$1|fHD$(    fE1     L95  HLL)Lf.     HIt It H9uHL)HthHHHH4HM2LH H)ȹ   H ʚ;L)ID Ht%IDHM\ M,L9rH)1L)@ H)H)HtHHH)H4HfD  H)1HT Ht!HIT H9sɚ;       H)HtH)LM9t.fAz A1AfCff.     fA~       fSBfD  sH߾   HkLT$LT$t<$    @ H$    p sH߾   HkDL$LT$rDL$t<$ LT$tfD  H$        LHDL$SH$    DL$yLֺ   HLT$+H$    LT$f     fCNL    OH11Hff.     USHH   dH%(   H$   1   Hu/   1H$   dH3%(      HĘ   []@ t̋?t)"uTHuH9Cu"   HHC @ 
   HHXHHHx
3yfD  
`HHH=B  1HIغ      H   4Hu)Ht HHl  H5G  H81~H@     USHH`B  HHdH%(   HD$81HH߾   wH5DC  HH HHD$1Hp2H(B     HHD$HD$HXHEHL1H11HH4HH|$HHD$HT$8dH3%(   uHH[]qH   P1ftft   ft
HD  1HÐH   ~P   ft1fHDHff.     H   >fx HHff.     H   H@HHD ff.     @ AT   USHH@dH%(   HD$81H5A  HH HHD$1P	H
   Iؾ   H`@  HD$HD$HL`1LL1ɺ
   HIHHHMHU   H<1LLHH@  LH|$HHD$H\$8dH3%(   u	H@[]A\s S   H@f   HDH[D  H   @fHHD  H   dH%(   HD$1NHH$HPHtH|$dH3<%(   HDu>HfHxHt%1D  HHH)HT HHH1H9uHc@H脿@ HH   H H U   SH8dH%(   HD$(1H5S>  HH H$HEH<HkHHH HHD$%HD$(dH3%(   usH8H[]޾ff.      U   SH8dH%(   HD$(1H5=  HH H$HEH<H1ɺ   HHH HHD$NHD$(dH3%(   usH8H[],G    U   SH8dH%(   HD$(1|H53=  HH H$HEH<HKH   HH HHD$sf1)fsHD$(dH3%(   uH8H[]諽ff.     U   SH8dH%(   HD$(1H5<  HH H$HEH<HHHH HHD$pHD$(dH3%(   usH8H[]f     AUATUSHH<  HHL-h  dH%(   HD$81HL$Hqh      謼Aą   H߾   H5;  HH HD$HEH<H   DHHH L-h  HHD$MsHAHT$8dH3%(   u2HH[]A\A]fD  H|$
   H|$7A^f.     AUATUSHH;  HHL-g  dH%(   HD$81HL$Hqg      謻Aą   H߾   H5:  HH HD$HEH<H   DHHH L-g  HHD$MsHAHT$8dH3%(   u2HH[]A\A]fD  H|$
   H|$7A^f.     AUATUSHH:  HHL-f  dH%(   HD$81HL$Hqf      謺Aą   H߾   H59  HH HD$HEH<H   DHHH L-f  HHD$MsHAHT$8dH3%(   u2HH[]A\A]fD  H|$
   H|$7A^f.     AVAUATUSHH[9  H@D-Oe  dH%(   HD$81HLD$貹   E1u6H<$
   sH<$躻H|$
   AXH|$螻AH߾   L5e  He      H58  HH HD$HEH<HDDHHH L5d  HHD$sHHT$8dH3%(   u2H@[]A\A]A^fD  H<$
   誹H<$ANԸ@ H   1HH PHt3<HcHw$H̺ fHHHHH9rH@ U   SHdH%(   HD$1HH H$HCH<起HHCH<襷HT$dH3%(   uHHH[]ff.     @ AUATI   UHSH8dH%(   HD$(1$1LIH H$H   HHT$AUf  Hf  f@f@	f   f   @e  qzf   f(  f   *"9  H;  HcH>    *  =   HD$(dH3%(     H8LH[]A\A]=D  )@EЅB*؀"  H;  HcH>ff   fOfD  *"  H<  HcH>     u> 1HL$(dH3%(   D  H8[]A\A]    LHHtŸ   fD     *u@ fofHD$(dH3%(     H8LH[]A\A]闶    t_       PfD  f   f   xA9}   f*"wpH;  HcH>fD  %    HHHf.     *"wH;  HcH>   H=8  1蜴@ fQ*"wH<  HcH>f~߃*"wH<  HcH>LHMEM9LIFHt*Iu H9p rwL1 LT M9T wr7HH9uM9s7f   *"MH<  HcH>flFv*f~˃*"H<  HcH>*"HZ=  HcH>Hz1HHl   *"H=  HcH>ff.     G   f>   rfL   bf<   Rf=   Bf*   2fAWAVAUATUHSH
   HHHdH%(   HD$81諳HHIHHx	   HEؾ   HIH HD$AEf  IEH51  H<H?H{HHH HD$AEDPfuEE  f  E  A   HC        HC   fDC  D  fw/I   Hs$1HC     fs1HC         A}  E  >  HD$DHCH50  H|苿H50  IH@HH| 	o   LHI       LLLc   u  fD  HLLLH$#   LLSH$H	L9vLHL)   LH&H|$  MtLLs` I   HH5/     HH HD$!        HC      C   HC    fCHD$8dH3%(   a  HHH[]A\A]A^A_!E   AHC     HC   f{D  HD$   :f.     I}I}    HC      fKfA} C   HC    >A4fS!@    hfD  A   HC        HC   fDS AtAHC     HC   fDKD  HZ  LLH   LH+U   SH8dH%(   HD$(1,Ht$H|$HH HHD$    H|$4  ~k1H52     D$ff/   Y  f.z$u"HW   HX  ^Y  D$gf.     HH5Z.  1Hǯ11HHD$HD$HhH蕭1H     H蒭;"D$8NHL$(dH3%(   ueH8[]    D$% Y  f.LFHW   H6W  ^fWF8  X  T@ UHSHH(dH%(   HD$1Ht?@u9@t3?u)HT$dH3%(   uFH(HH[] H߾   ;H8H<$HD$dH3%(   uH(H[]ƭ豬AUI   ATUHSH8dH%(   HD$(11LIH H$HtiHH H5z+  HD$HCID$H<HHLHH HHD$HD$(dH3%(   u>uH8H[]A\A] HD$(dH3%(   uH8LH[]A\A];֫fD  AUI   ATIUSH8dH%(   HD$(11LHH H$H  HH f{ HD$tf} u,HE HT$(dH3%(   !  H8[]A\A]f     HHIHt|H<H5?*  HiIH HD$Muuf} ID$     ID$            fAT$HD$(dH3%(      H8L[]A\A]fD  H5)  
   IH HD$HHLqAt$f     HD$(dH3%(   u-H8LL[]A\A]髫 fAD$W.ff.      AUI   ATIUSH8dH%(   HD$(1R1LHH H$>H  HH f{ HD$tf} u,HE HT$(dH3%(   !  H8[]A\A]f     HHIHt|H<H5(  HIH HD$Muuf} ID$     ID$            fAT$HD$(dH3%(      H8L[]A\A]fD  H5(  
   ?IH HD$H   HLAt$f     HD$(dH3%(   u-H8LL[]A\A] fAD$W~ff.      AW   AVAUATUSHXdH%(   HD$H1H5q(  IH LHD$ ʰ1HЩHD$H@HD$AD$fc  f  f  Pf  fHD$R  -0  @ fHD$    <-  IL$ <NHl-   HDAD$1Ht3HcHw$H̺ fHHHHH9r   HHIըLt$LLŨH|$LHP   L裨H苦LH萨LHt$HdH34%(     HX[]A\A]A^A_f.     Ht$If/  ID$HD$H      1D  Mt A	    +fD  L1HHIHHHAtKHt
   I9rL1H$  LH   HI1LL1ID  HH9l$iA0A 4f.     IA A0t@ Lt$InH跥HLHHcHA AHD$ NaN L~-@ 0   f HInfinityHD$H0@ D  H-InfinitHD$H0y   fpj+ff.     U   SHHdH%(   HD$81\HH DCHD$fE  fA  fA  Hs H  C,HcHw*H̺ fD  HHHHH9rͅ;  	61fED HHD H\$8dH3%(   x  HH[]@ u1Hc98HD$HD$HxIf{    I	jE1IIHD9[~[ JD  fD  1HH0IшAHILHLHI9uICI	L9t9IIHD9[@ HA0LI9tHA0LI9ufD   HD$8dH3%(   ~   HH
   []Q   LG-!1H5%     臨   1H5%     j   1H5%     M   t΢ff.      AWAVAUI   ATUHSHxdH%(   HD$h11LIH HD$HP  HH H5!  HD$HCID$L,LOl-蔹LH5W!  HH HD$ zLH5=!  IH HD$(`LH5#!  IH HD$0FLHLIH HHD$8HEH5   L$MLLH5   IH LD$HD$@LD$1HIH    LHD$H_HLHLLV   LLLCHD$hdH3%(   N   AuHxL[]A\A]A^A_@ LHuHt$HL$hdH3%(   uHx[]A\A]A^A_'    AWI   AVIAUIATIUSHhdH%(   HD$X11LHH HD$H  HH HD$EPfwvI   HskH5!     誷H5   HH HD$    获HI$I] HT$(1HL$XdH3%(     Hh[]A\A]A^A_f     KQf/  f  HEH9CH5  HCCL|	LK|?H5  IH HD$ HHLIH LHD$(IFH5  H<H¶1ɺ   LIH LLD$HD$00LD$HLL-LHLAFLD$fttf} C~dfdLƹLLD$HJ  LD$HL   LLD$M<$ME ]   HF@ fM$Mu hfD  HD$XdH3%(   uHHhLL[]A\A]A^A_ǟ    H5w     蟵H5f  HH HD$ 3 H8dH%(   HD$(1HL$HH$    HD$    Hu"H$H|$H wHD$HHD$賿HT$(dH3%(   uH8蹝f     SH@dH%(   HD$81HL$HH$    HD$    Hu=H$H|$H wHD$HHD$2H<$Hw"HHGH\$8dH3%(   uH@[ff.     AUI   ATUHSHhdH%(   HD$X1B1LIH HD$0-H   HH H5  HD$8HCID$Ll	LK|-H5  HH HD$@гHLHIH LHD$HdHE Hs H$IE HD$HHD$Hu*HD$XdH3%(   umuHhH[]A\A]@ IiE  ʚ;1HHHUHT1H% LHEHt HL$XdH3%(   uHh[]A\A]ff.     S
   HbH誝x[HEE  H5  H81ff.     AWAVAUATUH   SHxdH%(   HD$h1HIH HD$@IF tH5;  9LHc]IH HD$HIF HuYAFft	f  L   LAt$L觼H\$hdH3%(     Hx[]A\A]A^A_@ fA~   I~u
HC  ID$H5  I9FHHIMnH<P>H5  HHD H|E H"It$H|$8HIcFH4$HPHHHHLHNH)Ht$0HD$FL|$0D$8HrqqLLHLH?HH988HH)HL$0H)HIH9t)D$8d$  HI^I?IID$8fQf.  f.  f(fTY$  f.!$    f.Q  f/f(wfW$  #  f/  #  E1f^If/sMT$1I|$ T$(D$ J    d$LT$2D$ fLT$d$T$(f/)  -#  M|  1-r#  H       3fD  H,fID H*\f/  I93  Yf/rf(\H,H1    E1H5F  1ID$     ID$       fET$肝At$8    ID$        ID$   fAT$H$E|$   HL<HNID$HIcHCd   LFE1;@    LHH}   HL譶HcCH9D$}kIM9}bID$HH9$sH$ID$LLHHCH=LHHH5B  HHCfgAD$H߉f1)fAD$H$ID$ HtHAt$     ID$     f/ID$   T     fAt$-\!  1f.     I9vKf/LRvPY¸   MT$fAD$El$f/I  \H,H?MT @@ 1f/IRYfAD$MT$El$f/   H,MuL1LfE1H5:  1ID$     ID$       fEL$"At$    @   E1E   f/q YIf/w[D  \H,H?\D  fAL$cA~A      ID$   AD$   ID$    fED$5@ H,fD  ID$     1ID$   fA|$̔d$聖fd$3fAVAUATUHH  SHPdH%(   HD$H1HLD$Y  H|$HcIH   HH5j  L-?  H?      腫H   HH HD$ }H<$   HH HD$(dHSH5  IH HJHD$0IFHEHH9HCH|	HLHHHHT$8H豹5?  HDL->?  ɰsHmH\$HdH3%(   uQHP[]A\A]A^H4$HTfH4$HL$HT$HHD$    aHuH|$w'    AUATIUHHSH(dH%(   HD$1Du0HD$dH3%(      H(LH[]A\A]    HLL-S>  HF>         L-5>  H5=  HH HH$裯HD$dH3%(   uuH(H[]A\A]-H     AUATIUHHSH(dH%(   HD$1du0HD$dH3%(      H(LH[]A\A]    HLL-s=  Hf=         L-U=  H5=  HH HH$îHD$dH3%(   uuH(H[]A\A]Mh     AUATIUHHSH(dH%(   HD$1u0HD$dH3%(      H(LH[]A\A]    HLL-<  H<         L-u<  H-5'<  HH HH$HD$dH3%(   uuH(H[]A\A]m舐     AWAVAUI   ATAHUSHXdH%(   HD$H1H\$HLDHH HP  HD$ 1tH5L  HE1E1誘1H谑HD$HD$LhDDLHљLɏH|$HHD$Ht$HdH34%(     HX[]A\A]A^A_@ H|$H  @  @  Aǋ?   HH|$'HD$LhA]     E1+uA]A   IE1fD  I   À  ߀F   H5}  H萗HE~Ic1HD1HHt1HD$HD$LhE}DL蹗f} ~JA@  LAu@I]AE +5@ E1AH5  HE1Hf AE -I]HELc}HD$My  E1H|$ Mu_   fD  MxXLE HH{  1H   L$H֍L$HMu.HIL9t$   IMtJD Hs	 D  1HH0H׈CHHHHHH9u     HMu.HXHIx#HK	HHPB0H9ufD  HP  0t.   E5DL;%fD  H P uCDdCA] D  L+|$^fD  0.  H{f~   LHHHL)HL3HP	@ H@0H9uH9uH7I5fD  0   f4 I]AE  fA]A   I@ HI@ ATIHm
  US1H@dH%(   HD$81Hl$IH踋tH<$HcHH|$腋HD$HHp脙H1LHHsHHHD$YHL$8dH3%(   u	H@[]A\[ff.     UH	  S1HHdH%(   HD$81Hl$IHtH<$_HcHdH|$ʊHD$HHp9HpHHT$赬HL$8dH3%(   uHH[]蹊f     ff. 6  SzuHT4  ^ 6  f.5  z$u"H4  H"4  ^5  5  5  f.zlujH3  H3  f.~%   
^f(fWt5  ztOf.z9u7^fWL5  f.     f.ztHY3  ^4  H5-	     耗H5 	     H%5  hH=	  H
5  H2  H0蛋H2  H5H=  HIH;H*H5  nH;H/H5  SH;H4H5  8H;1HH5   H;   HQH5y  H;   HH5k  H;1H.H5Y  ҉H;5wH5I  nH;  H5:  ZH;   H54  FH;   H5.  2H;	   H5-  H;   H5-  
H;   H5,  H;  H5-  H;   H5$  ΉH;   H5  躉H;   H5  覉H;	   H5
  蒉H;   H5  ~H;   H5   jH;   H5  VH;   H5  BH;   H5  .H;HH5  H;   H5  H;HH5  H;   H5  ڈH;HH5  ĈH;1HXH5  H;   HMH5  чH;   HRH5  趇H;   HWH5  蛇H;HH5  耇H;1H4H5x  hH;HH5b  MH;1HH5O  5H;1HH5<  H;1HqH5+  H;   HH5  H;   HH5  φH;1HÈH5  跆H;1HH5  蟆H;   HH5	  脆H;   H5H5  iH;   HH5  NH;   HH5o  3H;   HH5V  H;   HH5B  H;   HH51  H;1HH5   ʅH;1HNH5  貅H;   HH5  藅H;1HH5  H;H0H5  dH;1HH5  LH;HH5  1H;HH5  H;   HH5y  H;   HH5d  H;   HqH5L  ńH;   HFH56  誄H;   H+H5  菄H;   HH5  tH;   HH5  YH;   HH5  >H;   HH5W  #H;   HdH5  H;1HH5  H;1HDH5t  ؃H;   HIH5b  轃H;1HH5Q  襃H;1HH5A  荃H;1HH52  uH;1HIH5  ]H;1HH5  EH;1HH5  -H;HH5  H;[HH5    HH       %s failed to allocate memory 11 1.0.1 %lu E%ld Exponent underflow Exponent overflow +Infinity -Infinity exponent overflow Computation results to 'NaN' (VpDivd) 0/0 not defined(NaN) (VpDivd) Divide by zero #0 01 argument must be positive %lu: #<BigDecimal:%lx,' ',%lu(%lu)> 02 (VpSqrt) SQRT(negative value) #1 F .5 BigDecimal new mode limit double_fig induced_from _load ver BASE EXCEPTION_ALL EXCEPTION_NaN EXCEPTION_INFINITY EXCEPTION_UNDERFLOW EXCEPTION_OVERFLOW EXCEPTION_ZERODIVIDE ROUND_MODE ROUND_UP ROUND_DOWN ROUND_HALF_UP ROUND_HALF_DOWN ROUND_CEILING ROUND_FLOOR ROUND_HALF_EVEN SIGN_NaN SIGN_POSITIVE_ZERO SIGN_NEGATIVE_ZERO SIGN_POSITIVE_FINITE SIGN_NEGATIVE_FINITE SIGN_POSITIVE_INFINITE SIGN_NEGATIVE_INFINITE precs add sub mult div hash to_s to_i to_int split + - +@ -@ / quo % modulo remainder divmod to_f abs sqrt fix round frac floor ceil power ** <=> === eql? < <= >= nonzero? coerce inspect exponent sign nan? infinite? truncate _dump      second argument must be true or false   first argument for BigDecimal#mode invalid      Conversion from String to BigDecimal overflow (last few digits discarded).      Computation results to 'NaN'(Not a Number)      Computation results to 'Infinity'       Computation results to '-Infinity'      load failed: invalid character in the marshaled string  ERROR(VpDivd): space for remainder too small.   %s can't be coerced into BigDecimal     Undefined operation in BigDecimalCmp()  BigDecimal to Float conversion  (VpSqrt) SQRT(NaN or negative value)    ؕhؕxHrXhX(x6~~~~~~~~~~~~~~~~~[  ~~~~~~~~ ~~~~[,fffffffffffffffffCffffffffCffff|||DNNNNNNNNNNNNNNNNN+NNNNNNNN+NNNN+ddd66666666666666666666666666666LLL?4o4oo'            &.>C]r2<    eA      ?      C                               ;  W   q  t  @w  Jw   x   0x4  @xH  Pz\  pzp  z  0{  |   }  }0  ~D  ~X        PX  t  @  0    0L  0      8  L  `x       `P  h  0 	  4	  `	  	  
  в,
  D
  @\
  pt
  
  
  
  
    0<  h  `      8  t  0      `  t            (  T  P  0  @      @,     8  PT  x  P     Ph       P         PL             zR x  $      n   FJw ?:*3$"       D   pq             \   t
          p   t             t            v             vl    RN(      PwH    ADD ^
AAG  H      tw    BBB B(A0A8DP
8A0A(B BBBJ    <  x   H0
A    X  ly          l  hyl            y       d     z   BHB B(A0A8G`M
8A0A(B BBBAf
8A0A(B BBBE        H|       0     }    yAD DAADL  L   D  }m	   FOE B(A0A8L"
8D0A(B BBBG        ,    Aj            A
E^d        BEB B(A0A8Dp
8A0A(B BBBGT
8A0A(B BBBA     8  ,c       8   L      BDH @
FBJS
ABJ   L     ܌    BED D(J0K
(A ABBF_
(D ABBH   `        BBB A(A0
(A BBBBm
(A BBBDY
(A BBBH   4   <  ؎7    BDH V
ABIACB      t         (     x    AX
GW
IW
IW @        FBB D(A0D`$
0A(A BBBA     ,      |     (U   BHB B(D0D8G
8A0A(E BBBA
8C0A(B BBBJS
8A0A(B BBBE         YW     4   BGB B(D0D8K`Z
8A0A(E BBBIt
8A0A(B BBBBD
8C0A(B BBBA
8A0A(B BBBA   0   <  (    FAD F0Q
 AABJ |   p  e   BEE B(D0A8Gpn
8A0A(B BBBF
8A0A(E BBBE
8A0A(E BBBC (     H   AAJM
AAE(     ȧ    EAN`
AAA    H  |?    Hj
FF      h  4    Hk      Ĩ%    HV      ܨ!    HS 0        FFA G`
 AABA      +    Ee         +    H\          H E
C    4      HT (   L      EFDPd
DAE (   x      EFDPk
DAE (     P    EFDPw
DAE (     ī    EFDPi
DAE 8     (    FBA A(Np
(A ABBG 8   8	      FBA A(Np
(A ABBG 8   t	      FBA A(Np
(A ABBG @   	  t<   FBB A(A0Np
0A(A BBBG    	  p\    HO(   
  q    EFD0P
GAE `   8
  e   BBI D(F`
(G ABBJ
(A ABBHX
(G ABBL      
            
            
            
            
                      L      /   FBB B(A0D8O
8D0A(B BBBF   (   d     EFDP'
AAH4     T    EDG@H
GAHh
DAE L         FJA D(D`
(D ABBHT
(G ABBE   `     L   FJD A(D`g
(A ABBJ|
(D ABBKT
(G ABBH   `   |     FJD A(D`g
(A ABBJ|
(D ABBKT
(G ABBH   L     E   FGB B(A0A8Dt
8A0A(B BBBK   4   0  R   EFD`
AAE
FAFd   h     FBB J(A0D8Dm
8D0A(B BBBId
8A0A(B BBBA   $       zR x      ,   |f
       d     H   BJE E(D0A8D
8A0A(B BBBJ
8G0A(B BBBL     t  w    H@i
A           EDP
AA L     pU   FJA D(D
(D ABBIL
(A ABBA         zR x      (   Ve
          <  H4    AZ
AH   X  l   FBB B(A0I8D
8A0A(B BBBED        FBB A(K0D
0A(A BBBA   L     (    FBD G(DPq
(G ABBLe
(D ABBE   L   <      FBD G(DPq
(G ABBLe
(D ABBE   L     H    FBD G(DPq
(G ABBLe
(D ABBE   H     l   FBB J(G0A8D
8A0A(B BBBE0   (      FKA F`
 AABA (   \      EHF`|
AAA         Q                  GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             @             p             4             C             S             ^             i             w                                                    l             `                           h                    o    `             (                   
                                                                                         H             P      	              o          o           o    0      o                                                                                                                                                                                   x                                                0      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                             @@      ?                        GA$3a1       y               GA$3p1067  p      j                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY     P      j               GA+GLIBCXX_ASSERTIONS   bigdecimal.so-1.8.7-16.el8.x86_64.debug n7zXZ  ִF !   t/w] ?Eh=ڊ2N$MF!5S[S)qIHZI_ڪ+M;7K1g
¬,
 voAK8`,1緤=xCVs/$
5=oBw>?<zX[CO!R~d%u:LFQn@E:vR$H]J"}.S[l6IIL\/׮o۟9s(';8	$-3xN1\MʒřB>B l"	'CW PQ!P@4CR،if'
-刲S;b
c_%'dU?3 ;	/.l;mxk-6=QѸ<XhXGR_>%0C:m۲P:NJce?!aθ(;*Ͷӧ q鮕U%VKAӤvCݨsH2/.R- AGGpXW\nWkÉ~,/IDȰ)v
ϡ`.TӈGolJ1d)5/\h(sE잫#1gDD暱g.LΆp⵻FFOJ d˿dٶ(4"kn{^OF2w7$3FKB,֠|oa\*ٸ8K-U(ԞQ*]&.[#cx &+^ԏ:7*mxJIZdųΞS>>[0/R8nHАsƿ9D[~Mc䃅i8e=E?5kIѓűbb!).uE>:b¶p^VnlT|ʭDjFwT`EY,j@ilaCEjj|%ZR	XˏG	gD) KHp.LI	-u]ZnI.69룻^CYi9}u>gEUZ>"~YD0J;mpwGTuTi:kVQH6 w'/UaT֗t Dls	8tzbi,grPN~%AwkeB"!#5Q@ĉЎЗSvN3 (GtG)0KЕbu
21sI;ol*/K5`˻s{͆(YF$ 	kv5払p<~i~;8$QAoYa00#b>?+DjØ&j{G[2N|mz?WeWf^{XU\KUEbQ:Q7z~%CNBfߙc6EjCUDsabEl{31чEmRVR7ӄ%yDDdrF)o .FPb:7G&fYnh{ʫ8OF*tvG`a(21ر61EaL꡻Vi0`E딯DU)dϫ     [c/D 6  [7 g    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                     8      8      $                                 o       `      `      @                             (                                                   0             (      (                                   8   o       0      0      v                            E   o                                               T             H      H      P                           ^      B                                              h                                                       c                                                     n                                                     w             p      p      {                             }             l      l                                                                                                       0      0                                                                                                                                                              `      `                                                h      h                                                p      p                                                 x      x      0                                                    X                                                        x                                         x      x                                                              H                                            `           H                                                        ,                              "                                                                                    1                             PK     Y\Ka  a    x86_64-linux/readline.sonu ȯ        ELF          >     #      @       Z          @ 8 	 @                                 C      C                    L      L      L      P                          L      L      L      `      `                   8      8      8      $       $                    C      C      C                             Std   C      C      C                             Ptd   <      <      <      D      D             Qtd                                                  Rtd   L      L      L      `      `                      GNU ErCANϧq6jj       X         @    X   Z       |CEqX}BW                            m                      W                                                                                                         a                      D                     p                                            w                                                                                                                                                                         }                     T                     .                     Z                                                                                                                                                                           ,                                                                                       S                                          "                     F   "                                        ;                                          N                     o                                          c                                          9                                                                                      
                     :                     w                     L                                                               
                                                                                                                                0                                          D                                          e                     U                                            .                                                                                                                                                                                               s                                          g                     +                                                               t                      D                                                               '    8R                  Q                  Q                  `5             __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_str_new2 rl_instream fileno __fdelt_chk rb_thread_select __stack_chk_fail rb_attr_get rl_attempted_completion_over rb_tainted_str_new2 rb_intern rb_funcall rb_Array ruby_xmalloc rb_obj_as_string strcpy __ctype_b_loc __ctype_tolower_loc strncpy strdup rb_string_value_ptr rl_username_completion_function rl_completion_matches rb_ary_new rb_ary_push free rb_ary_shift rl_filename_completion_function rb_secure history_length rl_filename_quote_characters rl_completer_quote_characters rl_basic_quote_characters rl_completer_word_break_characters rl_basic_word_break_characters remove_history rb_int2inum history_base rb_yield history_get rl_completion_append_character rb_string_value rb_check_safe_obj add_history ruby_xrealloc rl_emacs_editing_mode rl_vi_editing_mode rb_ivar_set rb_scan_args isatty __errno_location rb_stdout rb_check_type rb_io_taint_check rb_io_check_closed rb_stdin rl_outstream rb_protect rl_cleanup_after_signal rb_jump_tag rb_eIOError rb_raise rb_eIndexError rb_fix2int rb_num2int replace_history_entry rb_str_new rb_respond_to rb_eArgError Init_readline rl_readline_name using_history rb_define_module rb_define_module_function rb_define_singleton_method rb_cObject rb_obj_alloc rb_mEnumerable rb_extend_object rb_define_const rl_library_version rl_attempted_completion_function rl_event_hook rl_clear_signals libruby.so.1.8 libreadline.so.7 libncurses.so.6 libtinfo.so.6 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 GLIBC_2.15 GLIBC_2.4 GLIBC_2.3 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                                                             ui	   ,        
            8     ii   C     ii   M     ui	   ,      L             #      L             p#      L             L      O                     O                    (O                    0O                    8O         
           @O                    HO                    PO                    XO                    `O                    hO                    pO         #           xO         %           O         &           O         '           O         )           O         *           O         /           O         1           O         2           O         3           O         6           O         A           O         H           O         I           O         N           O         O           O         P           O         S           P                     P                    (P                    0P                    8P         	           @P                    HP                    PP                    XP                    `P                    hP                    pP                    xP                    P                    P                    P                    P                    P                    P                    P                    P                     P         !           P         "           P         $           P         %           P         (           P         +           P         ,           P         -            Q         .           Q         0           Q         4           Q         5            Q         7           (Q         8           0Q         9           8Q         :           @Q         ;           HQ         <           PQ         =           XQ         >           `Q         ?           hQ         @           pQ         B           xQ         C           Q         D           Q         E           Q         F           Q         G           Q         J           Q         K           Q         L           Q         M           Q         Q           Q         R           Q         T           Q         U           Q         V           Q         W           HH3  HtH     5r4  %s4   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   h2   h3   h4   h5   h6   h7   qh8   ah9   Qh:   A%0  D  %0  D  %0  D  %0  D  %0  D  %0  D  %0  D  %0  D  %}0  D  %u0  D  %m0  D  %e0  D  %]0  D  %U0  D  %M0  D  %E0  D  %=0  D  %50  D  %-0  D  %%0  D  %0  D  %0  D  %0  D  %0  D  %/  D  %/  D  %/  D  %/  D  %/  D  %/  D  %/  D  %/  D  %/  D  %/  D  %/  D  %/  D  %/  D  %/  D  %/  D  %/  D  %}/  D  %u/  D  %m/  D  %e/  D  %]/  D  %U/  D  %M/  D  %E/  D  %=/  D  %5/  D  %-/  D  %%/  D  %/  D  %/  D  %/  D  %/  D  %.  D  %.  D  %.  D  H=.  H.  H9tHF,  Ht	        H=.  H5.  H)HHH?HHtH,  HtfD      =u.   u+UH=+   HtH=)  9dM.  ]     w    H=e  @AT   USH   dH%(   H$   1ILHH-(+  H} ?H} 4HcH} ?)Ѻ   HH	E111Lx%H$   dH34%(   uHĐ   1[]A\ff.     @ AWAVAUATUHSH8H5|-  H=}-  hH  H5W-  HH=]-  H*      ;HHD$H=?  HH   HH1Htu<tIŃ?	tH%IMuE  E~McILHD$E~UAF1H,   f.     IE H<IH@HxHT$HHDIt$HH9uHD$JD8    A       HD$HT$D$ HLjHD$ AFHDHD$(fD  MeH|$  A$   E1H(?fD  IE J8DMHHL$tsHL$H It09u,C<HEDMHL$t?HL$H uD$D9DNIDt$L9l$(YIc}HccH\$HHHHsH( HD$H8[]A\A]A^A_ÐDEtMM AA9uct_   "    EHEfD9]AAƅuL@ HD$    H\$H{HrE1ff.     @ ATU   SHH|$Ht$ H59(  HHtPII<$HHt-LD  HHHH{cH;HuLSH}HH[]A\HxHH[]A\ff.     ATU   SHH|$Ht$PH5A'  HHtPII<$HHt-LD  HHHH{H;HuLH}HH[]A\HHH[]A\ff.     H   .H&   HHD     HH%  H8HtHFfD     HfD     HH_&  H8HtHfD     HfD     H~H%  H8HtHfD     HfD     H>H_%  H8HtHfD     HfD     HH%  H8HtHFfD     HfD  H   H5'  H='  H    H   H5'  H='  Hg    U   S   HYHtH8HH;HgH_HH[]D     HH#  8~1HfD     HfD  H   H#  Hc8Hff.     AUI   ATUSHH-#  E ~71L%f#  @ H8H9] ~A<$HuHL[]A\A]fSH   HHt$%H|$uH.#       HH[    H|$H|$HD$Hx tH@H"  HH[    AUIATU   SHHdH%(   HD$1t;EHLdHHCHH$,H<$CH$HxL9uHL$dH3%(   LuH[]A\A]~ff.      SH   HHt$H|$H|$HD$Hx3HH[f.     SH   HHt$H|$kH|$H=$  HD$HtPHpHHd$  HHD$HHPHp$HHD$H@ H=!  HHH[ÐHxH3HH$      SH   HHt$H|$H|$H=#  HD$HtPHpHSH#  HHD$HHPHptHHD$H@ HE!  HHH[ÐHxHHHY#      SH   HHt$UH|$H|$!H=#  HD$HtPHpHH"  HHD$HHPHpHHD$H@ Hu   HHH[ÐHxHHH"      SH   HHt$H|$[H|$qH=Z"  HD$HtPHpHH<"  HHD$HHPHpHHD$H@ He  HHH[ÐHxH#HH!      SH   HHt$H|$H|$H=!  HD$HtPHpHCH!  HHD$HHPHpdHHD$H@ H  HHH[ÐHxHsHH1!      H   N1   B   H     H   1      H     S   HH5   H=   H[    ATIU   SH dH%(   HD$1H\$LD$HH  L11S~H7H|$MHD$Hh1ud8	  H     H;WH;oHXHHCH   H  HH     H;HH;0HXHHH  HH=`  HHT$cHËD$ue   HD$u8HtHHHHL$dH3%(   Hu%H []A\@ HtH뾐HB|$H  H5G  H81ff.     fPXH54  HH  H81fS   HH߃t&H   x&9~&1[VfD  H   yy1H   H   ~11H@    HfD  S   HNH߃t6y	H.  H  HtH8[vfD  @ S   HHHT$H߃tMH|$H|$y	H  HD$1҉HpHtHD$H[ {bfS   qH  t$   H=g  3HP
[f        [f     S   HH=  HHtH5  H=  H[H  H5  H81@ USH  HHP  HH=  H=  H  H=  Hs  HH5  HHa  H=U     HH5  ]H=6  1HH5V  AH=     HH5  "H=  1H"H5+  H=  1HH5]  H=  1HZH5Q  H=     H[H5E  H=  1HH5F  H=l     HPH5C  tH=M  1H4H5D  XH=1     HeH5v  9H=  1HH5  H=     HzH5  H=  1H>H5  H=     HH5  H=  1HH5  H=     HH5  H=a  1HHH5  lH-  H} HHR  HH0g1HHH5  /H߹   HH5  H߹   HH5  H߹   HH5  H߹HH5u  1HHwH5b  1HHH5N  1HHH5<  {1HHoH5)  c1HHWH5  K1HHH5  3   HHH5  H=  HH5   RH} i   HH5   HHH=  HH5  H} ,   HH5   HHH=w  HH5  HH  H82H=K  H5t  HH  HH  HHH[]  HH       HISTORY call 02 stdin closed invalid index Ruby completion_proc completion_case_fold Readline readline completion_proc= completion_case_fold= vi_editing_mode emacs_editing_mode completion_append_character= completion_append_character basic_word_break_characters= basic_word_break_characters basic_quote_characters= basic_quote_characters completer_quote_characters= completer_quote_characters filename_quote_characters= filename_quote_characters to_s [] []= << push pop shift each length size empty? delete_at FILENAME_COMPLETION_PROC USERNAME_COMPLETION_PROC VERSION argument must respond to `call' completer_word_break_characters=        completer_word_break_characters ;D  '   `           4  pt     P      ,  PL  l      @       4  \  @    @     $  PH   l  0  `    @  `  $   D  `d    0               zR x  $      X   FJw ?:*3$"       D                \   H       0   p   D    FFA G
 CABAH         FBB B(A0D8DpO
8A0A(B BBBB<          FAF D0w
 DABAL DAB <   0      FAF D0w
 DABAL DAB    p  d+    H\      |:    MX
KI        :    MX
KI        :    MX
KI        :    MX
KI        :    MX
KI      (  )    H\    @  4)    H\ $   X  LK    AFK sDA      t:    M[
HI        %    HX 4     n    FJA A(D0N(D ABB$     y    EL c
DHtD8     <    FEA H(G@k
(A ABBA    T  F    EL pD     t      EL y
DB       \    EL y
DB           EL y
DB       t    EL y
DB            EL y
DB    (  (    H_    @  (    H_    X  )    E_   0   t     FDH D@A
 AABE     L    AAK       P_    Ep
K     :    H_
II         \    E@
K          ~    EL Z
AD    D  PG    Eq
JF    d  \    Ez
E(        EAK AA                    GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     #      p#      L                                                                                                                                   
             W             p             :             L                           L                    o    `             8                   
                                   P                                                                         	              o    x      o           o          o                                                                                                                                                                                                                                                                                                                                   L                                                                              0      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @               GA$3a1 p      ):               GA$3p1067  #      :                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY     #      #               GA+GLIBCXX_ASSERTIONS   readline.so-1.8.7-16.el8.x86_64.debug   `l$Z7zXZ  ִF !   t/] ?Eh=ڊ2NthO̗W/QgZWz=~?Pl@uی~4e$1uh=&iԶ{"}'Hv-RMlCZ^g}Z}6(tqavsq]@l/h>C٥Q6ǫk< ʑ#aB3B*MWyYPOsNkDѮ+w)md+&ì"[
=9faHrq-]!.ߪs˪gcVm$prPW&HUZ'i{1V=C]hAztm@䊪TQHVs̘pj]\aw2C	enKCjL,(1cَWHCG5+m7<<c-_1+\V}1MI
寕EjUMSua	[fK}cV%MWXXR]Քz'G)"rd?y)$ʑHwm/Dؓ+SEz탂*f	U@3:"lz#c$`ԅ+Q|lH9i͎D|4~UR/Ipw	Kk5<2'
-7MX%vg&7|9{+h *Z(Tz\7.*	@+mdd
vKf|cێ]7!L5i}_ޤ^ JJ֋3}^|yM+e_%'*IiDWx?.B~/N*_P¾j.qʂ#IŉK qR?QfՁ1{:y;NSF5\.˛/qoV7SKbvcG>D
GQEze&\A
 "v ĹVrnrZŁ/e#!h6~$P.)8)zPRE>#zKo{F
Uڣf7 :*G'8iQ3)BuX}u^]\gJ
z>/=޴dr[:f@:LT`uQnvXT6s;"IHsqk+F>&?K:fx<R&:XqrX}04T    FXjC 	+  `暯g    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                               8      8      $                                 o       `      `      4                             (                                                   0             8      8                                   8   o                                               E   o       x      x      p                            T                                                     ^      B                                             h             p      p                                    c                                                     n             P      P                                  w              #       #                                   }             :      :                                          2       0:      0:                                               <      <      D                                          >      >                                                C      C                                                  L      L                                                L      L                                                L      L                                                 L      L      `                                        O      O                                                 P       P                                               Q      Q      H                                            8R`     Q      H                                                  8T      ,                                                   dT                                                         lY      +                             PK     Y\VEB{  {    x86_64-linux/digest.hnu [        /************************************************

  digest.h - header file for ruby digest modules

  $Author: shyouhei $
  created at: Fri May 25 08:54:56 JST 2001


  Copyright (C) 2001-2006 Akinori MUSHA

  $RoughId: digest.h,v 1.3 2001/07/13 15:38:27 knu Exp $
  $Id: digest.h 11708 2007-02-12 23:01:19Z shyouhei $

************************************************/

#include "ruby.h"

#define RUBY_DIGEST_API_VERSION	2

typedef void (*rb_digest_hash_init_func_t)(void *);
typedef void (*rb_digest_hash_update_func_t)(void *, unsigned char *, size_t);
typedef void (*rb_digest_hash_finish_func_t)(void *, unsigned char *);

typedef struct {
    int api_version;
    size_t digest_len;
    size_t block_len;
    size_t ctx_size;
    rb_digest_hash_init_func_t init_func;
    rb_digest_hash_update_func_t update_func;
    rb_digest_hash_finish_func_t finish_func;
} rb_digest_metadata_t;
PK     Y\uR        x86_64-linux/fcntl.sonu ȯ        ELF          >          @                 @ 8 	 @                                                                                                                         0      0                   8      8      8      $       $                                                             Std                                            Ptd                        $       $              Qtd                                                  Rtd                     h      h                      GNU .!Y2E{ bz                      
       BE|qXϫ                            q                                                                    `                      ,                       F   "                   }                           8                   @                   8              U                  __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize Init_fcntl rb_define_module rb_int2inum rb_define_const libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                             ui	                                          P                                                                                                                                                  (                    0                    HH	  HtH     5	  %	   h    h   h   h   %m	  D  %e	  D  %]	  D  %U	  D  H=Q	  HJ	  H9tH  Ht	        H=!	  H5	  H)HHH?HHtH  HtfD      =   u+UH=   HtH=6  Id  ]     w    SH=  1HH5y  HH   H5e  HH   H5Q  HH   H5=  HH   uH5)  HH   YH5  HHw   =H5  HH[   !H5  HH?   H5  HH#1H5  HH
   H5  HH   H5  HH@   H5  HH   |H5|  HH   `H5g  HH~   DH5T  HHb   (H5@  HHF   H5-  HH*   H5  HH1H5  HH   H5   HH   HH5   HH[   H5   HHFcntl F_DUPFD F_GETFD F_GETLK F_SETFD F_GETFL F_SETFL F_SETLK F_SETLKW FD_CLOEXEC F_RDLCK F_UNLCK F_WRLCK O_CREAT O_EXCL O_NOCTTY O_TRUNC O_APPEND O_NONBLOCK O_NDELAY O_RDONLY O_RDWR O_WRONLY O_ACCMODE  ;$      P@   h                 zR x  $      P    FJw ?:*3$"       D   0@              \      Er              GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           P                                                                                                                                  0             (
                                                            o    `                                
       5                                         `                                         (                    	              o          o           o          o                                                                                                                                                 `      p                           GA$3a1 0      5
               GA$3p1067        (
                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign    fcntl.so-1.8.7-16.el8.x86_64.debug  n'7zXZ  ִF !   t/] ?Eh=ڊ2NpI  Q{H;rw/ɡ";Ƣ6cv 'xp5''Cn`V['HفH¨IDb\6 ]G}$FWʿPB[K3(T!(r ,1[cCWpsSQFEI<O~FZt_̞g6b(X,;K'{\toGnCt"gp	ЙW rJH]C%m),XVУH;%;<v-ǳ!RbLhŨҜ3)ĉhh"P	uPQ	- ݅xW3|ERv91ai	(Y2dGGgn~X,r4.5Zu>8n!It}[ \JlҔoaL&J&MNJ*pid*U}g(6Wy{aNajnK/uсhe,=*348Hu. R=<1^rRl)y
Gh
YZS.9K!6nv9CaHh/ $:PfO<6#S8fź !K h#k:h9yæR6\rK_R'+<Y׭~	

=R  	-L   \g    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                               8      8      $                                 o       `      `      4                             (                                                    0                         5                             8   o                                               E   o                                                T             (      (                                  ^      B                   `                           h             0      0                                    c             P      P      P                             n                         @                             w                         H                             }             (
      (
                                          2       5
      5
                                                              $                                           (      (      x                                                                                                                                                                                                                                                                                  0                                                                                                             8                                          8      8                                                  @`     8                                                        0      (                                                   X      <                                                         +                             PK     Y\ve    x86_64-linux/dl.sonu ȯ        ELF          >    ?      @                @ 8 	 @                                 (\     (\                   Xk     Xk!     Xk!                               pk     pk!     pk!     0      0                   8      8      8      $       $                    \     \     \                            Std   \     \     \                            Ptd   <     <     <     $      $             Qtd                                                  Rtd   Xk     Xk!     Xk!                                 GNU pTį^zm    C   e      	   H "1DB( J    I4 J  PeoI 1 e   g       h   j   l   o       q   r   s   t       u   v   x           y       z   |       }                                                                                                                                                   rJD-ADw
AnxؐhY=vTF#I\^ËV>.:[=Jrau4S$-6B-30vl~]'[|#OZw[>[fWXu#`MVXls\A]=_^E0*l/xEN_ͻVD`$ן^	gk#TM,%R=#QbGBEr&ׂV>s?uz鹩]uh|rvhJџqqX v7S                                                                                           F                     y                                                               )	                     <                                          =                                                                                                           &                     %                     l                                          /                     Y                                          L	                     :	                                                                                    k                                                               a                     H                                                               \                      6                     A                                                                                                         w                                                                                     2                     k                     _                     x                                            D                                          v                                                               K                     t                      }                                                                 	                                          R                                          U                     :                                                               9                                                                                      K                     a	                                                                                                         
                                          0                     $                                                               T                                          y                     ,                                                                 L                     F   "                                                             (                     .                     d                                                                                                                ;       	         )                 5           	                     D           Hv!            k          1      
         ]                        
	                 k    Pv!                      /       >    `      k       	    A      M                1                                 q          Xv!                      4      l    @                 &           ^         V          	     R                5                           0           U     @      	           P	     )                 j      F          i                 -                       n    P     ?       8    0'     k       K         0                 	           p      3            A      2       _    @                	     ;           P     D       v	    @           V    p                                 0      ]       \          2           @                 8v!            y         ]                1       o    0      	       	    hv!                 `v!                 P                  P      B       %          e                 -       0                 	    Hs!             ]    P      $       g     @      D           @v!                 PA      M                             @      t           `     (       
    pv!                      a          P      ,       !    0           (    p                     3        
    Hs!                 '                     0        __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize dlfree ruby_xfree rb_io_to_ptr rb_io_taint_check rb_io_check_closed rb_dlptr_new rb_dl_dlopen rb_secure rb_cDLHandle rb_class_new_instance rb_dl_malloc rb_dlptr_malloc rb_num2long rb_dl_strdup rb_string_value rb_check_safe_obj rb_dlsym2csym rb_int2inum rb_assoc_new rb_hash_aset rb_scan_args rb_block_given_p rb_hash_aref rb_eDLError rb_raise rb_block_proc __sprintf_chk rb_dlsym_new rb_eDLTypeError __stack_chk_fail rb_tainted_str_new2 rb_float_new rb_check_type rb_ary_entry rb_funcall2 rb_dlptr2cptr rb_eArgError rb_num2int rb_fix2int dlmalloc ruby_xmalloc rb_str_to_ptr memcpy dlrealloc ruby_xrealloc dlstrdup strlen strcpy rb_cDLPtrData rb_obj_is_kind_of rb_check_string_type rb_check_safe_str rb_intern rb_funcall dlsizeof __ctype_b_loc strncpy strtol rb_string_value_ptr rb_ary2cary rb_check_array_type rb_ary_to_ptr Init_dl rb_define_module rb_eStandardError rb_mDL rb_define_class_under rb_hash_new rb_define_const rb_define_module_function Init_dlptr Init_dlsym Init_dlhandle rb_cString rb_define_method rb_cArray rb_cIO rb_dlptr_null_p dlptr_free rb_data_object_alloc rb_dlptr_to_i rb_dlptr_free_set rb_dlptr_free_get rb_dlptr_to_s rb_tainted_str_new rb_bug rb_dlptr_to_str rb_dlptr_define_data_type rb_to_id rb_dlptr_define_struct rb_dlptr_define_union rb_dlptr_get_data_type rb_dlmem_each st_foreach rb_yield rb_Integer rb_dlptr_size st_delete rb_dlptr_inspect rb_class2name __snprintf_chk rb_str_new2 rb_cFixnum rb_cFalseClass rb_cNilClass rb_cTrueClass rb_cSymbol rb_ary_new3 rb_dlptr_aset memset rb_id2name rb_eNameError dlptr_init st_insert rb_dlptr_new2 st_lookup rb_dlptr_ptr rb_dlptr_ref rb_dlptr_to_array rb_ary_new rb_ary_push rb_eTypeError rb_dlptr_eql rb_dlptr_cmp rb_dlptr_plus rb_dlptr_aref rb_dlptr_minus rb_cObject rb_define_alloc_func rb_define_singleton_method rb_define_module_under rb_mDLMemorySpace st_init_numtable dlhandle_free dlclose rb_dlhandle_enable_close rb_dlhandle_disable_close rb_dlhandle_close rb_dlhandle_to_i rb_dlhandle_s_allocate rb_dlhandle_initialize dlerror rb_eRuntimeError rb_ensure rb_dlhandle_to_ptr rb_dlhandle_sym dlsym_free rb_dlsym_s_allocate rb_dlsym_to_ptr rb_dlsym_initialize rb_s_dlsym_char2type rb_dlsym_name rb_dlsym_proto rb_dlsym_cproto rb_str_cat2 rb_str_cat rb_dlsym_inspect rb_dlsym_to_i __errno_location rb_thread_current rb_thread_local_aset rb_thread_local_aref rb_dlsym_call rb_secure_update rb_cDLSymbol libruby.so.1.8 libdl.so.2 libpthread.so.0 librt.so.1 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 GLIBC_2.3 GLIBC_2.14 GLIBC_2.4 GLIBC_2.3.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                                                                                                                                      	         ui	   
        	         ui	   
        	         ii   
        '
     ii   2
     ui	   
     ti	   <
      Xk!            @      `k!            `@      hk!            hk!     m!        e           m!                   m!        h           m!                   m!        s           m!        v           m!                   m!        o           m!        i           m!        f           m!                   m!                    n!                   n!        |           n!                   n!                    n!                   (n!                   0n!                   8n!        p           @n!                   Hn!        w           Pn!                   Xn!                    `n!                   hn!                   pn!                   xn!                   n!        j           n!        q           n!                   n!        m           n!        y           n!                   n!        2           n!        }           n!        5           n!                   n!                   n!                   n!                   n!                   n!        n           n!                    o!        >           o!                   o!        A           o!                    o!        x           (o!                   0o!                   8o!        D           @o!        g           Ho!                   Po!        I           Xo!        L           `o!        u           ho!                   po!        ~           xo!        M           o!        t           o!                   o!                   o!        Q           o!                   o!                   o!        k           o!                   o!        X           o!                   o!        [           o!                   o!        \           o!        {           o!                   o!        d           p!                    p!                   (p!                   0p!                   8p!                   @p!        v           Hp!                   Pp!                   Xp!                   `p!        	           hp!        
           pp!                   xp!                   p!                   p!        l           p!                   p!                   p!        r           p!                   p!                   p!                   p!                   p!                   p!                   p!                   p!                   p!                   p!                   p!                    q!                   q!        !           q!        "           q!                    q!        #           (q!        $           0q!        %           8q!        &           @q!        '           Hq!        (           Pq!        )           Xq!        *           `q!        +           hq!        ,           pq!                   xq!        -           q!        .           q!        /           q!        0           q!        1           q!        3           q!        4           q!        5           q!        6           q!        7           q!        8           q!                   q!        9           q!        :           q!        n           q!        ;           q!        <            r!        =           r!                   r!        ?           r!        @            r!                   (r!                   0r!        B           8r!        C           @r!        E           Hr!        F           Pr!                   Xr!        G           `r!        H           hr!        J           pr!                   xr!        K           r!        ~           r!        N           r!        O           r!        P           r!                   r!        z           r!        R           r!        S           r!        T           r!        U           r!        V           r!        W           r!                   r!        Y           r!        Z           r!                    s!                   s!        \           s!        ]           s!        ^            s!        _           (s!        `           0s!        a           8s!        b           @s!        c           HH;! HtH             5<! %<!  h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   h2   h3   h4   h5   h6   h7   qh8   ah9   Qh:   Ah;   1h<   !h=   h>   h?   h@   hA   hB   hC   hD   hE   hF   hG   qhH   ahI   QhJ   AhK   1hL   !hM   hN   hO   hP   hQ   hR   hS   hT   hU   hV   hW   qhX   ahY   QhZ   Ah[   1h\   !h]   h^   h_   h`   ha   hb   hc   hd   he   %}6! D  %u6! D  %m6! D  %e6! D  %]6! D  %U6! D  %M6! D  %E6! D  %=6! D  %56! D  %-6! D  %%6! D  %6! D  %6! D  %6! D  %6! D  %5! D  %5! D  %5! D  %5! D  %5! D  %5! D  %5! D  %5! D  %5! D  %5! D  %5! D  %5! D  %5! D  %5! D  %5! D  %5! D  %}5! D  %u5! D  %m5! D  %e5! D  %]5! D  %U5! D  %M5! D  %E5! D  %=5! D  %55! D  %-5! D  %%5! D  %5! D  %5! D  %5! D  %5! D  %4! D  %4! D  %4! D  %4! D  %4! D  %4! D  %4! D  %4! D  %4! D  %4! D  %4! D  %4! D  %4! D  %4! D  %4! D  %4! D  %}4! D  %u4! D  %m4! D  %e4! D  %]4! D  %U4! D  %M4! D  %E4! D  %=4! D  %54! D  %-4! D  %%4! D  %4! D  %4! D  %4! D  %4! D  %3! D  %3! D  %3! D  %3! D  %3! D  %3! D  %3! D  %3! D  %3! D  %3! D  %3! D  %3! D  %3! D  %3! D  %3! D  %3! D  %}3! D  %u3! D  %m3! D  %e3! D  %]3! D  %U3! D  H=Q3! HJ3! H9tH-! Ht	        H=!3! H53! H)HHH?HHtHu/! HtfD      =2!  u+UH=j/!  HtH=*! d2! ]     w        UHSH>HXHbH;HtH11[] H   []ff.     UHATIS   H-! L[A\H]ff.      U   HSHHt!HHH5-! H[]f     HxH UHSH}HHuH}HEHxHX\H,! HHH[] U   HAVAUE1ATSHHH1! I    1fD  HcL9$t'HH
uIHPIu[   A\A]A^]ÐKLIHPI8LHH=3!    HIu벐UHAWAVAUIATA   SH0H   dH%(   HE11HLL8DHi  Hǅ8   t<HH0H@A<    H(  HcH>    $  Hǅ8   fD  E1E1f1fD  HLc-LI"LHH=2! HH   HH
uHm+! H5  H81@ A   A   f.     A   A   o    A   A   W    A   A   ?    A   A   '    A   A       A   A   H8fD  H8H0HILL@H(H(HH=F1! LHAE   H     L1H0LHPKIDH}.! H<HMdH3%(   u-Hĸ   [A\A]A^A_]H)! H5  H81 UHAWAVAUATSH(HUVHMȄ(  IIA   H8       BE<  HcH>D  I>ID@ HMJDICT= uHED H(D[A\A]A^A_]I>11IpfD  I>I|f.     I>IHca    I>IHHs fAZ]D  IIHEE>fD  I>IH#E12H'! H5  H81 UHAUATSH  dH%(   HE1HEH`	   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE7   H*HHH=.! HH   HHǾ	   1H   HI   LII|$|HIt$HH`HbHLH5_+! :HrHMdH3%(   u&H  [A\A]]H&! H5  H81Ha'! H5  H81pUHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHOH=,! H H   HHǾ	   V1H,   HI   LI,I|$|HIt$HH`HHLH5)! HHMdH3%(   u&H  [A\A]]H>%! H5  H81H%! H5}  H81UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHH=H+! H`H   HHǾ	   1H   HI|   LII|$|HIt$HH`H"HLH5(! H2HMdH3%(   u&H  [A\A]]H#! H5g  H81MxH!$! H5  H810UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEW   HJHHH=)! HH   HHǾ	   1H   HI   LII|$|HIt$HH`HHLH5&! ZHHMdH3%(   u&H  [A\A]]H!! H5  H81H"! H5=  H81UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHoH=(! H H   HHǾ	   v1HL   HI<   LILI|$|HIt$HH`HHLH5$! HHMdH3%(   u&H  [A\A]]H^ ! H5'  H818H ! H5  H81UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   H
HHH=h&! HH   HHǾ	   1H   HI   LII|$|HIt$HH`HBHLH5?#! HRHMdH3%(   u&H  [A\A]]H! H5  H81mHA! H5  H81PUHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEw   HjHH/H=$! HH   HHǾ	   61H   HI   LII|$|HIt$HH`HHLH5!! zHHMdH3%(   u&H  [A\A]]H! H5  H81H! H5]  H81UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHH=(#! H@H   HHǾ	   1Hl   HI\   LIlI|$|HIt$HH`HHLH5! HHMdH3%(   u&H  [A\A]]H~! H5G  H81-XH! H5  H81UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE7   H*HHH=!! HH   HHǾ	   1H   HI   LII|$|HIt$HH`HbHLH5_! :HrHMdH3%(   u&H  [A\A]]H! H5  H81Ha! H5  H81pUHAUATSH  dH%(   HE1HEH`1HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHRH=! HH   HHǾ	   Y1H/   HI   LI/I|$|HIt$HH`HHLH5! HHMdH3%(   u&H  [A\A]]HA! H5
  H81H! H5  H81 UHAUATSH  dH%(   HE1HEH`	   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHH=H! H`H   HHǾ	   1H   HI|   LII|$yHIt$HH`H"HLH5! @HEdH3%(   u&H  [A\A]]H! H5j  H81P{H$! H5  H813 UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEW   HJHHH=! HH   HHǾ	   1H   HI   LII|$yHIt$HH`HHLH5! Z@HEdH3%(   u&H  [A\A]]H! H5  H81H! H5@  H81 UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHoH=! H H   HHǾ	   v1HL   HI<   LILI|$yHIt$HH`HHLH5! @HEdH3%(   u&H  [A\A]]Ha! H5*  H81;H! H5  H81 UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   H
HHH=h! HH   HHǾ	   1H   HI   LII|$yHIt$HH`HBHLH5?! @HEdH3%(   u&H  [A\A]]H! H5  H81pHD! H5   H81S UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEw   HjHH/H=! HH   HHǾ	   61H   HI   LII|$yHIt$HH`HHLH5! z@HEdH3%(   u&H  [A\A]]H!! H5  H81H! H5`  H81 UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHH=(! H@H   HHǾ	   1Hl   HI\   LIlI|$yHIt$HH`HHLH5! @HEdH3%(   u&H  [A\A]]H! H5J  H810[H! H5  H81 UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE7   H*HHH=! HH   HHǾ	   1H   HI   LII|$yHIt$HH`HbHLH5_! :@HEdH3%(   u&H  [A\A]]H! H5  H81Hd! H5   H81s UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHOH=! H H   HHǾ	   V1H,   HI   LI,I|$yHIt$HH`HHLH5! @HEdH3%(   u&H  [A\A]]HA! H5
  H81H! H5  H81 UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHH=H! H`H   HHǾ	   1H   HI|   LII|$yHIt$HH`H"HLH5! @HEdH3%(   u&H  [A\A]]H	! H5j  H81P{H$
! H5  H813 UHAUATSH  dH%(   HE1HEH`1HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEZ   HMHHH=! HH   HHǾ	   1H   HI   LII|$yHIt$HH`HHLH5! ]@HEdH3%(   u&H  [A\A]]H! H5  H81H! H5C  H81fD  UHAUATSH  dH%(   HE1HEH`	   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHoH=! H H   HHǾ	   v1HL   HI<   LILI|$}HIt$HH`HHLH5
! fZ@HEdH3%(   u&H  [A\A]]H]! H5&  H817H! H5  H81ff.     @ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHH=X! HpH   HHǾ	   1H   HI   LII|$}HIt$HH`H2HLH5/	! 
fZ@HEdH3%(   u&H  [A\A]]H! H5v  H81\H0! H5  H81?ff.     @ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEW   HJHHH=
! HH   HHǾ	   1H   HI   LII|$}HIt$HH`HHLH5! ZfZ@HEdH3%(   u&H  [A\A]]H! H5ƾ  H81H! H5<  H81ff.     @ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHH_H=! HH   HHǾ	   f1H<   HI,   LI<I|$}HIt$HH`HHLH5! fZ@HEdH3%(   u&H  [A\A]]HM! H5  H81'H! H5  H81ff.     @ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHH=H! H`H   HHǾ	   1H   HI|   LII|$}HIt$HH`H"HLH5! fZ@HEdH3%(   u&H  [A\A]]H  H5f  H81LwH  ! H5ܹ  H81/ff.     @ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEG   H:HHH=! HH   HHǾ	   1H   HI   LII|$}HIt$HH`HrHLH5o! JfZ@HEdH3%(   u&H  [A\A]]H  H5  H81Hp  H5,  H81ff.     @ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHOH=! H H   HHǾ	   V1H,   HI   LI,I|$}HIt$HH`HHLH5 ! fZ@HEdH3%(   u&H  [A\A]]H=  H5  H81H  H5|  H81ff.     @ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHH=8! HPH   HHǾ	   1H|   HIl   LI|I|$}HIt$HH`HHLH5  fZ@HEdH3%(   u&H  [A\A]]H  H5V  H81<gH  H5̴  H81ff.     @ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE7   H*HHH= ! HH   HHǾ	   1H   HI   LII|$}HIt$HH`HbHLH5_  :fZ@HEdH3%(   u&H  [A\A]]H  H5  H81H`  H5  H81off.     @ UHAUATSH  dH%(   HE1HEH`1HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   H}HHBH=  HH   HHǾ	   I1H   HI   LII|$}HIt$HH`HHLH5  fZ@HEdH3%(   u&H  [A\A]]H0  H5  H81
H  H5o  H81fUHAUATSH  dH%(   HE1HEH`	   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHHH=8  HPH   HHǾ	   1H|   HIl   LI|I|$pHIt$HH`HLHH5  HǨu#NHMdH3%(   uH  [A\A]]ÐtH  H5ٯ  H81,He  H5.  H81@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE7   H*HHH=  HH   HHǾ	   1H̿   HI輿   LII|$pHIt$HH`HbLHH5_  :HǨu#螿HMdH3%(   uH  [A\A]]ÐkĿHm  H5)  H81|H  H5~  H81d@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE臽   HzHH?H=  HH   HHǾ	   F1H   HI   LII|$pHIt$HH`HLHH5  芿HǨu#HMdH3%(   uH  [A\A]]ÐH  H5y  H81̼H  H5έ  H81贼@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE׻   HʻHH菿H=(  H@H   HHǾ	   薾1Hl   HI\   LIlI|$pHIt$HH`HLHH5  ڽHǨu#>HMdH3%(   uH  [A\A]]ÐdH  H5ɪ  H81HU  H5  H81@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE'   HHH߽H=x  H萻H   HHǾ	   1H輺   HI謺   LI輼I|$pHIt$HH`HRLHH5O  *HǨu#莺HMdH3%(   uH  [A\A]]Ð[贺H]  H5  H81lH  H5n  H81T@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEw   HjHH/H=  HH   HHǾ	   61H   HI   LII|$pHIt$HH`HLHH5  zHǨu#޸HMdH3%(   uH  [A\A]]Ð諽H  H5i  H81輷H  H5  H81褷@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEǶ   H躶HHH=  H0H   HHǾ	   膹1H\   HIL   LI\I|$pHIt$HH`HLHH5  ʸHǨu#.HMdH3%(   uH  [A\A]]ÐTH  H5  H81HE  H5  H81@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   H
HHϸH=h  H耶H   HHǾ	   ַ1H謵   HI蜵   LI謷I|$pHIt$HH`HBLHH5?  HǨu#~HMdH3%(   uH  [A\A]]ÐK褵HM  H5	  H81\H  H5^  H81D@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEg   HZHHH=  HдH   HHǾ	   &1H   HI   LII|$pHIt$HH`H蒾LHH5  jHǨu#γHMdH3%(   uH  [A\A]]Ð蛸H  H5Y  H81謲H  H5  H81蔲@ UHAUATSH  dH%(   HE1HEH`1HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE躱   H譱HHrH=  H#H   HHǾ	   y1HO   HI?   LIOI|$sHIt$HH`HLHH5  轳HǨu&!HMdH3%(   uH  [A\A]]@ DH  H5  H81H5  H5  H81@ UHAUATSH  dH%(   HE1HEH`	   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHH迳H=X  HpH   HHǾ	   Ʋ1H蜰   HI茰   LI蜲I|$pHIt$HH`H2LHH5/  
HǨu#nHMdH3%(   uH  [A\A]]Ð;蔰H=  H5  H81LH  H5N  H814@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEW   HJHHH=  HH   HHǾ	   1H   HIܮ   LII|$pHIt$HH`H肹LHH5  ZHǨu#辮HMdH3%(   uH  [A\A]]Ð苳H  H5I  H81蜭H  H5  H81脭@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE觬   H蚬HH_H=  HH   HHǾ	   f1H<   HI,   LI<I|$pHIt$HH`HҷLHH5  誮HǨu#HMdH3%(   uH  [A\A]]Ð۱4H  H5  H81H%  H5  H81ԫ@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHH诮H=H  H`H   HHǾ	   趭1H茫   HI|   LI茭I|$pHIt$HH`H"LHH5  HǨu#^HMdH3%(   uH  [A\A]]Ð+脫H-  H5  H81<Hu  H5>  H81$@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEG   H:HHH=  H谪H   HHǾ	   1Hܩ   HI̩   LIܫI|$pHIt$HH`HrLHH5o  JHǨu#让HMdH3%(   uH  [A\A]]Ð{ԩH}  H59  H81茨H  H5  H81t@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE藧   H芧HHOH=  H H   HHǾ	   V1H,   HI   LI,I|$pHIt$HH`H²LHH5  蚩HǨu#HMdH3%(   uH  [A\A]]Ðˬ$H  H5  H81ܦH  H5ޗ  H81Ħ@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HڥHH蟩H=8  HPH   HHǾ	   覨1H|   HIl   LI|I|$pHIt$HH`HLHH5  HǨu#NHMdH3%(   uH  [A\A]]ÐtH  H5ٔ  H81,He  H5.  H81@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE7   H*HHH=  H蠥H   HHǾ	   1H̤   HI輤   LI̦I|$pHIt$HH`HbLHH5_  :HǨu#螤HMdH3%(   uH  [A\A]]ÐkĤHm  H5)  H81|H  H5~  H81d@ UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE臢   HzHH?H=  HH   HHǾ	   F1H   HI   LII|$pHIt$HH`H貭LHH5  芤HǨu#HMdH3%(   uH  [A\A]]Ð軧H  H5y  H81̡H  H5Β  H81贡@ UHAUATSH  dH%(   HE1HEH`1HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEڠ   H͠HH蒤H=+  HCH   HHǾ	   虣1Ho   HI_   LIoI|$sHIt$HH`HLHH5  ݢHǨu&AHMdH3%(   uH  [A\A]]@ dH  H5ɏ  H81HU  H5  H81@ UHAUATSH  dH%(   HE1HEH`	   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE'   HHHߢH=x  H萠H   HHǾ	   1H輟   HI謟   LI輡I|$|HIt$HH`HRHLH5O  *H肤HMdH3%(   u&H  [A\A]]H  H5  H81}訟HQ  H5  H81`UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE臝   HzHH?H=  HH   HHǾ	   F1H   HI   LII|$|HIt$HH`H貨HLH5  芟HHMdH3%(   u&H  [A\A]]H.  H5  H81ݜH  H5m  H81UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HڛHH蟟H=8  HPH   HHǾ	   覞1H|   HIl   LI|I|$|HIt$HH`HHLH5  HBHMdH3%(   u&H  [A\A]]H  H5W  H81=hH  H5͊  H81 UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEG   H:HHH=  H谛H   HHǾ	   1Hܚ   HI̚   LIܜI|$|HIt$HH`HrHLH5o  JH袟HMdH3%(   u&H  [A\A]]H  H5  H81蝙ȚHq  H5-  H81耙UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE觘   H蚘HH_H=  HH   HHǾ	   f1H<   HI,   LI<I|$|HIt$HH`HңHLH5  誚HHMdH3%(   u&H  [A\A]]HN  H5  H81(H  H5  H81UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE   HHH迚H=X  HpH   HHǾ	   ƙ1H蜗   HI茗   LI蜙I|$|HIt$HH`H2HLH5/  
HbHMdH3%(   u&H  [A\A]]H  H5w  H81]舗H1  H5  H81@UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEg   HZHHH=  HЖH   HHǾ	   &1H   HI   LII|$|HIt$HH`H蒠HLH5  jHHMdH3%(   u&H  [A\A]]H  H5ׅ  H81轔H  H5M  H81蠔UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEǓ   H躓HHH=  H0H   HHǾ	   膖1H\   HIL   LI\I|$|HIt$HH`HHLH5  ʕH"HMdH3%(   u&H  [A\A]]Hn  H57  H81HH  H5  H81 UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE'   HHHߕH=x  H萓H   HHǾ	   1H輒   HI謒   LI輔I|$|HIt$HH`HRHLH5O  *H肗HMdH3%(   u&H  [A\A]]H  H5  H81}訒HQ  H5  H81`UHAUATSH  dH%(   HE1HEH`1HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE芐   H}HHBH=  HH   HHǾ	   I1H   HI   LII|$|HIt$HH`H赛HLH5  荒HHMdH3%(   u&H  [A\A]]H1  H5  H81H  H5p  H81Ï UHAUATSH  dH%(   HE1HEH`	   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE1HݎHH袒H=;  HSH   HHǾ	   詑1H   HIo   LII|$tHIt$HH`HHLH5  HEdH3%(   u&H  [A\A]]H  H5b  H81HsH  H5}  H81+ff.     UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEG1H=HHH=  H賎H   HHǾ	   	1Hߍ   HIύ   LIߏI|$tHIt$HH`HuHLH5r  MHEdH3%(   u&H  [A\A]]H  H5}  H81訌ӍH|  H58|  H81苌ff.     UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE觋1H蝋HHbH=  HH   HHǾ	   i1H?   HI/   LI?I|$tHIt$HH`HՖHLH5  譍HEdH3%(   u&H  [A\A]]HY  H5"|  H813H  H5z  H81ff.     UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE1HHHH=[  HsH   HHǾ	   Ɍ1H蟊   HI菊   LI蟌I|$tHIt$HH`H5HLH52  HEdH3%(   u&H  [A\A]]H  H5z  H81h蓊H<  H5x  H81Kff.     UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEg1H]HH"H=  HӉH   HHǾ	   )1H   HI   LII|$tHIt$HH`H蕓HLH5  mHEdH3%(   u&H  [A\A]]H  H5x  H81ȇH  H5Xw  H81談ff.     UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEǆ1H轆HH肊H=  H3H   HHǾ	   艉1H_   HIO   LI_I|$tHIt$HH`HHLH5  ͈HEdH3%(   u&H  [A\A]]Hy  H5Bw  H81(SH  H5u  H81ff.     UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE'1HHHH={  H蓆H   HHǾ	   1H迅   HI诅   LI过I|$tHIt$HH`HUHLH5R  -HEdH3%(   u&H  [A\A]]Hٹ  H5u  H81舄賅H\  H5t  H81kff.     UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE臃1H}HHBH=ۿ  HH   HHǾ	   I1H   HI   LII|$tHIt$HH`H赎HLH5  荅HEdH3%(   u&H  [A\A]]H9  H5t  H81H  H5xr  H81˂ff.     UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE1H݁HH袅H=;  HSH   HHǾ	   詄1H   HIo   LII|$tHIt$HH`HHLH5  HEdH3%(   u&H  [A\A]]H  H5br  H81HsH  H5p  H81+ff.     UHAUATSH  dH%(   HE1HEH`1HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEJ1H@HHH=  H趁H   HHǾ	   1H   HIҀ   LII|$tHIt$HH`HxHLH5u  PHEdH3%(   u&H  [A\A]]H  H5p  H81րH  H5;o  H81ff.      UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE~   H~HH_H=  HH   HHǾ	   f1H<   HI,   LI<I|$   HIt$HH`HΉHLH5˷  覀uRHu*HHMdH3%(   u=H  [A\A]]D  <tҋ?uHx ~H@ fH訃H
  H5n  H81}H  H5Nm  H81}UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE|   H|HHH=  H0~H   HHǾ	   1H\}   HIL}   LI\I|$   HIt$HH`HHLH5  ~uRHu*H"}HMdH3%(   u=H  [A\A]]D  <tҋ?uHx ~H@ fHȁ!}H*  H5l  H81{H  H5nk  H81{UHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEz   HzHH~H=8  HP|H   HHǾ	   }1H|{   HIl{   LI|}I|$   HIt$HH`HHLH5  |uRHu*HB{HMdH3%(   u=H  [A\A]]D  <tҋ?uHx ~H@ fHA{HJ  H5k  H81yHү  H5i  H81yUHAUATSH  dH%(   HE1HEH`1HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE
y   HxHH|H=[  HszH   HHǾ	   {1Hy   HIy   LI{I|$   HIt$HH`H1HLH5.  	{uUHu-HeyHMdH3%(   u@H  [A\A]]     <tϋ?uHx ~H@ fH~ayHj  H53i  H81xH  H5g  H81xUHAUATSH  dH%(   HE1HEH`	   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHE'w   HwHHzH=x  HxH   HHǾ	   y1Hw   HIw   LIyI|$   HIt$HH`HNHLH5K  &yuRHu*HwHMdH3%(   u=H  [A\A]]D  <tҋ?uHx ~H@ fH(|wH  H5Sg  H819vH  H5e  H81!vUHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEGu   H:uHHxH=  HvH   HHǾ	   x1Hu   HIu   LIwI|$   HIt$HH`HnHLH5k  FwuRHu*HuHMdH3%(   u=H  [A\A]]D  <tҋ?uHx ~H@ fHHzuH  H5se  H81YtH2  H5c  H81AtUHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEgs   HZsHHwH=  HtH   HHǾ	   &v1Hs   HIs   LIuI|$   HIt$HH`H~HLH5  fuuRHu*HsHMdH3%(   u=H  [A\A]]D  <tҋ?uHx ~H@ fHhxsHʧ  H5c  H81yrHR  H5b  H81arUHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEq   HzqHH?uH=ح  HrH   HHǾ	   Ft1Hr   HIr   LItI|$   HIt$HH`H|HLH5  suRHu*HqHMdH3%(   u=H  [A\A]]D  <tҋ?uHx ~H@ fHvqH  H5a  H81pHr  H5.`  H81pUHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEo   HoHH_sH=  HqH   HHǾ	   fr1H<p   HI,p   LI<rI|$   HIt$HH`HzHLH5˨  quRHu*HpHMdH3%(   u=H  [A\A]]D  <tҋ?uHx ~H@ fHtpH
  H5_  H81nH  H5N^  H81nUHAUATSH  dH%(   HE1HEH`   HhHEHEHpHEHE HxHEHE(LEHEHE0LMHEHE8HEHE@HEHEHHEHEPHEm   HmHHqH=  H0oH   HHǾ	   p1H\n   HILn   LI\pI|$   HIt$HH`HxHLH5  ouRHu*H"nHMdH3%(   u=H  [A\A]]D  <tҋ?uHx ~H@ fHr!nH*  H5]  H81lH  H5n\  H81lWo    UHATISH_{HcHc rIt$HH`oH  H H
nHt!LH	uItI$   H	[A\]ff.     'n    UHSHHmHxrqHHWlH[]UHAWE1AVAUATSHHLwIcHH>6qIAFHEEu   H   HtvHtp<tl ?tw"   Hҟ  LH0oH   "   LnIE H KIGL;}tPILHEkIŨxLkIH   LmI}nKIGL;}uHL[A\A]A^A_]fuK    fD  H=wZ  m1LH1lIH  LH0nHt8"   LFmIF H K(DHܞ  H5[  H81[jDfD  UHAWIAVAUATSH8dH%(   HE14kE  oDEE11IH5\  McI9E1   Kt7HDW   C47V0  HcH>Hu    HHGl,E9HMdH3%(   H  He[A\A]A^A_] HuD  HuD  HuHH    HuHHC    HuHHj@ HH\fD  AEHIDG   KD7A   D  ALAT$HBDWuHcMcHHHH H)HHH9tH   H$   H9u%  t	H)HL LT$LDEILMLL]hL]
   1HB jHjZ  DELMKf     E1ۺ   Y1lHu  @H5W  H81giff.     UHHH}HujHlHwgD  UHAWAVIAUAHATSHdH%(   HE1iHf  PHÅ  M   1HgIĨ  H   H  H  <   ?"  HZ  HcH>L-Q  LIu kHu0H=V  <i1LH1-hIu HjH  LHIHMdH3%(   L  He[A\A]A^A_]D  HH9   H   H$   fAFt  Ad  Af  LkIcHI>kIEwEuE1V     Hn  HtNHtH<tD?N  u1fZHCIEM9ILHETftH  DH5V  H81eD  HHL$ Lt$I     AL  (  ACP  `  AH  LkIcHI>jIE~EuE1b    Ht>HVHL<D?
    $1fClIEM9ILHEOetHsjfCl@ C     E1E   LkIcHI>iIEEuE1Y    HtjHH|<t?tBa@CIEM9OILHEdt/    K    fD  ADGH'  H5S  H81cfD  AIuLkIcHI>hIEEuE1^fHt>HH<?
    |C    IEM9mILHEctHhC@ E)LkIcHI>DhIEEuE1c    Ht>HH<?
F  =  K    IEM9ILHEbtHhK@ Ah~AiAl1U AcHLkIcI>ggIEAEuE1WfHt:HH<?
~   tyC, IEM9ILHEbtHAgC,Hԕ  H5SQ  H81Sa H(b Hb HbfD  Ha>bHw  H5P  H81`fD  UHAUIHP  ATSH]HH(dH%(   HE1zat~uHcHUL8ZdIĸ   Mt5H&  HuLbHtLH	uIu>fD  HMdH3%(   u8H([A\A]]fD  HUL1cID  IU    H	<aff.     UH=O  HSHGbH=O  Hi  dH5  H  H5O  HHHAeH  H;H5O  HH%eH  HveH_H5H!  HHH  HH=.H  H@H  HH  HH  H6H  HH  HH  HH5ݘ  H5>Hט  HPH5ј  H5bH˘  HH5Ř  H5H  HH  HJH5  H5|H  HH  H`H5  H5H  HH  HVH5  H5H  HZH  HH=  H=NH5o  H5Hq  HHk  HĸH=m  H=VH  H5P  H5HR  HHL  HűH=N  H=WH58  H5H:  HH4  HͪH=6  H=_H5   H5H"  HH  HգH=  H=gH5  H5	H
  HH  HݜH=  H=H5  H5H  HH  HH=  H=H5ؗ  H5)Hڗ  HHԗ  HH=֗  H=H5  H51H  HÉH  HH=  H=ǄH5  H5YH  HH  H]H=  H=~H5  H5H  HS|H  HzH=  H=WwH5x  H5xHz  HuH=  H=pH5n  H5?rHp  HnH=z  H=jH<  HsH5V  H5kHX  H9hH=b  H;H(  HmH5B  H5IK  HD  HH"  `   ZH;H5)K  H`   ZH;H5K  Hu`   ZH;H5K  HY`   oZH;H5J  H=`   SZH;H5J  H!`   7ZH;H5J  H`   ZH;H5J  H_   YH;H5J  H_   YH;H5J  H_1YH;H5J  H_H=J  \H;H5J  Hz_H;HȎ  H5lJ  ?^H;H`bH5_J  $^H;HEbH5=J  	^H;   HzaH52J  ]H;H,     H5M  ]H;H     H5J  ]H;   HIH5I  ]1]1\1]H=  HI  H5I  ]H;H5I  H|^H  1H  H5{H  H8\H  Hό  H5YH  H8k\H  1H  H5:H  H8H[]F\fD  U"   HSHH[HC H8 H[]Hff.      UHATI   S\@   ZfL1H  H H@@ @0ZH    HC    HC    HC    C     HC(    HC0    HC8    [A\]ÐU"   HSHHFZHC H8H[]4W@ UHATI"   SHZH[ LYZHC   [A\]ff.     U"   HSHHYHC HG  H5J  HxH[][D  UHAUI"   ATAHSHHdH%(   HE1zY1HMLHF  DH[ ^WtJuOH}@u+fWH;Hc[HUdH3%(   u4H[A\A]]Ð+\f     H;xXH=I  1VcW UHAUI"   ATAHSHHdH%(   HE1X1HMLHE  DH[ VtJuSH}@u+VH;HcZHUdH3%(   u8H[A\A]]Ðk[f     Hs8H;ZH=I  1UVff.     @ UHAWAVLuHMAULMMATIHH  SHHdH%(   HE1U"   LWMl$ q  X  H}@:  UELVH}	   WH}LgE~/A\$E1D  H}ILAUHYIGL9uEI}Ee Ee0AE4HtVIcHYI}IEHtVH<    YI}(IEHtVIc}0HYLIE(WHE:  YIAD$E1HE%@ IEHB   ID$L9e  IH}LkTIU(HN4XHsJ    IIEB IHCDBtH    HHDBuIHI)I@HH% H)HHH9tH   H$   H9u  3  LL$LHMILELGSLEHM1
   HB  IMHMUHMID$L9efD  ;    I}8    HEHxWIE8z{XE H}D  H}@tvQXH   I}AE     IE0    HtTIE    I}(HtTIE(    HMdH3%(      uIHe[A\A]A^A_]@ RH H)HL Hˇ  H5E  H81QSH  H5E  H81Qff.     fUDWHHdH%(   HE1IcIH   HH% I)HLH9tH   H$   H9u  uVLD$II    A~DO1HHILHHI9uLDUHUdH3%(   u    H)HL R     UDWHHdH%(   HE1IcIH   HH% I)HLH9tH   H$   H9u  uVLD$II    A~DO1HHILHHI9uLDTHUdH3%(   u    H)HL HQ     U"   HSHHRH[ H{Ht)Hcs THc{4H[H]H|?YSf     Hc{4H   []H|?7S    UH=̋  1H5   HP   ]ff.     UHSHHOHHRHRH   []ff.     UHAVAUHMILMATLEHB  SH dH%(   HE1Ot   tPH=B  1BOfH}'SH};  SHRLeHA6  IE1wD  H}RH}   RHRHE1E1E H}RH}   RH^RLeHA   IH}1QIHt1L"   PMm I} HtIEHtI] Me8MuHUdH3%(      |   H [A\A]A^] RLeHHAzLQIm    QH QLeHHALE1|QI6Nff.     @ UHSHH4=  HMHdH%(   HE1MtEHEt%HHHS HJ8H]dH3%(   u/H[]ÐHPHHE    HC Hx8{LM@ UHSHHdH%(   HE1HHt.   HE{PH=  Hu1MHCHtH;H{HtNH{HtNH{(HtNHEdH3%(   uH[]FMfD  U"   HAWAVAUATSHH  dH%(   HE1NLc M|$Mt$8M,$   H   H   H      H{2OAWH   AVILh@  HAU     1AT KH HdMHUdH3%(   udHe[A\A]A^A_]fD  Hq  H8@ H  H8zHA  H8jH	  H8ZH  H8JLff.     UHATS@Ht@u@t?	tfD     1I!LLHƉ[A\]@NUHAWAVIAUA   ATLeSHH8dH%(   HE1HE   HE   HE   -N1HMMLEH>  LDJuHEHE   HEH}@(  H   N"   HILLc AD$4    AD$01L=>  q@ HudH34%(   HEm  H8[A\A]A^A_]fID$HcHHE:Hu1I<$HUIHLLKHA9\$0~ID$(L9,uIT$H
A<0  IcL>D  ID$HcHHED  @?t	
LJH߾"   nKHC H}H@!  HHEHH}LpL`H  @  JIIM9LLHIN2KM9LJ<#1L)I AD$0MD$DH11H5>  LT>       A< W  HcH>M$HcM4ITAtf.     IӃHAMuIT$(L9,   C0G  IcL>D  I$HcH<HTt HуHHuIT$(L;,  IT$HPI9H'    I$HcH<HTt HуHHuIT$(L;,utI   fD  HuHUHUHcI<$IHILII$HcH<HTt HуHHuIT$(L9,Y  IT$+    I$HcH<HTt HуHHuIT$(L;,   IT$S    I$HcH<HTt HуHHuIT$(L9,D   D  IT$ ID$HcHEGfD  ID$HcHHE, SKI IH LLH:HL   kHy  H5)9  H811E@ H   >F   4?FuHHtrHtaHtOt>H{HLH0EHH58  HH4y  H81DHz  H8Hz  H8Hy  H8Hz  H8Hx  H8fD  U"   HSHHdH%(   HE1GHC H0Ht*H={  HEt>HEdH3%(   uAH[]ÿ   HuHH=C  Hu1 EfD  HtH   EUHAWI   AVIAUIATIS   H(dH%(   HE1GMtAH=  HULYCtUH]HtKHtEMt"   H#FHC LhHMdH3%(   H   H([A\A]A^A_]fD  @   EfL1Hw   H@@ @0HEELEHHM MhI@    I@    A@     Mp8I@(    I@0    	GYCff.     @ Hv  HHHH8C@ U"   HSHH&EHC 11H H8H[]Cff.     fU"   HSHHDH{ H1[1]C UHAWAVAUI"   ATAHSHH8dH%(   HE1DL{ H]1LEHLDH(1  sB"    HDH}D @  bBkCIŅ   CACL5r8  1HE@ A0wJDIcL>D  IHH  HHUTCLHEHUHBD  HCH9]t>Hf     IHu  H<1{BLHpEHCH9]ufD  HUdH3%(   L  H8[A\A]A^A_] IH<H0  BLHEk I1H<D  IH<@LHD<@ IHc<?LHD@ IH<X?LHD IfZDLHD    IH<?LH`D I;DLH@D cE@ HBD AD$<0   H<7  HcH>    LC>fD  I_8HI_8AL   HI_8AI   HI_8AH   H{I_8AF   HhI_8AD   HUA_8AC   F@IH=2  1??fD  UHAWAVAUATSH  @HA։Eu%C@  H6  @HcH> AE15@HEAEL-7  ED    }[  KcD L> H;11H?HD  H}ABE9uHEH[A\A]A^A_] H;H=H    Hc;Hl=H    H;HS=HfD  fHZCBHvfD  fHZCAHVfD  H;H<H;H?H11[A\A]A^A_]>H?H[A\A]A^A_]<Hc?H?fZH[A\A]A^A_]mAH?뻐HE   H,q  UH50  H81<     UHATISH   @HAH1H0>LH[HA\]=ff.      UH+  HSHMLEH(dH%(   HE1<tSuqH}@u4<H}?HHc<HUdH3%(   uKH([] A    H}@tA1 <1H=/  1<<fUHSHHHo  H0?HuHu)H1[]D  H߾"   >HC H H[]Hn  H5q/  H81%;D  UHATIS;LH;H9[A\]HÐUHATIS;LH;H)H[A\]: UHAUIATSHHT;IIE Lh8t$HHLI<1H)[A\A]]<fD  H>H UHAWAVHMLEAUATSHH)  H(dH%(   HE1HE   HE   :  H}@   H   >H}H  @  @t?t	$q  >"   HIc<LC A@4  A@0  MPDX11L2  L-2  @ A4N4  IcL>     @E?t	
2HEHHHEp>Hu   H?<H]dH3%(   m  H([A\A]A^A_]D  M8HcM4ILAt I΃HAMuIH(L9$?  C@q  @IcL L> I8HcH4HLt@ H΃HHuIH(L9$   IHHJL9A  Hf     I8HcH4HLt@ H΃HHuIH(L;$uDI     fI8HcH4HLt@ H΃HHuIH(L;$  IH[f     I8HcH4HLt@ H΃HHuIH(L;$Q  IHHf     I8HcH4HLt@ H΃HHuIH(L;$D      fD  IH@    A@0   Ip(L;&   H   H     HH9   HPL9duH    IHI8IH4vD  1)6HETI8IHHHǋHHi  H5Y+  H81/6    L   Hj  H5)  H816H   룾F   11_uHHtZHtIHtlt[H{l9LH6HH5)  HHj  H815Hj  H8Hk  H8Hi  H86H{k  H8Hwj  H8fUHAUIATSHH5IIE Lh8t$HHLJ4+1H)[A\A]]6fD  H(9H UH5O)  HAUATSHL%j  Hh  I<$H^:Hi  H5HH9H;HVH5(  8H;H[H5d(  O8H;H5h     H5(  48H;1HPh  H51%  8H;1Hh  H5(  8L-5h  H;1H5#  L7H;1LH5x(  7L-vi  H;1H5c(  L7H;1LH5P(  7H;1Hh  H5;(  7H;Hh  H5&(  s7H;HIg  H5!'  X7H;H~h  H5'  =7H;1Hh  H5'  %7H;HKi     H5'  
7L-g  H;   H5'  L6H;L   H5'  6H;Hh     H5'  6H;Hg     H5m'  6H;HEh  H5T'  6H;Hbg  H5J'  i6H;H?h  H57'  N6H;1Hg  H5'  66H;Hf  H5'  6H;Hg  H5&   6L-g  H;H5&  L5H;LH5&  5I<$H5&  6H,f  H5H;   H5&  Hm  a7H;1He  HH5&  [A\A]]6f.     D  HHtOtWuD  HH5     U"   HSHH4HC @   H   []ff.     @ U"   HSHH3HC @    H   []ff.     @ U"   HSHH3HC @    H84H[Hc]e0D  U"   HSHHF3H{ H[]70    U   HSH2fHd  1H HHde  H8T2H    HC    H[]ff.      UHAUATLEIHf  SH]HH(dH%(   HE10  ^  E1H}   H}@   s5L2IH   L"   @2I\$ H;HtStC   L+HC   q4   HMdH3%(         H([A\A]]fD  H2H}I@_/LX2IH_4HQHH|d  H5"  H81. H}t9H1  I@ Hb  H=bc  LLW09f  E1 K2H=(  1./ U"   HSHH0H{ H1[   ]/UHAWIAVLuAUA   ATISH]H(dH%(   HE11DILHA  L1E1.   H}HtL/H},.L0Hþ"   LD0ID$ P   H8H2IHt1LHL2HMdH3%(   uuH([A\A]A^A_]D  2HtHb  HH5&  H81- H.H}-H/I,Hb  H5&  H81,-f.     UH`  H5&  HATSHH]b  H8%2Ha  H5`  HHL1H;Hb`  H5F   10H;1Hma  H5   0H;1Ha  H5  0H;1HU`  H5&  /L%
b  H;H5%  L/H;LH5   /H;1Hha  H5%  /H;1[H`  A\H5%  ]/0C   H&  HcH> H%       H4        H%       H%       HN%       H9%       HH%       H^%       H2%       H
%       H%       H$       H$       H$       1ff.     fUHSHHHHt2*H{HtH[]*fD  H[]ÐUHATI    S,fL1H@_  H H@F,H    HC    HC    C    [A\] U"   HSHH,HC 1Ҿ   H8H[]m+ff.     fUHAWAVHMIHz  AULmATLeMSMH(dH%(   HE1;*H}-H}   -HHH}u<H}uGE1E1Hu^HUdH3%(         H([A\A]A^A_] LE1*H}tL+IHEH   LxHtL"   +Mf I|$Htt(I|$Hte(I$MtL-IM|$Mt?L-LID$)AD$6     ,H,H  ID$    1 E1k)ff.     UHHH}Hu+8_HǸ   Ht*ff.     U"   HSHH*HC HxHtH[])fD  H   []ff.     U"   HSHHF*HC HxHtH[])fD  H   []ff.     U"   HAWAVAUATSHH)Lk IEH   8HXaHI(LIH,C|>*I   IuH   LL-+!  &   H5%!  L9(f     ;@t1HLHt&; tL   L';@uϺ   H5   L'HL[A\A]A^A_]ÐH5      H'IuHSH5z   G H=x   D(IuIHt L%H5_   L%    H53   ff.     @ U"   HAVAUATSHt(HLk %HXIƍ{dHc+AvscMAu IHcHL'  H   1%XLZ'LH'HeH[A\A]A^]U"   HSHH'H{ H[]$    UHHATSHt:*A$D L%#a  %HLH%[   A\]fD  %AfD  UHIHSHHdH4%(   Hu1HH9tH   H$   H9uHHL$ HT$0HHU@C^  H   @HcH>f     HHHHPHpppphp`pXpPpHp@p8p0LH(L@ H8AHPH   H]dH3%(     H]fHHHHPHpppphp`pXpPpHp@p8p0LH(L@ H8AHP   f.     HHHHPHpppphp`pXpPpHp@p8p0LH(L@ H8AHPf   KfD  HHHPHHpppphp`pXpPpHp@p8p0LH(L@ H8AHP   D  HHHPHHpppphp`pXpPpHp@p8p0LH(L@ H8AHP   D  HHHHPHpppphp`pXpPpHp@p8p0LH(L@ H8AHP   \    HHHPHHpppphp`pXpPpHp@p8p0LH(L@ H8AHP   f     1#@ UHSHH^  "HHH[]%fD  UHAWAVAUIATAHSHH  dH%(   HE1$"   H+$L{ AGPD9  HcH<    #IAGxHcH#HAGxHcH#AOM_HÃ   HHcLL5S  HMIfD  B    EIUCD+A<2  IcL> Bp   K<H  HT  DH0$DH  KHH H"   #HH@ H KHLX    IE;MLA;G<C  H'  HcH>fD  Ba   K4H  11#KHLXK<@"  HK<vfD  K<@  M%CHLXIf     K<@  HHJ<JKBl       K<@J  $fCHLXK<   !KfZHHCLX    K<   z!K@HBJKHBd   LXd@ K<@  H5  @HLZHBJKBc   D  KHB  HHHHH@KHLX@ K<@"  #HfBJKHBh   LXK<   R KHfZPJBKHBf   LX8     K<@  #HBJKHBi   LXfKHHH}HHxHI"KHHHVHvHHBs   LXfK<   RK@HCLXS K<@  H  0HLZC@ AGIH    IS2E1MLH=L  F<2w(HcH>@ AHI9t2F<2vDAE  Axr  H 1L  H@ AD3LFA<2w7IcL>f.     Af.     IHHGM_AGLƃD9A;H  DHc8L5eW  HHLHIG 0<CP  H  HcH>K     fD  yfD  fD  {fD  [ HLZ6 C HLY @?H HG @?H HG IHHGM_f.     AM_qIcHHGM_[ IHHGM_BfHHLX9     HHLX     H=	  DK<1H1HM  HHH1TDHH}M  DH5c  H81f     HHǅ   H  D  E1AH~jLMIǐBD  HI  H5z  HcH>@ K<11HH@ AEID9LHHHHH]dH3%(     H  [A\A]A^A_]@ K<HHK<'rfKH8HHTO    KfZ 'HH(# K HH    KHH0H  HfKH8HHKHc8HHHǅ   HH%  HHCHfZ&HH=HHc%HHHqH11HUHHǅ   H:5H)HJ  H1H     IEB|0AtK4HTO    K<LHL7H+H#IGHH5  HI  H81LL牅HHH5  HJ  H81(HH5LH|HtIGH5a  HI  H81LMHAH9IGH5'  HH  H81jHCJ  H5  H81R}LHHH
J  H5  H81LHHHfH  DH5n  H81UHAWAVAUIATI   SHHH   Hބ   ʉH   HuA   Mte    fHjH  1 IH@HG  H8dM&IMtLqIMnHbHIF&AFHL[A\A]A^A_]HL11[A\A]A^A_]HOG  H5  H81ff.     UHSHHHqF  H0HuHu)H1[]D  H߾"   ;HC H H[]HF  H5Q  H81UD  UH5N  HAUATSHL%G  H*F  I<$HHE  H5F  HHH;HF     H5   H;HG  H5  L-F  H;H5  LH;LH5Z  jH;1HF  H5  RH;1HfF  H5  :L-;E  H;1H5w  LH;1H+E  H5  H;L1H5  H;1HE  H5   HTF  H;1H5a  H=  GI<$1HH5  HM  I<$H   [HH5  A\A]] HH   11 unsupported type `%c' rb_dl_callback_func_%d_%d too many arguments to_ptr unexpected type '%c' an array is expected. type mismatch unsupported type 01 call DL DLError DLTypeError FuncTable RTLD_GLOBAL RTLD_LAZY RTLD_NOW ALIGN_INT ALIGN_LONG ALIGN_FLOAT ALIGN_SHORT ALIGN_DOUBLE ALIGN_VOIDP MAX_ARG dl DLSTACK dlopen define_callback remove_callback strdup sizeof 0P free FREE       too many callbacks are defined. callback function does not exist in DL::FuncTable       unexpected type of the element #%d  |x`H0xhXX}}PP(free) rb_dlptr_to_s rb_dlptr_to_str 11* wrong arguments too few/many arguments 12 rb_dlptr_initialize 21 unsupported type '%c' undefined key `%s' for %s rb_dlptr_to_array rb_dlptr_s_malloc DL::PtrData was expected PtrData free= to_i +@ ref -@ null? to_a inspect <=> == eql? + - define_data_type struct! union! [] []= size size= MemorySpace MemoryTable each       #<%s:0x%lx ptr=0x%lx size=%ld free=0x%lx>       the key must be a string or symbol  LLLLLLLLKHxmi=i=iimiiimiimiiiiiiiiiiiiiiimi=i=iimiiimiim8X WDf1ffffffffffffffffffffffffffffffffffffffpjeO55aalaaTaaaaa3 P`T{{D{{T{{{T{{Trb_dlhandle_new closed handle unknown symbol "%s" Handle sym disable_close enable_close void void * char short short * int int * long long * double double * const char * (null) ,  ); void ( )() %d arguments are needed unknown type '%c'. too many arguments. unknown type `%c' unknown argument type '%c' unknown type specifier '%c' DL::Symbol was expected Symbol char2type name cproto DLErrno last_error last_error=   x8XXh8H((hHhx(xxxx(xxx(phH8<8 4Dd}Dd}+4lD#<DL::Symbol:0x%lx func=0x%lx '%s'>     unexpected type of argument #%d unknown type '%c' of the return value.  unknown type `%c' of the return value.  ;$     `@  h       P      0$  P     
    `   0  \  @         8  `d       @   	  "@	   $l	  %	  `'	   )	  *
  P,H
   .t
  /
  `1
  3
  4$  p6P   8|  9  p;   =   >,  @X  0B  C  E  @G  H4  J`  PL   N  O  `Q  S<  Th  pV   X  Y  [  0]D  ^p  p`  b  c  Pe   fL  hx  0j  k  pm  o(  pT  Pr  s  u  0w  x0  pz\  |  }    p  P8  0d      Њ    @  pl         @    P8  X  @  0         <   `  @     Ч    P,   P  x            ,  `X  |    P       4   T          <  @`  p      0  0  D  d  P           0  p`        0  p   8  @X      `       D  Ph    P  p               zR x  $      p   FJw ?:*3$"       D   ``             \   h	       $   p   dD    ECEc
HK        2    ECBD_        M    EHAd
N       M    ECI{(          EHDFW
B ,   ,     ECFEI
A (   \  (m   ACM
A(     l   ECLV
A   (        ECLV
A   (     T   ECLV
A   (        ECLV
A   (   8  <	   ECLV
A   (   d  
   ECLV
A   (     $   ECLV
A   (        ECLV
A   (        ECLV
A   (        ECLS
A   (   @     ECLS
A   (   l  h   ECLS
A   (        ECLS
A   (     P   ECLS
A   (        ECLS
A   (     8   ECLS
A   (   H     ECLS
A   (   t      ECLS
A   (        ECLS
A   (        ECLP
A   (     |    ECLW
A   (   $   "   ECLW
A   (   P  #   ECLW
A   (   |  %   ECLW
A   (     &   ECLW
A   (     (   ECLW
A   (      )   ECLW
A   (   ,  +   ECLW
A   (   X  ,   ECLW
A   (      .   ECLT
A   (     /   ECLZ
B   (     1   ECLZ
B   (     2   ECLZ
B   (   4   4   ECLZ
B   (   `  5   ECLZ
B   (     (7   ECLZ
B   (     8   ECLZ
B   (     0:   ECLZ
B   (     ;   ECLZ
B   (   <  8=   ECLW
E   (   h  >   ECLZ
B   (     @@   ECLZ
B   (     A   ECLZ
B   (     HC   ECLZ
B   (   	  D   ECLZ
B   (   D	  PF   ECLZ
B   (   p	  G   ECLZ
B   (   	  XI   ECLZ
B   (   	  J   ECLZ
B   (   	  `L   ECLW
E   (    
  M   ECLV
A   (   L
  XO   ECLV
A   (   x
  P   ECLV
A   (   
  @R   ECLV
A   (   
  S   ECLV
A   (   
  (U   ECLV
A   (   (  V   ECLV
A   (   T  X   ECLV
A   (     Y   ECLV
A   (     Z   ECLS
A   (     l\   ECLK
A   (     ]   ECLK
A   (   0  T_   ECLK
A   (   \  `   ECLK
A   (     <b   ECLK
A   (     c   ECLK
A   (     $e   ECLK
A   (     f   ECLK
A   (   8  h   ECLK
A   (   d  i   ECLH
A   (     j   ECLf
F   (     l   ECLf
F   (     \n   ECLf
F   (     p   ECLc
I   (   @  q   ECLf
F   (   l  xs   ECLf
F   (     ,u   ECLf
F   (     v   ECLf
F   (     x   ECLf
F   (     Hz   ECLf
F      H  {	           \  {t    ECBDe     T|	            P|0    ECAf,     `|   ACBJ
C   ,     }e   ECBN
D        +    ECb   ,   4      ECDEM
F (   d      ECBM
G         t   EJEq       2    EHA`           ECBI{     l,    EHAY      |5    ECBIa    <  ;    EHAh(   \      ECBJGs
B  (     L    ECBJGs
B  ,        ECDSK!
E       p    EG
H             EG
H   $   ,  ȕi    EHAo
SO    T  $    ESK      t   4    ECAj(     @   ECHYC
D          ECAU
B      p    ECA
A(     4   EHI
G    4   P    ACCD ,   X  ,   ECDEJE
C           EHAQ
A,     x1   ECBJEED
G                 3    EHA`     -    EHAZ,   0  ġj   ECFJGU
D @   `     ACM
D
EQ
Ea
E        B    ECBDo           EJMX
D(     k    ECAi
FZ
A        ̧/    ECBDZ     <  ا-    ECBDZ $   `  ]    ECBFu
K,        ECQi
F   $     ]    ECBFu
K(     $a   EJID           h(             1    EHAb   @  1    EHAb   `  İ;    EHAh     )    EHAV     R    EHE(     4   ECHK
G        Ȳ0    EHA],     زV   ECBEFJD
F$   <     EQC        d        $   x  ?    ECAd
KF       ]    ECBII     @3    EHA`,     `   ECHLFOs
D      5    ECl   $   4  D    EHA_
KK $   \  D    EHA_
KK (     0q   EHI
B$         EHG{      )    EHAV$     Z    EFC{
G          4   AIA
C   D  *    ECEX,   d     ECFEG	
E 4        ECFEI
AU
E   (     xk    ECAi
FZ
A  $        EJI               GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             @      `@      hk!            	             	             	             	             	             	             	             H
             2             P)            Xk!                          `k!                   o    `                                
       u
                            p!            	                           h)              "             h      	              o    `!      o           o          o                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           pk!                     03      @3      P3      `3      p3      3      3      3      3      3      3      3      3       4      4       4      04      @4      P4      `4      p4      4      4      4      4      4      4      4      4       5      5       5      05      @5      P5      `5      p5      5      5      5      5      5      5      5      5       6      6       6      06      @6      P6      `6      p6      6      6      6      6      6      6      6      6       7      7       7      07      @7      P7      `7      p7      7      7      7      7      7      7      7      7       8      8       8      08      @8      P8      `8      p8      8      8      8      8      8      8      8      8       9      9       9      09      @9      P9      `9      p9      9               GA$3a1 2      ])              GA$3p1067  @      @               GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA!omit_frame_pointer             GA+stack_clash            GA!stack_realign             GA$3p1067        O)               GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA!omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY     @      C              GA+GLIBCXX_ASSERTIONS   dl.so-1.8.7-16.el8.x86_64.debug h7zXZ  ִF !   t/*] ?Eh=ڊ2N	2\P
Aq;a{.3mAGv¾
&)Zv  "eA55[Ix;(	d.ɞ`(zS I|:ݑ=?;P#6L*ZHݩ3Zrs6C3qoj~Ȕ`^PvH^q +q)1n[a>qϨ	<tN*Il5ѣޘyRk* ls\[(Dj-t=o^p0LT=xDwDnL9Jw
դ)nuiՓB
Y4Ѭ[`[rP
-.ѷ\a "GޞtV6K-kLʪRS<Iy䎽)ns|.y%n_RN_뉂($ ^ ÎU+\SF(ASvRUcpϐo?-=^(`хb7hI,-q {._3Y"Gl@v[LyPm5c5usBG3alUF3jel5!E;am&yZ-D1k ;7^+/.IOge$ Lՙ׊EJ{ƈ<ugeWI\2A(@;ݚvq4u((ޢ7b8kik*|Bjj}vtOGr#Ϝ*[c9nbDvbtqHHDZ- -[UhkA)fmËj:6ٛQݎ6ِ{dt?}^)9Z(HTRvx0l =*yN׭{yFWb*"Cɱd)(CW6*@Q)?`d5NjXj/0 A?!ym C;" lxCEei
PpyǍ\{cwE9vrڷMJ;;b9X|7LLh%<a!KG#\k42ʐS(FOuyHHe-ҏ'޿d,ڄӜ[fyGM[ni54AdhT`C(˺l*	Y(7ɁIhR_<j.s$SK~%ZӒ䋖O"Ad~>VcCVmݧJ|t`6I  _y{GTGz%h۶b%GBV]QAtS<WQOTb<+)6(^|^B0{2~Ou>_n(_ _AOKk="v9o3YuU[:4mh#林(1[ca'+6Meã%_se;#k%:}6v`2ÁL_VU+7Ґ"MUO/{S[LBo o^3,֚c@~E	q˶%TKtbTN8ogf%WXn?3uY);?~G"@W
UHL3\*xPzɤ\}U.w̽T`L-d/! e%?<)>ֻW?`tC+7iz#΄~jE5Վ![!PLadSMTP=6MAfE幁>`*Kn.c[
ԡpe=6)Gd6If{D{vAjl\)=J갅 `	}*L3&r
a;r<A/U:/>;pN,zᘄU&IAJnͳe5FaiEx   #F T  &i*g    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                               8      8      $                                 o       `      `                                  (                                                   0                         u
                             8   o                   b                           E   o       `!      `!                                  T              "       "      h                           ^      B       h)      h)      	                          h             2      2                                    c              3       3      p                            n             9      9      `                            w             ?      ?      _                             }             P)     P)                                                `)     `)     `                                          <     <     $                                          A     A                                                \     \                                                 Xk!     Xk                                               `k!     `k                                               hk!     hk                                                pk!     pk     0                                        m!     m     `                                          p!      p     H                                         `s!     Hs                                                 pva     Hs                                                       dw     $                                                   w                                                             +                             PK     Y\Х    x86_64-linux/nkf.sonu ȯ        ELF          >    `      @       `         @ 8 	 @                                                              #     #     h<      xO                         #     #     0      0                   8      8      8      $       $                                                          Std                                         Ptd   <     <     <                        Qtd                                                  Rtd        #     #     p8      p8                      GNU  \)_g\m    	     @         !                         B2   "?       ?             A` @    ? x ` ?@ 0        (           ~                       @                            ??                    ??                        ~ ~                        
                     ?                   @         0                        D $              " /             !   "                   #   $   %   &   (   +   -   .   /                               0   1       2   6   :   =   A   E   I   M   O   R               T   U   V   W   X   [   _   b   d   f   i                                       j   l   o   r   t   v   x   y   z   {   }       ~                                                                                                                                                                                                                                                                                                                                                                                                                                                                            	  
                                                                                                 !  "  #  %  &  '  )  +  -  .  0  1                      2  3  4  6  8  :  =  >          ?                      @      A  C  D  E  F  G  H  I  J  K                              L  M  N  O  P  Q                                          R  S  T  V  X  Y      Z  [  ]  _  `  b  d  f  h  j  l      m  n  o  q          r  t  v  x  z  {          |  }  ~                                                                                                                                                                                                      	                             "  #  &  )  ,  0  4  8  ;  =  ?      @      A  B  C  E  I  M  P  U  Z  ]  b  e  g              i      j  l  n  r  u  x  z  {  |  }                          ~                                                  ,,r'fr'f,!, ,r'fr'fr'fr'f),+,+,r'f-,BWQr'f-,r'f/,r'fr'fr'f9,;,<,,r'fW/,<,r'fE}>,r'f,,>,r'f@,r'f~,,@,r'fr'fB,,,r'fr'f,,r'famiFK,K,M,,r'fM,r'fN,,,r'fr'f, ,r'fr'f,r'f,,r'f,r'f,r'f,r'f,r'f,,,,r'f#A(t-a-,-,/,r'f.,(0,xMBr'f,1,r'f,1, ,3, ,2,cu:",5,5,i,m,m,<,?,?,A,A,2QC,aaÃŃŃǃǃML,'SO,O,Q,Q,S,S,U,U,V,Ճm,o,o,p,^,LO8p,_,r,a,`,s,t,c,b,u,w,,,,,,,,,,,CE쏐,,,,#\,,,,,,U믔,,ܠ,,,,,,,,,,,,,,;s͝Ř,͝Ř,,Ô,Ô,ܠŔ,?a_ϔ,є,є,Ӕ,Ӕ,Ք,Ք,ה,ה,ٔ,,,,,,,,,,,,,,,,,,,,,,,NB,,,,,,,,!,#,",'(%,$,)*PG',+-eFe%x26=<\99;;==??AIIKKMMYY,[Z,]]_`,`,,,,,,,,,	,,,,,,kmz_ȍmo$,_ȍ&,_ȍ»y',(,_ȍ),+,y{{|Ӊ_ȍ|Ӌ_ȍӁ(NS4,6,7,9,9,;,µ{q;,=,=,>,ӋӘ_ȍӛ_ȍZlG_ȍT,_ȍV,_ȍV,_ȍF,X,_ȍX,_ȍG,H,Z,_ȍZ,_ȍI,J,],\,K,_,.lG_ȍӪ_ȍӭ_ȍ_ȍg,_ȍg,_ȍi,i,k,k,,_ȍޡ_ȍ_ȍv,_ȍ_ȍw,x,_ȍ_ȍ({,y,z,_ȍ 5_ȍ 9{,|,_ȍ,{,},,{,,.{,,/{,1{,1{,;r'f ,_ȍ=r'f_ȍ<r'f,,>r'f_ȍ%$_ȍ,,?r'f,@r'f_ȍ,_ȍ,,Ar'f,8{,,Cr'f,Br'f,,:{,,,Kr'fLr'f_ȍ_ȍ,Mr'f_ȍ,Or'f_ȍ,Or'f_ȍ,Qr'f_ȍ,_ȍ,_ȍK{,lk_ȍ_ȍM{,O{,O{,Q{,Q{,R{,[r'f]r'f_ȍ\r'f,^r'f,_ȍ_ȍ,_r'f`r'fh,_ȍ,_ȍ,`r'fk,br'fj,_ȍ,,br'fm,dr'f,,|,q,ˮו,lr'fٕ,lr'f ϵؕ,_ȍڕ,_ȍnr'fɑ,nr'fڕ,_ȍ\]xʑ,ܕ,_ȍqr'fpr'fz,ʑ,ܕ,`ȍ̑,ޕ,`ȍ|,ǤV̑,ޕ,`ȍ,`ȍ},~,`ȍ`ȍ,󅧭,}r'f,}r'f`ȍ~r'fd,,`ȍr'f`ȍr'f,`ȍr'fr'fr'fr'fr'f,r'fqX,,r'fr'f,,r'fr'f `ȍ, `ȍ,r'f,,,,,,,,r'fr'f
,,
,,r'fr'f,,                                                                                              m                     {                     t                     f                                                                 A                                          '                                                               a                                          Z                                          ,                       F   "                   d                     S                     Q                                     W                 )                )                                  h                y                 -)    @            <)                K)                Z)                                                                  i)    @                                             x)                                )                                 )                 )    @            )                                                                 |                 )                k          n                        #                 )                 	                 4                )    @                                             E                 )                H	    :            V                )                9	     9                                             g                 *                      8            *    @                7            x                                                 ,*    ~            ;*    }                 7                                             J*     }                @]                                                             &                Y*    @|                            ,     $            h*    {                             7                 H                    6            w*    z            *     z            Y                 j                *    @y                 6            *    x            {                     5            *    w                                             *     w            		     5                            *    @v            	    4                             *    u                            *    t                             *     t                                                             %                 +    @s            t    @#                #            <                 M                  ^                +    r            o                     $$            6                          @       ++    q            G                                 j+     q            X                                 i                                 z                                 3    #                                                              W	                h	                 y	                     `$     P                            G     K                                                         *                    `           k    #            ;                 \    #                #                $     =           #                #                #                #            )    #                      (       L                D     *            ]                 n                                                                                                                                    z    #                $                $                                             /                @                                      @#           Q                                 b                                 )                 s                                 :                K                                                  	                 	                	                	                                                                                                                    +    $                             .                 ?                P                     9            a                r                                                                                       @                                            `     $                                                                               "                 3                                                 D                                 U                                 f                 w                                   ($                                 ,$                                                                              U      $                                      >          #            J    #                                                              !                2                 C                T                 e                v                                 	                	                 
                                 
                 &
                                                7
                                  H
                                Y
                                  j
                                {
                 
                
                 
                
                 
                
                           @       
                                                                                      `                            %                                 6                                 G                 X                i                     `                            "                z                                                 4                 F    `                                             X                j                :+    @p                             |                     `                  ;                #                               8                                                 `                                                                 `            0                B                T                 f    `            x                                                     `                                                $                                 `                 $                                            ,                 >    `                            P                                                     #                                  #                                 "                                                  "            "    !                             $                3     !            5                 b                t                 f!    o                `                            F                w!    n            W                 !     n                 #           h    
            y     
            !    @m                	                 	                                                 `                            !    l                            !    k                                 `            (                j    (                            :                                 L                                                                                        #                           #                 4                E                 ^    `            p                !     k                            !    @j            &    @            !    i            \                !    h            m                 "     h            ~                !"    @g            V                                 2"    f                            C"    e            g                 x                                 T"     e                            e"    @d                                                                                                                &                v"    c                             "    b                `            "     b            "    @a                            "    `                             "    _            (                9                 J                [                 0!    3            "     _                `     (       "    @^            "    ]            l                #    \             #     \            }                                 1#    @[            B#    Z            U!     4                                             S#    Y            F    @#           d#     Y            ]    #                                             u#    @X            -     2                             >      2                            O     1                             `      1            D!    0                 /            L+                    #           -                #    W            [+                 #    V            0&                >                 O                ?&                #     V            z     `     n      #    @U                            `                 N&                 q                ]&    @            #    T            '                 #    S            8                                 l&                                      /            I                 {&                Z                &                                                       .            k                                  &    @            &                #     S            #    @R                            &                $    Q                             &                 $    P                            &    @            0$     P            
                 &                A$    @O                            R$    N            ,                 c$    M                  .            q      0            t$     M            $    @L                 -                  -                 ,                  ,            !    +            !     +            &                '                 $    K            '    @            =                 '                N                 $    J            $     J            _                /'                >'                     *            $    @I            p                 $    H                            M'    @            Y    )            \'                      )            $    G                                             k'                     (            z'                                                  +    $                                  '            C    `$     P                       '    @                            '                     #                             $     G            1                %    @F            '                                '                 B                 %    E            '	     :                             S                /%    D            '    @            '                     '            	                d                 @%     D                             u                Q%    @C                &                 $     H       +                                 b%    B                            s%    A                 &                %            %     A            %    @@                 %            8    #                             '                                '                 %    ?            (    @                  3                                             %    >            (                %     >            (                                 %    @=            .(                 =(    @            L(                [(                j(                                 y(    @            +    $                                              (                (                0                 A                (                 (    @            %    <            R                 %    ;            c                (                t                                                                                                                                    (                (                                  $                                5                 (    @             )                                 F                 __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize std_gc_ndx std_gc_buf shiftjis_cp932 shiftjis_x0212 cp932inv euc_to_utf8_2bytes x0212_to_utf8_2bytes euc_to_utf8_1byte euc_to_utf8_2bytes_ms score_table_A0 score_table_F0 __stack_chk_fail x0212_shiftjis utf8_to_euc_2bytes utf8_to_euc_3bytes utf8_to_euc_2bytes_932 utf8_to_euc_3bytes_932 utf8_to_euc_3bytes_ms utf8_to_euc_2bytes_ms z_prev2 z_prev1 normalization_table mime_lastchar2 mime_lastchar1 mimeout_buf_count mimeout_buf mime_pattern mime_encode mime_encode_method mimeout_preserve_space input_code_list stderr fwrite exit strcmp rb_str_resize rb_string_value find_inputcode_byfunc __fprintf_chk malloc free perror realloc check_bom mime_priority_func hex_getc nkf_split_options rb_str_new Init_nkf rb_define_module rb_define_module_function rb_define_alias rb_singleton_class rb_define_const rb_str_new2 x0212_shiftjis_A2 x0212_shiftjis_B0 x0212_shiftjis_B1 x0212_shiftjis_B2 x0212_shiftjis_B3 x0212_shiftjis_B4 x0212_shiftjis_B5 x0212_shiftjis_B7 x0212_shiftjis_B8 x0212_shiftjis_B9 x0212_shiftjis_BA x0212_shiftjis_BB x0212_shiftjis_BC x0212_shiftjis_BD x0212_shiftjis_BE x0212_shiftjis_BF x0212_shiftjis_C0 x0212_shiftjis_C1 x0212_shiftjis_C2 x0212_shiftjis_C3 x0212_shiftjis_C4 x0212_shiftjis_C5 x0212_shiftjis_C6 x0212_shiftjis_C7 x0212_shiftjis_C8 x0212_shiftjis_C9 x0212_shiftjis_CA x0212_shiftjis_CB x0212_shiftjis_CC x0212_shiftjis_CD x0212_shiftjis_CE x0212_shiftjis_CF x0212_shiftjis_D0 x0212_shiftjis_D1 x0212_shiftjis_D2 x0212_shiftjis_D3 x0212_shiftjis_D4 x0212_shiftjis_D5 x0212_shiftjis_D7 x0212_shiftjis_D8 x0212_shiftjis_D9 x0212_shiftjis_DC x0212_shiftjis_DD x0212_shiftjis_DE x0212_shiftjis_DF x0212_shiftjis_E0 x0212_shiftjis_E1 x0212_shiftjis_E2 x0212_shiftjis_E3 x0212_shiftjis_E4 x0212_shiftjis_E5 x0212_shiftjis_E6 x0212_shiftjis_E7 x0212_shiftjis_E8 x0212_shiftjis_E9 x0212_shiftjis_EA x0212_shiftjis_EB x0212_shiftjis_EC x0212_shiftjis_F3 x0212_shiftjis_F4 utf8_to_euc_E2_932 utf8_to_euc_E3_932 utf8_to_euc_E4 utf8_to_euc_E5 utf8_to_euc_E6 utf8_to_euc_E7 utf8_to_euc_E8 utf8_to_euc_E9 utf8_to_euc_EF_ms utf8_to_euc_E2_ms utf8_to_euc_E3 utf8_to_euc_E2 utf8_to_euc_EF utf8_to_euc_C2_932 utf8_to_euc_C3_932 utf8_to_euc_C4 utf8_to_euc_C5 utf8_to_euc_C7 utf8_to_euc_CB utf8_to_euc_CE utf8_to_euc_CF utf8_to_euc_D0 utf8_to_euc_D1 utf8_to_euc_C2_ms utf8_to_euc_C3 utf8_to_euc_C2 utf8_to_euc_EFA4 utf8_to_euc_EFA7 utf8_to_euc_EFA8 utf8_to_euc_EFBC utf8_to_euc_EFBD_ms utf8_to_euc_EFBE utf8_to_euc_EFBF utf8_to_euc_EFBD utf8_to_euc_E980 utf8_to_euc_E981 utf8_to_euc_E982 utf8_to_euc_E983 utf8_to_euc_E984 utf8_to_euc_E985 utf8_to_euc_E986 utf8_to_euc_E987 utf8_to_euc_E988 utf8_to_euc_E989 utf8_to_euc_E98A utf8_to_euc_E98B utf8_to_euc_E98C utf8_to_euc_E98D utf8_to_euc_E98E utf8_to_euc_E98F utf8_to_euc_E990 utf8_to_euc_E991 utf8_to_euc_E992 utf8_to_euc_E995 utf8_to_euc_E996 utf8_to_euc_E997 utf8_to_euc_E998 utf8_to_euc_E999 utf8_to_euc_E99A utf8_to_euc_E99B utf8_to_euc_E99C utf8_to_euc_E99D utf8_to_euc_E99E utf8_to_euc_E99F utf8_to_euc_E9A0 utf8_to_euc_E9A1 utf8_to_euc_E9A2 utf8_to_euc_E9A3 utf8_to_euc_E9A4 utf8_to_euc_E9A5 utf8_to_euc_E9A6 utf8_to_euc_E9A7 utf8_to_euc_E9A8 utf8_to_euc_E9A9 utf8_to_euc_E9AA utf8_to_euc_E9AB utf8_to_euc_E9AC utf8_to_euc_E9AD utf8_to_euc_E9AE utf8_to_euc_E9AF utf8_to_euc_E9B0 utf8_to_euc_E9B1 utf8_to_euc_E9B3 utf8_to_euc_E9B4 utf8_to_euc_E9B5 utf8_to_euc_E9B6 utf8_to_euc_E9B7 utf8_to_euc_E9B8 utf8_to_euc_E9B9 utf8_to_euc_E9BA utf8_to_euc_E9BB utf8_to_euc_E9BC utf8_to_euc_E9BD utf8_to_euc_E9BE utf8_to_euc_E880 utf8_to_euc_E881 utf8_to_euc_E882 utf8_to_euc_E883 utf8_to_euc_E884 utf8_to_euc_E885 utf8_to_euc_E886 utf8_to_euc_E887 utf8_to_euc_E888 utf8_to_euc_E889 utf8_to_euc_E88A utf8_to_euc_E88B utf8_to_euc_E88C utf8_to_euc_E88D utf8_to_euc_E88E utf8_to_euc_E88F utf8_to_euc_E890 utf8_to_euc_E891 utf8_to_euc_E892 utf8_to_euc_E893 utf8_to_euc_E894 utf8_to_euc_E895 utf8_to_euc_E896 utf8_to_euc_E897 utf8_to_euc_E898 utf8_to_euc_E899 utf8_to_euc_E89A utf8_to_euc_E89B utf8_to_euc_E89C utf8_to_euc_E89D utf8_to_euc_E89E utf8_to_euc_E89F utf8_to_euc_E8A0 utf8_to_euc_E8A1 utf8_to_euc_E8A2 utf8_to_euc_E8A3 utf8_to_euc_E8A4 utf8_to_euc_E8A5 utf8_to_euc_E8A6 utf8_to_euc_E8A7 utf8_to_euc_E8A8 utf8_to_euc_E8A9 utf8_to_euc_E8AA utf8_to_euc_E8AB utf8_to_euc_E8AC utf8_to_euc_E8AD utf8_to_euc_E8AE utf8_to_euc_E8B0 utf8_to_euc_E8B1 utf8_to_euc_E8B2 utf8_to_euc_E8B3 utf8_to_euc_E8B4 utf8_to_euc_E8B5 utf8_to_euc_E8B6 utf8_to_euc_E8B7 utf8_to_euc_E8B8 utf8_to_euc_E8B9 utf8_to_euc_E8BA utf8_to_euc_E8BB utf8_to_euc_E8BC utf8_to_euc_E8BD utf8_to_euc_E8BE utf8_to_euc_E8BF utf8_to_euc_E780 utf8_to_euc_E781 utf8_to_euc_E782 utf8_to_euc_E783 utf8_to_euc_E784 utf8_to_euc_E785 utf8_to_euc_E786 utf8_to_euc_E787 utf8_to_euc_E788 utf8_to_euc_E789 utf8_to_euc_E78A utf8_to_euc_E78B utf8_to_euc_E78C utf8_to_euc_E78D utf8_to_euc_E78E utf8_to_euc_E78F utf8_to_euc_E790 utf8_to_euc_E791 utf8_to_euc_E792 utf8_to_euc_E793 utf8_to_euc_E794 utf8_to_euc_E795 utf8_to_euc_E796 utf8_to_euc_E797 utf8_to_euc_E798 utf8_to_euc_E799 utf8_to_euc_E79A utf8_to_euc_E79B utf8_to_euc_E79C utf8_to_euc_E79D utf8_to_euc_E79E utf8_to_euc_E79F utf8_to_euc_E7A0 utf8_to_euc_E7A1 utf8_to_euc_E7A2 utf8_to_euc_E7A3 utf8_to_euc_E7A4 utf8_to_euc_E7A5 utf8_to_euc_E7A6 utf8_to_euc_E7A7 utf8_to_euc_E7A8 utf8_to_euc_E7A9 utf8_to_euc_E7AA utf8_to_euc_E7AB utf8_to_euc_E7AC utf8_to_euc_E7AD utf8_to_euc_E7AE utf8_to_euc_E7AF utf8_to_euc_E7B0 utf8_to_euc_E7B1 utf8_to_euc_E7B2 utf8_to_euc_E7B3 utf8_to_euc_E7B4 utf8_to_euc_E7B5 utf8_to_euc_E7B6 utf8_to_euc_E7B7 utf8_to_euc_E7B8 utf8_to_euc_E7B9 utf8_to_euc_E7BA utf8_to_euc_E7BC utf8_to_euc_E7BD utf8_to_euc_E7BE utf8_to_euc_E7BF utf8_to_euc_E680 utf8_to_euc_E681 utf8_to_euc_E682 utf8_to_euc_E683 utf8_to_euc_E684 utf8_to_euc_E685 utf8_to_euc_E686 utf8_to_euc_E687 utf8_to_euc_E688 utf8_to_euc_E689 utf8_to_euc_E68A utf8_to_euc_E68B utf8_to_euc_E68C utf8_to_euc_E68D utf8_to_euc_E68E utf8_to_euc_E68F utf8_to_euc_E690 utf8_to_euc_E691 utf8_to_euc_E692 utf8_to_euc_E693 utf8_to_euc_E694 utf8_to_euc_E695 utf8_to_euc_E696 utf8_to_euc_E697 utf8_to_euc_E698 utf8_to_euc_E699 utf8_to_euc_E69A utf8_to_euc_E69B utf8_to_euc_E69C utf8_to_euc_E69D utf8_to_euc_E69E utf8_to_euc_E69F utf8_to_euc_E6A0 utf8_to_euc_E6A1 utf8_to_euc_E6A2 utf8_to_euc_E6A3 utf8_to_euc_E6A4 utf8_to_euc_E6A5 utf8_to_euc_E6A6 utf8_to_euc_E6A7 utf8_to_euc_E6A8 utf8_to_euc_E6A9 utf8_to_euc_E6AA utf8_to_euc_E6AB utf8_to_euc_E6AC utf8_to_euc_E6AD utf8_to_euc_E6AE utf8_to_euc_E6AF utf8_to_euc_E6B0 utf8_to_euc_E6B1 utf8_to_euc_E6B2 utf8_to_euc_E6B3 utf8_to_euc_E6B4 utf8_to_euc_E6B5 utf8_to_euc_E6B6 utf8_to_euc_E6B7 utf8_to_euc_E6B8 utf8_to_euc_E6B9 utf8_to_euc_E6BA utf8_to_euc_E6BB utf8_to_euc_E6BC utf8_to_euc_E6BD utf8_to_euc_E6BE utf8_to_euc_E6BF utf8_to_euc_E580 utf8_to_euc_E581 utf8_to_euc_E582 utf8_to_euc_E583 utf8_to_euc_E584 utf8_to_euc_E585 utf8_to_euc_E586 utf8_to_euc_E587 utf8_to_euc_E588 utf8_to_euc_E589 utf8_to_euc_E58A utf8_to_euc_E58B utf8_to_euc_E58C utf8_to_euc_E58D utf8_to_euc_E58E utf8_to_euc_E58F utf8_to_euc_E590 utf8_to_euc_E591 utf8_to_euc_E592 utf8_to_euc_E593 utf8_to_euc_E594 utf8_to_euc_E595 utf8_to_euc_E596 utf8_to_euc_E597 utf8_to_euc_E598 utf8_to_euc_E599 utf8_to_euc_E59A utf8_to_euc_E59B utf8_to_euc_E59C utf8_to_euc_E59D utf8_to_euc_E59E utf8_to_euc_E59F utf8_to_euc_E5A0 utf8_to_euc_E5A1 utf8_to_euc_E5A2 utf8_to_euc_E5A3 utf8_to_euc_E5A4 utf8_to_euc_E5A5 utf8_to_euc_E5A6 utf8_to_euc_E5A7 utf8_to_euc_E5A8 utf8_to_euc_E5A9 utf8_to_euc_E5AA utf8_to_euc_E5AB utf8_to_euc_E5AC utf8_to_euc_E5AD utf8_to_euc_E5AE utf8_to_euc_E5AF utf8_to_euc_E5B0 utf8_to_euc_E5B1 utf8_to_euc_E5B2 utf8_to_euc_E5B3 utf8_to_euc_E5B4 utf8_to_euc_E5B5 utf8_to_euc_E5B6 utf8_to_euc_E5B7 utf8_to_euc_E5B8 utf8_to_euc_E5B9 utf8_to_euc_E5BA utf8_to_euc_E5BB utf8_to_euc_E5BC utf8_to_euc_E5BD utf8_to_euc_E5BE utf8_to_euc_E5BF utf8_to_euc_E4B8 utf8_to_euc_E4B9 utf8_to_euc_E4BA utf8_to_euc_E4BB utf8_to_euc_E4BC utf8_to_euc_E4BD utf8_to_euc_E4BE utf8_to_euc_E4BF utf8_to_euc_E380_932 utf8_to_euc_E381 utf8_to_euc_E382_932 utf8_to_euc_E383 utf8_to_euc_E388 utf8_to_euc_E38A utf8_to_euc_E38C utf8_to_euc_E38D utf8_to_euc_E38E utf8_to_euc_E38F utf8_to_euc_E380 utf8_to_euc_E382 utf8_to_euc_E280_932 utf8_to_euc_E284 utf8_to_euc_E285 utf8_to_euc_E286 utf8_to_euc_E287 utf8_to_euc_E288_932 utf8_to_euc_E289 utf8_to_euc_E28A utf8_to_euc_E28C utf8_to_euc_E291 utf8_to_euc_E294 utf8_to_euc_E295 utf8_to_euc_E296 utf8_to_euc_E297 utf8_to_euc_E298 utf8_to_euc_E299 utf8_to_euc_E280_ms utf8_to_euc_E288 utf8_to_euc_E280 euc_to_utf8_8FA2 euc_to_utf8_8FA6 euc_to_utf8_8FA7 euc_to_utf8_8FA9 euc_to_utf8_8FAA euc_to_utf8_8FAB euc_to_utf8_8FB0 euc_to_utf8_8FB1 euc_to_utf8_8FB2 euc_to_utf8_8FB3 euc_to_utf8_8FB4 euc_to_utf8_8FB5 euc_to_utf8_8FB6 euc_to_utf8_8FB7 euc_to_utf8_8FB8 euc_to_utf8_8FB9 euc_to_utf8_8FBA euc_to_utf8_8FBB euc_to_utf8_8FBC euc_to_utf8_8FBD euc_to_utf8_8FBE euc_to_utf8_8FBF euc_to_utf8_8FC0 euc_to_utf8_8FC1 euc_to_utf8_8FC2 euc_to_utf8_8FC3 euc_to_utf8_8FC4 euc_to_utf8_8FC5 euc_to_utf8_8FC6 euc_to_utf8_8FC7 euc_to_utf8_8FC8 euc_to_utf8_8FC9 euc_to_utf8_8FCA euc_to_utf8_8FCB euc_to_utf8_8FCC euc_to_utf8_8FCD euc_to_utf8_8FCE euc_to_utf8_8FCF euc_to_utf8_8FD0 euc_to_utf8_8FD1 euc_to_utf8_8FD2 euc_to_utf8_8FD3 euc_to_utf8_8FD4 euc_to_utf8_8FD5 euc_to_utf8_8FD6 euc_to_utf8_8FD7 euc_to_utf8_8FD8 euc_to_utf8_8FD9 euc_to_utf8_8FDA euc_to_utf8_8FDB euc_to_utf8_8FDC euc_to_utf8_8FDD euc_to_utf8_8FDE euc_to_utf8_8FDF euc_to_utf8_8FE0 euc_to_utf8_8FE1 euc_to_utf8_8FE2 euc_to_utf8_8FE3 euc_to_utf8_8FE4 euc_to_utf8_8FE5 euc_to_utf8_8FE6 euc_to_utf8_8FE7 euc_to_utf8_8FE8 euc_to_utf8_8FE9 euc_to_utf8_8FEA euc_to_utf8_8FEB euc_to_utf8_8FEC euc_to_utf8_8FED euc_to_utf8_8FF3 euc_to_utf8_8FF4 euc_to_utf8_A1_ms euc_to_utf8_A2_ms euc_to_utf8_A3 euc_to_utf8_A4 euc_to_utf8_A5 euc_to_utf8_A6 euc_to_utf8_A7 euc_to_utf8_A8 euc_to_utf8_A9 euc_to_utf8_AA euc_to_utf8_AB euc_to_utf8_AC euc_to_utf8_AD euc_to_utf8_AE euc_to_utf8_AF euc_to_utf8_B0 euc_to_utf8_B1 euc_to_utf8_B2 euc_to_utf8_B3 euc_to_utf8_B4 euc_to_utf8_B5 euc_to_utf8_B6 euc_to_utf8_B7 euc_to_utf8_B8 euc_to_utf8_B9 euc_to_utf8_BA euc_to_utf8_BB euc_to_utf8_BC euc_to_utf8_BD euc_to_utf8_BE euc_to_utf8_BF euc_to_utf8_C0 euc_to_utf8_C1 euc_to_utf8_C2 euc_to_utf8_C3 euc_to_utf8_C4 euc_to_utf8_C5 euc_to_utf8_C6 euc_to_utf8_C7 euc_to_utf8_C8 euc_to_utf8_C9 euc_to_utf8_CA euc_to_utf8_CB euc_to_utf8_CC euc_to_utf8_CD euc_to_utf8_CE euc_to_utf8_CF euc_to_utf8_D0 euc_to_utf8_D1 euc_to_utf8_D2 euc_to_utf8_D3 euc_to_utf8_D4 euc_to_utf8_D5 euc_to_utf8_D6 euc_to_utf8_D7 euc_to_utf8_D8 euc_to_utf8_D9 euc_to_utf8_DA euc_to_utf8_DB euc_to_utf8_DC euc_to_utf8_DD euc_to_utf8_DE euc_to_utf8_DF euc_to_utf8_E0 euc_to_utf8_E1 euc_to_utf8_E2 euc_to_utf8_E3 euc_to_utf8_E4 euc_to_utf8_E5 euc_to_utf8_E6 euc_to_utf8_E7 euc_to_utf8_E8 euc_to_utf8_E9 euc_to_utf8_EA euc_to_utf8_EB euc_to_utf8_EC euc_to_utf8_ED euc_to_utf8_EE euc_to_utf8_EF euc_to_utf8_F0 euc_to_utf8_F1 euc_to_utf8_F2 euc_to_utf8_F3 euc_to_utf8_F4 euc_to_utf8_F5 euc_to_utf8_F9 euc_to_utf8_FA euc_to_utf8_FB euc_to_utf8_FC_ms euc_to_utf8_A1 euc_to_utf8_A2 euc_to_utf8_FC libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.3.4 GLIBC_2.4 GLIBC_2.2.5 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     +         ti	   +     ii   +     ui	   +      #                  #                  #            #     #            H     #                 #            ؇     #                 #            ߉     #                 #                 #                  #                 #                 #                 #                  #                 (#                 0#            )     8#                 @#            .     H#                 P#                 X#                 `#                 h#                 p#                 x#            	     #                 #            $     #            (     #            +     #            -     #                 #            8     #            =     #            A     #                 #            I     #            $     #            i     #            Q     #            T     #            ]      #            `     #            r     #                 #                  #                 (#                 0#                 8#                 @#                  H#                 P#            u     X#            &     `#            z     h#                 p#                 x#                 #            D     #                 #            L     #                 #            T     #                 #            c     #                 #            [     #                 #            k     #                 #            v     #                 #                 #                  #                 #                 #            &     #                  #            2     (#                 0#                 8#                 @#            ܇     H#                 P#                 X#                 `#                 h#                 p#                 x#                 #                 #                 #                 #                 #                 #                  $                  $                  0$            0B     8$            0B     `$            ^     h$            j     p$            y     x$                 $                 $                 $                 $            Ɖ     $            щ     $                   $            @     $                   $            @     $            P=     $                   $            @     $                   $            @     $            P=      $             !     $             !     $             !     $             !      $             !     ($             !     0$             !     8$                  @$             !     H$                  `$            ͆     $            0L     $                  $                 $            0J     $                  $            H     $            `H     $            0B     $            r     0$                  @$                 h$            P      $                   $            @     $                   $            @     $                   $            @     $                   $            @     $                 #                  8#        #          @#        %          H#        &          P#        '          X#        )          `#        +          p#        /          x#        0          #        1          #        5          #        6          #        9          #        :          #        =          #        >          #        A          #        C          #        D          #        E          #        F          #        G          #        H          #        I          #        J           #        K          #        L          #        M          #        N           #        O          (#        P          0#        Q          8#        R          @#        S          H#        U          P#        V          X#        X          `#        Y          p#        Z          x#        [          #        ]          #        m          #        n          #        p          #        q          #        |          #        }          #        ~          #                  #                  #                  #                  #                  #                   #                  #                  #                  #                  P#                  X#                  #        ~           #                   #                   `#                   #                   #                   h#                   #                   #                   p#                   #                   #                   x#                   #                    #                   #                    #                   #                   #                   #                   8#        i          #        i          P#                   X#                   #                   #                   8#                   P#                   X#        B          `#        H           #        H           `#        H           h#        J           #        J           h#        J           x#        P           #        P           x#        P           #        `           #        `           #        `           #        f           0#        f           #        f           #        i           8#        i           #        i           #        n           @#        n           #        n           #        q           H#        q           #        q           #        P          #        C           X#        C           P#        @           #                   #                   #                   #                    #                    #                   #                   #                   #        9           #                   #                   #                   #                   #                   #        	          #        
          #                  #                  #                  #                  #                  #                   #                  #                  #                  #                   #                  (#                  0#                  8#                  @#        !          H#        "          P#        $          h#        (          p#        *          x#        ,          #        -          #        .          #        2          #        3          #        4          #        7          #        8          #        <          #                  #                  #                  #                  #                  #                  #                  #                    #                   #                   #        #           #        $            #        %           (#        '           0#        *           8#        ,           @#        0           H#        1           X#        2           `#        7           h#        :           p#        >           x#        A           #        F           #        K           #        U           #        V           #        W           #        Z           #        ]           #                   #                   #                   #                   #                   #                   #                   #                    #                   #                   #                   #                    #                   (#                   0#                   8#                   @#                   H#                   P#                  X#                  `#                  h#                  p#                  x#                  #                  #                  #                  #                  #                  #                  #                  #                  #        B          #        D          #        G          #        I          #        N          #        R          #        X          #        [           #        `          #        b          #        j          #        l           #        q          (#        r          0#        w          @#        ~          H#                  P#                  X#                  `#                  h#                  p#                  x#                  #                  #                  #                  #                  #                  #                  #                   #                   #                   #                   #                   #                   #                   #                   #                   #                    #                   #                   #                   #                    #                   (#                   0#                   8#                   @#                   H#                   P#                   X#                   `#                   h#                   p#                   x#                   #                   #                   #                   #                   #                   #                   #                   #                   #                  #                  #                  #                  #                  #                  #                  #                   #                  #                  #                  #        
           #                  (#                  0#                  8#                  @#        %          H#        '          P#        *          X#        /          `#        1          h#        7          p#        8          x#        <          #        =          #        ?          #        L          #        Q          #        W          #        Z          #        _          #                   #                   #                   #                   #                   #                   #                   #                    #                   #                   #                   #                    #                   (#                   0#                   8#                   @#                   H#                   P#                   X#                   `#                   h#                   p#                   x#                   #                   #                   #                   #                   #                   #                   #                   #                   #                  #                  #                  #                  #                  #                  #                  #                   #                  #                  #                  #                   #                  (#                  0#                  8#                  @#                  H#                  P#                  X#                  `#                  h#                  p#                  x#                  #                  #                  #                  #                  #                  #                  #                  #                  #        3           #        6           #        <           #        =           #        D           #        E           #        L           #        M            #        Q           #        R           #        X           #        ^            #        _           (#        c           0#        d           8#        h           @#        k           H#        l           P#        o           X#        r           `#        t           h#        v           p#        x           x#        y           #        z           #        {           #                   #                   #                   #                   #                   #                   #        \          #        ^          #        _          #        a          #        c          #        e          #        f          #        i           #        j          #        l          #        r          #        t           #        w          (#        x          0#        z          8#        {          @#                  H#                  P#                  X#                  `#                  h#                  p#                  x#                  #                  #                  #                  #                  #                  #                  #                  #                  #        T          #        W          #        `          #        b          #        d          #        g          #        h          #        k          #                   #        3          #        3          #                  #        :          #        :           #        @           #        @          #        V          #        V           #        ]           #        ]          (#        d          (#        d          0#        e          0#        e          8#        h          8#        h          #        -          #        5          #        p          #                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                   #                  #                  #                  #                  #                  #                  #                   #                    #                    #                   H#                  H#                  H#                  `#                  `#                  `#                  h#                  h#                  h#                  p#                  p#                  p#                  x#                  x#                  x#                  #                  #                  #                  #                   #                   #                   #                   #                   #                  #                  #        o          #        s          #        u           #        y          #                  #                  8#                  @#                  H#                  P#                  X#                  `#                  h#                  p#                  x#                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                   #                  #                  #                  #                   #                  (#                  0#                  8#                  @#                  H#        	          P#                  X#                  `#                  h#                  p#                  x#                  #                  #        #          #        (          #        )          #        .          #        0          #        6          #        H          #        J          #        O          #        S          #        Y          #        \          #        a          #        c          #        f           #        g          #        n          #        s          #        u           #        x          P#                  X#                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                  #                   #                   #                  #                  #                  #                  #                  #                  #                   #                   #                  (#                  (#                  0#                  0#                  8#        !          8#        !          @#        "          @#        "          H#        $          H#        $          P#        &          P#        &          X#        +          X#        +          `#        ,          `#        ,          h#        2          h#        2          p#        4          p#        4          x#        9          x#        9          #        ;          #        ;          #        C          #        C          #        E          #        E          #        K          #        K          #        M          #        M          #        T          #        T          #        U          #        U          #        k          #        k          #        m          #        m          #        o          #        o          #        t          #        t          #        v          #        v          #        y          #        y          #        z          #        z          #        {          #        {          #        |          #        |           #        }           #        }          #                  #                  #                  #                  #                  #                   #                   #                  (#                  (#                  0#                  0#                  8#                  8#                  @#                  @#                  H#                  H#                  P#                  P#                  X#                   X#                   `#                   `#                   h#                   h#                   p#                    p#                    x#        !           x#        !           #        "           #        "           #        &           #        &           #        )           #        )           #        +           #        +           #        -           #        -           #        .           #        .           #        /           #        /           #        4           #        4           #        8           #        8           #        ;           #        ;           #        ?           #        ?           #        B           #        B           #        G           #        G           #        I           #        I           #        N           #        N           #        O           #        O            #        S            #        S           #        Y           #        Y           #        \           #        \           #        a           #        a            #        b            #        b           (#        e           (#        e           0#        g           0#        g           8#        j           8#        j           @#        m           @#        m           H#        p           H#        p           P#        s           P#        s           X#        u           X#        u           `#        w           `#        w           #        |           #        |           #                   #                   #                   #                   #        ;          #                  #                  #                   #                   #                  #        F          #                    #                  #        v          #        [           #                    #        ?          (#                   0#                  8#        }           @#                   H#                   P#                   X#        @          `#                   h#        (           p#                  x#        ^          #                   #        A          #                   #                   #                   #                  #                   #                   #                   #        5           #                   #                  #                   #                   #                   #                    $                     $                   ( $                   0 $                   8 $                   @ $                   H $                   P $        T           X $                   ` $        	           h $        
           p $                   x $                    $                    $                    $                    $                    $                    $                    $                    $                    $                    $                   HH# HtH     5# %#  h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %# D  %}# D  %u# D  %m# D  H=# H# H9tH~# Ht	        H=a# H5Z# H)HHH?HHtH%# HtfD      =%#  u+UH=
#  HtH=" 9d# ]     w    H# Hc   tJH># <øf# D##    $  LcDVO@McMIM)L5# MGCE  E   ?        f.     G~	v?w	w7π  ,@    Et$[  G	w
:11f     wfDVMcHL@LHL)LO# LE@DE   D   A   M2    Ekk   D?a     ND)ǁ   1)1@ HDFL@McLHL)LL_# E@Eu=D?a  D)ǁ   ~fDAE     DAE        .   91      HcH<xHݤ  <            /  H|$t$tGv8# 1HÐt$    Z# uF	w;N   w0t1~D$    iҼ   1)  t$@ HL$HT$ut$|$r% ǀ u        f  u?@π:    Ð   t8= YA?AAD% ?  ?	@΀  2A?A?@πAD9fD              D  Htkǀxf9}bHcHHtVƀ   ?wHHcrft<&# ftf w&f-t fx+f   DȃA1Aø   f.     ̏fD  AU       ATIUSH    كt4ЍY9L-  D  1At AԉمyH[]A\A]fS&   1#  #   1# ?B =  غC1ֺ)ƃ0# ھZ|
1ֺ)ƃ0`# غY1ֺ)ƃ04# غMb1ֺ̉)ƃ0# غQ1ֺ)ƃ0# ̉1Љ)ƃ0# غ1)Ís0# ;   1[%# f      '    (cK	~mf     S&   1,# #   1# x   1# H=# ;   1[%# fD  AT\   U1S#        U   1L%  # 0   1# 0   1# 1HA4# 1A4n# 1A4V# 1A4;# A41.# A4,[1]A\%# D  u   1L%  # fS\   1# x   1# {   1# H=# d}   1[%# fD  ^# %# f.     t{ff= t/1!]w}d"# HcuuH&# H1HuJfB"# u"  u
   Ct?1!]w2H# HcH    H# 1!]wHcr@ H# H DGEx?A   t.wHD0t,Dp t)pt<O~IfO O@ I H!# AB	AD  H# AB	Aff.     fSH |$t$dH%(   HD$1	!# t+ #     # # # |$   t$uE%   =      #     y# HD$dH3%(   d  H [    t[#    tǉHL$HT$Ht$|$ # |$t# |$tf# D  V#    @΀# dD   ƀ t8t$  u<@# t$?@π# D  # 
    u @f# ߃?@π  @=# ?@π(# ߃?@π# t$?@΀# @ AUATUSH# t3=#   H# #        п   # thtwuC%   =      ={#   Hx# t6ЉH[]A\A]%`#      ts H[]A\A]%*# f@̀1        п# Xf        u&@Yf.     H[]A\A]D  % = 
  H#      AA@AA=}#   tD҉r# Di# DU# M# Dff.     fV# ATUStC=#   H# /#        11# #    #    }   uaډ؁   %    D؉H# Á=#   @tD1Љ# Dw# []A\%k#  މÅu[]A\@ ˀ D;# 3# [1]A\%'#     []A\%# @    п# 1# 1# 
AfAfA tP   ~D  GAq   A   _EMD~   t1_1    A# AEH߅t;A   EH   AwAAA   ~   tfD  A]VL# McOMtAAGTQEEuAu   A
f.     AEDD	ÐA@AAG@B    ~   	fUILSHdH%(   HD$1oq	#     A8t$1HL$dH3%(     H[]D  A;ff= uϋu HL$HIÅ          A   e?# A#      G  H# IMعp   D%ÅQ# A`     ց   8  # #    X    H5# HcIMع@   H D    D(# EW          'H֗     ?4fD           Z     IA     A     A   "         4     uH3     ?HY# l@ A      t   H#         uA      y H!# o@    H     ?5    H# @ t$<$HLA      A         H     ?    Hߔ     ?DEA   tqA      d      QN`   85   '#    =      [ff.     ATIUHS H dH%(   HD$1% u!    HL$dH3%(   uOH []A\HL$HT$Ht$zT$t$I|$L#~   A$    1] D  H|$t$uu# 1H    t   D$    1D$@ HT$Ht$uËD$|$f     H|$t$u@t;(wA $=  wn
D$    : $1   t$# 1H@    tHL$HT$<0HDuǋt$|$뵸ff.     @ H(|$t$dH%(   HD$1      tt$   /  Gv?~:# 4  F# t	k  t$|$D  "# 1HL$dH3%(   r  H(    T  :# D$tJǉT$ց   |$HL$HT$   t$|$뉐t$|@ =# u6	w+_]w k^D$    
 t$=D  ǉ։T$   |$ D$      t$    Gt$|$/t$|$HL$HT$|$t$   _]k^D$    1_ t$|zUD  H|$t$u:%   =   F  H# u#       HÐuKH# J# t0   п(   # = # # H# #     멐ff   =# # H# u`D(  t=# D(     ҿ$   \# (   Q# D   F# H?# D$ҋ|$*# HD  P(  tv# P(     ҿ$    # (    # P    # H # D$랐HT$Ht$|$|$%   =   D# % D$Et-   =W  vSH# HroD     п(   V # =;" I # HB # |$#     /]AL  zk^|$)эA!D$ua#    |$@π" 5 #     rD$ ^9# # H" thO(  t9# O(     п$   |" (   q" O   f" H_" |$Ћ|$O" Lf^Anft#       п$   " =" 
" H" 뢃=Y# H" t.F#       п(   " I   " H" |$H    Hc # ~D  J # H # <@ tg
t")   # ~	 # %x"  #       #    9J  D # Et   v # tz  Db # E   U # A 	   E    t3% #     # # ;
 #  # D    1%"  u D" EX    5"     5" "     
   1%k"     A" 
   "     U
   S1H+" H[]%" ]" =R"  uA!NA>   !   A   5" A   D	" " ED" A9&V" A9   D" G" 8`D  D" E
<$" 
   D  H     `HHЃ!AE=E /    ?5:" f     A   ɀ" f.     tjEtv1?wH      H߃]EЃ߃AvcBЃ	w	"        !t"    Fރ5wH     HӃ t
tf" ATUStjL%" A<$      " tJuED-H  HcЀ< uH  < S  H" A$   ([]A\D  t{%" H~" t#	  !tt[]A\fHq" LR"  D P^@  H_  H  HcA$    4<A+ []A\%"     !  M߃]wMH5ɋ  Hc^P&#  v=<  >u;H}  &   D  H" H13@uHs}  "t1ۉ[]A\@ Hތ  []H<A\4%:" f.     H5y  HcA$    [4]A\A@ H  HcHA$    4[<]A\AD  u+\    1[    ]1A\%" fD      10H|  H|  @ tu/@~M~EZ~`~m~6z%/"      ~O&/ ~O)/@ %"     FуLD  GуLD  " H" t
%t&!tYtuy0 uqt   %   D  F߃RvxtuH" HeH9tHIH9u;0 1 N̓vPtFˉ!   C    $u3 ~.1t@ǃ$     $   f      !tWff.      F=   w vmG׃veG	v]Hn  A9"  /"  A.   L   A"   fD  D@H9D9ANANI9u%U" D  .   "   @ ff.     %" fD  %" fD  AWAVAUATUHSHHL-" L%" dH%(   HD$81AAǉD$&t.HL$8dH3%(   D  HH[]A\A]A^A_     HAՉD$#tHA    HAՉD$߃X   HD$A   E1HD$0D  vEG   IGHI	II
   HDAՉHD$OB<GЃ	wI	wHI	ÍGvwGA   E1   1@ HAHcˍPЉD	wxKHcL<BAt[AAuHcˋDPЃ	wNKHcL<Bڃ;uIu*HcfD  |HHAԅuD|$~A   r;t|0%" fD  AWAVE1AUATIUSHXL-" dH%(   HD$H1H" HD$AՉD$ %   =     fD  D$  D$         l$l$E1Hcŉl$H@H" HHl     BD E   B9D    E9ALAIcD II	uA	   HP"    CL$    D$$C   D$(A   McHl$ fD  B| IDD$LHD$EDD$EtE1IcƋD %   =   HL$HdH3%(   D$ uuHX[]A\A]A^A_@ EHT$9T$E~E1f@ D$~D$f     D$   DqkA   ()f     %" fD  5" H" V"   @<f     HR"    u@" H{  0<{" =   p" =   e" " " t0=9" ts?   @" =   5" " "     H    r" H  <<" =   " " " tD  Qtu" B   H@ USH^" H" :     B   Q   a  
X  GЃ	   ߃A   =   ҉
P7x0M7" C7{0
M%" " H[]    uSe" H-  ?<	H| | " x" r" B   H[]    ҃U" H[]fD  H  =" Hc<҃(" ""    H[]    " 0	H;  H<҉" "    " H[]D  "     ff.     fUSH" H" tu%H." ߉H" (H[]    H!" VUUU0E" )B~1Ѿ
   1"     1" H"     AWAVAUAATUSH=0" "     Q  H" ALc#E~C4H-" HcDt    Au"   AU  A
K  A u?Ay  H-" E1A<,I" @" D9E     ="   D#E~<H-L"     1@ <+A@  @
u  HA9HD[]A\A]A^A_aAD=" AuA	A 	A  A
    A  A
  E~A KA=AH" AT$F, <~    Jl H;HH9uH[]A\A]A^A_    
" Q   G  AH[]A\A]A^A_ " uH"  <?   п=   " "     "     " " H" DЃs" HfD  G~*t
t=   " 
   " 9"     A	KfE~H-T" E1A<,Ia" D9#"         A H-" fD  H" D"       EH" Al$HXHf.     H8$HH9uY    E9AIcY"     A)H\(L4(LfA>I" I9u="   FD  E)A\$E1H-@" I &     IIA</@ wIs	=" F~nIGL9uD|$fHcD$A9H(E)HD(If     ;H$L9u\f.     A
A	A   A	     F" &  DL  
   ~" H-W" "     E <       V" " Lc#AD$Fl% <=" H[]A\A]A^A_>  fD  Q  E  H-" E1D  A<,I*D9#AGMcFl= Tf
   " ^"     a   E~HE1H-z" $     <
t,." %" ID9#~$A<,i" A,<u1H-5" D  Dm    E   H-" AD$HHL(fHH9   !<]wTE1~ A<,I" " D9#   Dm Pl"     AE߃]~#H-" E1D  A<,I" D9#""         8H-H" EH-9" oH &     HAD$Fl% <qE1~#     A<,I" " D9#    lf.     AWAVAUATUSHH5" H
E  HX"    HP   f.     9  HBuH" Hcɋ=" -"   L%" H\" 1A$~H+"    	  
   п    $" H]" "    HD$    A$~,H" Hc wH &     HH҃ 9}ML-" HcA| @ w7I &     Is'Lc" D8" E9<$~C</@ vHD$     ;@t@ b" H" ;@uA$A$    9}0H" Hc̓)HlHH@ ;HH9uH[]A\A]A^A_IIRnD  H!" (HD$u6L%?" A$fD  H9" HcH΋-f.     1L%" f   H" DB   H!" H8 t) H8@    H8 @    @    @    uD"     H" /"     H   "     "     "     "     "    "     "     "     "     "     "    "     "     "     "     H"     " ?   "   "     s"   )"     "     "     "     "     "     "     "     "     "    "    "     }"     D    HH9uH%" H!  H'  "     ?"          HfH" H" H  H" H" H" H" H" H" Hp" HHJ" H3" H" H" "     "     "     "     "     u"     " B" B" 
   H" H" H" H" H" H" %"     H" "          H" "          H6h  "     "     "     "     "     H"     H<" ff.     PXH=i  (      HH" H   ff.     PX1Hff.     @ n" SHt)X" t? tH5" t
9"    H" [#"    fD  AWAVAUATUSHXdH%(   HD$H1=" uH    HW<- 
  HuE1L- i  H-)Hzd  fu:MtAu'HD$HdH3%(     HX[]A\A]A^A_@ LE1 LgW<X   IcD L>IA$-	  uLs "    "    B"     <	  1D  IDBA$JЀ	v" L=    -            L 8
  1  3  2  HHH9" <L  <BuH?0  "    f     "    LnfD  H1[2IEO    H,  LH" 2fR"     LfD  JЋ'" 	  0H	Љ" fHLHg" f.     Ѓ<@M  H" @ "    LfD  Ѓ<Bt	H)  H" w    BR  QI  N	  S  0
  L; ."    L5"    @ H(  L,"     H"      v" 
   LfD  ^"    LfD  "     LfD  JЋ" 	  H" @ "    LnfD  8[  1  3u
2  Q"    L5D  =U" L0"    8"        B  QQ  "    L@ u  m  w  0t  L@ "    LfD  ~"    L~fD  "    LffD  JЋ[" 	  HE" <@    	  D$    L-" IE1    D$    Aw<=      @8   HO   @ LT$A1t<=tLBH@8t@8A@ A   ADL$A/M:InfD  " <   L-bAD$I|$m"     PЀ	A1    HTPHЀ	v<"     1UITHGtD  IA$uMcH۟" IJ|?      LH HɅ=     H=_  L HɅ%  
   H=_  L   
   H=_  L      H=o_  L   
   H=__  L Y     H=K_  L M     H=6_  L   	   H=_  L 2  	   H= _  L      H=^  L |     H=^  L ;     H=^  L A     H=^  L      H=^  L      H=^  L      H=r^  L t  H5a^  LHT$D$-D$HT$  H5?^  LHT$D$D$HT$-  H5 ^  LHT$D$ٺD$HT$g  H5^  LH$贺H$6  H5]  LH$蕺H$  LH5]  H$vLH$!<]D$   H5" :L$@<HcD$Hx@]vLD  L" L" vLnLz" ]LU6U"   Ho"     6	  H-" LH" 	"    LGH" B   H"    Q" 
   HM6"    HO" Q   H"    "    HmD$    2F<]w;   H|$DFND$ABHc@4Ht4HDFA]vD  L|$    H=Y  L      H=Y  L      H=xY  L      H=bY  L      H=LY  L      H=6Y  L   l"    L"    FfD  "     H-"    LHTHH" S"    H0H-n" ~  6"    H"    H@"    H"    L"   H"   <L  <BHbD$    2y"     F<]w;   H|$DFND$ABHc@4Ht4HDFA]vD  L|$    H=W  L       H=oW  L h  HL%"    H2" "     "    "     H"     tR"    LbHY"   HFP"    L4HLH" "    L/"    u"    ""   HGH"    L"    3"    "    Lz"    L"    A"     L"     "     ]   H=U  L uXH,L["    H" F"     "    -"    L"    L   H=U  L u*HL"     H>" $"       H=]U  L uoHvL="    H" "     c   H='U  L uyS"    L"    "    #^   H=T  L uYHL"    Hq" "    "     H5T  LAuF"    L
   H=}T  L    H  LH" wH5XT  L	  H5MT  LѲq	  H5S  L躲Z	  H5,T  L裲C	  H5T  L茲	  H5
T  Lu	  H5S  L^   "    L"    -"    H5S  L!  H5S  L
  H5S  L  H5eS  Lܱ  H5TS  Lű   H5CS  L讱  H53S  L藱  H  L#"     H|" b"    H5R  LV  H5R  L?  H5R  L(   H5R  L   H5R  L   H5R  LtcH5R  LаtPH5R  L轰tH5R  L誰  ,"    L"    "     "    L"    "     "    L"     -"     "    La"     "    H5Q  L4  H5Q  L  H5Q  Lͯ  H5uQ  L趯   H5kQ  L蟯   H5`Q  L舯tqH5\Q  Lut^H5XQ  LbtH5RQ  LO   H`  Lw"    H4" b"    "     H  L?"    H " "     iH  L"    H" "     ?H  L"    H" "    H5P  L膮t&H5P  LstH5}P  L`u4"    LH5KP  L;uQH-8" LH5@P  LtH56P  Lu>"    L_"    fH5O  L׭udH-" LDH5O  L赭t&H5O  L袭tH5O  L菭uH"   L0"   H5}O  L`u[H-]" L("    H5O  L4tH5O  L!uE"   L"   H53O  LukHLH" XH56O  Lɬt&H5*O  L趬tH5 O  L裬ub)"   LD"   H5N  LttH5N  LauiHL)"    HJ" H5N  L.tLH5N  L"   L"   tH5<N  L  HL}"   H" =H  LH" '    "    L"    L"    `"    LH5:0"     H5-"   J߀X   D$      11A	v>DNA   @΃7|$H	DH	tDt:DVDNAw@A	   0HLH" .@t[" =U" HT$Ht$D$LD$2" uD$      1t
DNAwL$HDDH	uH3LH" D$    114
DNA	Xk
DǍD0ЍqHt$Hu=A@WHڲLH" ;HtLH" %HLH|" Hl"     Lb"    L"    L"    L"    /"    H+  L"    H" H5cK  Lu*HL"   H" "    UH53K  LƨtH5'K  L賨uH(LH" H5K  L芨u HLR"    Hs" H5J  LWu H̷L"   H@" LH5J  $LH"   H	" "    rfufD  Hc" 5" S9}H" H" [    5" H=" 5" HceH" %" HPHc" H[H" y"      HH|$Ht$)HD$HHHxHH9  1H9     փ@l  c  r@   rq@      r_@>   HqH9^  s    QDBA   DB Aj     HH9        H9   V7   P HqH9         QDBA>vDBA v z    HfD  r@vE Hqw[H9tn  $QDBA>vDBA v   HÀ~1    HHHf.        HfD  Qt1%Qt1D  H9w fD  mA?vvLƀv!Jq;LFL9htA8t1    Qs1@ 	   HfD  HNLff.     H" u'Hcp" ;f" }0P_" H`"  Hl" HfD  f.        x   (   ~P  ?		    у?%  <   ǉ	%  		    ~?%  	øf.     u    1A8D@1A/vAVAAUIATMUSV~AE     D   A$1[]A\A]A^f.     H|$t$   w`u" 1H    1      t⍇@HK  H  HI  HcH>    Gt$v\%   =   u&iD$    1   ƉD$k    HL$LD$Ut$|$@@ 2fD  '  t$1Nс    aD     t$1N?vD     t$1p/vf.        t$1Nс      D  tkt$1      ^     t$1N?=f     t#t$1`vfD  1    USH̿"    H_" Ã$   (u_=" tV" wHH/" }"     B   q"    f" (   T"    fD  B" H[]ÐH6" ," HH[]f=" t)" uH" "     @u."    ݾ" $   ˾"    f.     HM" fUSH" tT"     u:
u5" HX"       t
   H1[]fD  
   1tHމ[]%" t+
ttH1[]%" =" 
uH[]"    H[]       1H" n N" t
%4" @ b" P%  T" H]"      " St" [D  " H#" 
" %  @<[ff.     fHt?Hx" HHufD  H8HHtH;z(uHf.         1D  H=" H9=:" t8HHtH8$" u H" H
" HD      HQ" HB"    H@  H81Lf.     u
" u$9=" t=" Htݽ" uH56" ؽ" t?        HGIG&H" I9A(t	H@ 11Hs OA5  H"D  SHHcH>     F?   HcGPWt9}8LCHK     SsH舧C    C    [     ~%   =   t㍆@       HcGG   PWt[     " tH        G    HG[f.     F?w HcGSPWt[    H[        HcGG   PWt[f     H      H9CSs       wHcGG   PWt[ff.      SGHta~/   uF>  F|  [    u`" tH        G    HG[D  ~%   =   t_>   <   -  "      HcGG   PWt[@ F>vF|vH[    HcCHKPSHSts{HC    C    [    HcCHKPSHSts{跛KC    C    [ HcWHHB   Gr舤C    C    [     " *HcCC   PSt[ff.     Gte~3t~ui_]   HcGG   PWt@ uC+`" t!H        G    HGfD  cf.             _]w5HHcGIPWt{AA    AA    HfD   %   =   t_]1   %   uHcGG   PWD   ff.     fH(|$t$dH%(   HD$1uD%   =      "     P" HD$dH3%(   p  H(    tZ      ff=   D$!]1  G߃]%  K" 
   @πٳ" |$@π˳" vfD  HT$Ht$i|$u|$%   =   /% D$-   =W  w"   H" H
 "    |$@π8"  " 
      " |$@π" f" 
   " t<z"    ۲" |$f     11jft$HL$HT$车t:D$u"     |$" 0ff {t$|$HL$HT$託뭁  ]ALk^)H," !  ~+  D$ЉT$ff= u6   |$uD$T$ʀы|$@πֱ" ϔff.     @ H|$t$u,%   =     "     " H tt$n  E  ff=   F^i  G^]  HL$HT$"    4" |$tNwCL$HQH@HHcHH)HHO" BЅtT$׉D$D  " |$H7" @" |$D  HT$Ht$1|$|$%   =   % D$-   =W  w³"    H[" H v"    @΀" }D  V"    @΀" HD  11JfHL$HT$"    ǣ'|$" |$" ]AL  1   iҼ   |$)у>D@D$R" |$H" ff.     ." ;$" AVAUATUSt&P%  " H" []A\A]A^fN" H  ="     DAH" Q  BC  D%" f.     A  Hg" HAă ~  =p" 2  H9" Ã ~A?  =  "        ÑIH1  A   E1H" Ã  
B    3     Et^=uIcAD< tL<	tHDH" t0IcAT$HcIDLH)If;HH" I9uA] L~|f     ʯ"     [H]A\A]A^f     =I" "     a  H
" H" H5" H" H" Ht1H" H"     H=3  躐[]A\A]A^f.     ЉÃt݃_trC߃]  =ty?=y" D%" Hc" t=u=R"   ή" Q   H/" ]f.     =!"     E?@ D%" H " Ã3~   H߫" Hͫ" Ã ~H" Q       H" H" H" H"     ="   Hi" AŃ ~    =p" ,  H9"  ~" B   A@P  AZ:  AL$@w  Z  S?AA@<  AZ  AU@~  Z  pD	=  =خ" Lݮ" AD_A  D" CA=tRDɃ?DWA  AD" AD	C=t!Ѓ?A  =i" 	C^" P%  P" A A@ =	" ."     	*IcA\ A\$E9~ELAvHc蟍H  IAD%8" =" uH" H
  Ѓ   _  H" H" t p  	g  HH
   T" E     {H" M 1" Q   SЃ	  S  SXЃ	vHXɃvH1ۃwX   D%?" ^IHA   E1H" Ã  
   ~    tvE=uIcAD< <	DHO" IcAT$HcIDLH)I;HH" I9u	uIcA\ A\$E9~ELAvHc袋H  IA%Ѓt    	   H" E&H" H
c  Ѓ  
  H|" t   	  HR" H
   D" E      H    D " @K1҃SH    DAL$A/1A+>AUA/1A+>S/1҃+>yH" E6   p/1+@ƃ>qH    L" AU@DApEЃt
 tȃ	tH" ESAL$E#fLH=,  襉H" Ey.EI#f     AWE1AVA   AUAATUSHL%" Lf.     E1HH; t,HC Hk8HtDHЋUЅuMuI@ EtMt
" tTA~5H[]A\A]A^A_    AD$    I8AD$    AD$    I<$ uH[]A\A]A^A_ Iw(H   []A\A]A^A_@ SH" =      ~E=      =      Hv" =      HމX" H޿   [%I" uLHC"    H2" =     =   T  Hމ	" H1" @ Hމ[%" @ H" =   4  Hމɣ" H޿   [%" fH" =      Hމ" H޿   [%" fHމ}" H1[%q" f     Hg"   HV" N  ,"   HH9z" <  H1" H1" "   HH9B"   H޿   ޢ" Hע" =      Hމ" H޿   " fD  H" u[H" z  5h" $  H՜H9"    H1U" H1J" Hމ=" *Hމ-" "    H H9a" 3  H޿   " /=ޥ" U  H+H9," tVH޿   ̡"     H" =   -  Hމ" H޿   " " T  [f.     Hw" =      HމY" H޿   K" =fD  H5!   *fH5	   f.     Hމ" Hމ" "   [@ "   [@ D" E   HH9" tH޿   " <H5   lDd" EteHԚH9" thH޿   U" H5   'H5   H5   VH5o   " _  [    AWLGAVAUATUSHxL," dH%(   HD$h1"  "     "     L" "     @ƃ	@=  		ʈT$!" " H0IDD!" HV" EtH°H" H<" A  D5" EtHg" HHY" H2" D-" EtH?" HH1" H" D%" EtH" H H	" H" -" tH" HH" H" " t&H˞" H"     H" H" 6" L" tH" HpH" Hr" D" LHML" H" Et*H  L" H" HΧHǟ" H؝" D" Et8H͝" H6  H" HH" H" H" Hl" DM" Et8H" HH{" HTH5" H^" HW" H" D" Et	@k  ==" t=
"   " t8H" HH" HgH" H" H" HӜ" t	@	  =" t
" " HXH" 	  H:" H8 t*@ H8@    H8 @    @    @    u11D$    HZ" f.     1ЉÃtu#" g     ="    u=b"    9H  " `" F  ?  H" 11ЉÃuf     11	" W" u|$ L  Ht$hdH34%(        Hx[]A\A]A^A_@ H" HRH9  HH9  %   =   g  =$"    u=z"    9  
" -"   <  =j"    fD  D(        uZT$މ" c  u1" AăR  f.     D$    H" 19f     uc5" t!EwS߃]wk^1퍜 D  މ" H?" D$    D  O(  tP(  u   `" H	" D$    l߃NS     13"  =F" D  )@  ="   ~[tV-"   -R" J
  C?   D5/" Et=W" U	  ="    UD         |$ t|"   1" Ã-$
  (1" ÃIO  Bt	H   "     @ "     H" Jf.     1H" ="   w  ЉŃ({1S" Aă7  1?" D$	  D$=" A	Dd$(     `?wHH9t?H"      HH9
  1ЉÉ!`?D=s" Et="   ="    fD  1x" Aă\  1d" AŃ  1P" D$#  I" =_  x
  H  =T  ?
  =  &
  AA=q" AA   	D	 =V" D(  u  H" jf.     L%ٞ" @-Ҟ" "    Þ" N1	  Hc"     BAP" j"   =     uF1:" Ãu" u'z  H" fD  Hr(   " E1f     A9   IcEoH!" A,   H5}H9  A9   McA1҉G4,Dу   u'D;="   IcAE,DD" r" A9rc{ 1҉1EыG" Bf1(" AƃtǉEv1HU" Dуi" D921" AŃ7" A9h       A    _>1҉   E|" D  1x" AŃ1X" Aă1=" AŃADD	    =v" DfЉŃ  (w/1" D$  d$1Ɠ"   	D$=" ݉     |$ D" E=" }Hf"    @ Dމ" H=" D$      x  |$ 	  =  Y  =" 
  HUۖ" H," @ ;-fD  =D-" ED%" E1" Ã  ?  =" *
  -|" L-" A   %  AD =EY" E%  AD ?1?" =" J  ." AD -  _  AAuH " HH9t]H" Hޑ" H5ߟ=ؐ" H" H" H5" u*H" H3H" HeH^" Hg" D" E  -" Hq" 1f.     1X" ǉD$AD$DD	t" 6" 1|$   Dr" E  
  ɔ"   -Ŕ" 
    -6"   1"    (  
G  1" H" t	 
  1ǻ   ҿ
   1j" =ؒ" w    H" H8Ht HfD  p9rHLH8H: uH8\{    =" D =v"  .   "   @" H" =    DA=8" AŁ   	\$	" H4" H8 uH    Hx  t
J9HHLH8H8 uX     =Ƒ" Éa"    H?" f.     ="    08-v"   1" 1 q  " 
W@ Hю" HHÎ" HH" H" H" H" XH" H]H" HHP" Hi" Hb" H3" 2H7Lh" H" =" G1%" ="    -1" Ã:@   (  "      11)" $   1" 1" H" f=" =" t
" HH΍" p" H\uH9   =ɏ" 1f1   A" 3" 4   =" t
	" HuHS" " O     =V" DE=A" A	܋\$   D	E="    A	݋\$D	1" Ã$)  1n" @vAbȺ$I
)Ѝ    ))H  Hc D$PZ41J" 1" u     B"     11=3" =(" 1   H5I11"  ?q  =" ý   =   11" 1Q" HR" 1   1" =" C " h   11g" 1(   Z" =p" 1" Ã@  DI  O   P     1" $   1" (   1" 1" H" 81    s" Ht" H $     HH߃A7PЃ	+Ã=  H," ?#1ЉË" P%  A\ H" " Ai  ڃ߃BC  6" B   1ЉËʍ" P%  A\ H" " A  ?D  HY"     H9Ћ"    =P" t
D" H-H" 0" X"    H"" "     1" 1   L" =b" HJH+" H=3  9"    +"     =h" H" H"    HI  H81lH" 0"    Ho" ͊"    HQ" H" "     HH=   ?   HD${ HSE  E1AHl$IA   1" BD   PHA7C9   IAN<+A? wABD+HD" 1" J4H" H" }J<kHt`߃=" B  Hw" H@H9t]Hd" HU" H5V=O" H " H" H52" u*H" HH" HHՆ" Hކ" ܊"    A*H5" DIcDXEFEDGLLH     I1McHtRItEK8Nu2       H:LuHcH9uD9u	D9tHIA몹   A1H]J" AEL$Hu 1H" L9u(HF1=   " H" H-" H9DV" E  -" 11    (0" P(  H" "     ^" O(  H" "     >" D(  H}" ۇ"     -\" -:" H" L-\" JJ" 9" 7" t!H  AT5 u" D%" 1` + "   t`=u	?  +t=t߃AvHЃ	w)J  É" AD 1" " u"    J  AD Hq" H:d" b" H9HF" H5G=@" H" H2" H" H5" u*H" HH" HH" Hȃ" H=   13" E1E1A   f  H" D%" AD =HwH9IIQ" Q   HJH9}=΅"  t1-f" "    1HH9H>"    X     HHt$~H|$g"     *fHD$=" HPH@HO" =" u=" " \"    M" 	   B"     uH"    : u	H@    H=  Hָ    t׹   H=1  Hָ    t
   H=	  Hָ    t   H=l  Hָ    s   H=r  H HHHAWAVIAUAHATIUHSH҉D9   HADxAōPA	v<v7@wHAAč@AL$	vv
AT$wjA]9T$HAԋT$Ač@Ѓ	AL$vD߃Aw4A	wFD	w[	H[]A\A]A^A_HDAD  HDAHDA@ Auq1ۃwA] AD$wA7D	D  wAWD	fHU" HV" H%   dHE" HF" H:   dATUSH  dH%(   H$  1taH_1111I.fD  <'   Hc<t*      Huԅt@Hc41uօ   1H$  dH3<%(      H  []A\Ð<\t,t8<"tdHcʃ    1zf        e@ <'t<"t`< tjHcʉCf   5@ 1(    RfD  HcH 聞6@    HcL [
1aH(Ht$H$H|$aHD$Hx1aHێ"     "     aH$1HPH@t@
Hˎ" Hc" Mb=B}" "     HPH" HD$H@H" w"  u=ׁ" |" HE" HcN" HH HPu&HtH$uHtH   H	H( SH=  a   HH5l  HHAaH߹   HbH5O  &a   HH7H5;  aH/  H5/  H`HaH  H5  H`Hߺ   H5   SaHߺ   H5  ?aHߺ   H5  +aHߺ   H5  aHߺ	   H5  aHߺ	   H5  `Hߺ   H5  `Hߺ   H5  `Hߺ   H5  `Hߺ   H5s  `   H5h  H`H=a  o_H5r  HHm`H=V  Q_H5P  HHO`H=J  3_HH5F  [H0`HH   0123456789ABCDEF &gt; &quot; &lt; &amp; ic= ISO-2022-JP X-ISO2022JP-CP932 CP50220 CP50221 CP50222 ISO-2022-JP-1 ISO-2022-JP-3 SHIFT_JIS WINDOWS-31J CSWINDOWS31J MS932 EUCJP EUC-JP CP51932 EUC-JP-MS EUCJP-MS EUCJPMS EUC-JP-ASCII EUCJP-ASCII SHIFT_JISX0213 SHIFT_JIS-2004 EUC-JISX0213 EUC-JIS-2004 UTF-8 UTF-8N UTF-8-BOM UTF8-MAC UTF-8-MAC UTF-16 UTF-16BE UTF-16BE-BOM UTF-16LE UTF-16LE-BOM UTF-32 UTF-32BE UTF-32BE-BOM UTF-32LE UTF-32LE-BOM oc= cap-input url-input numchar-input no-output debug no-cp932 cp932inv x0212 no-cp932ext no-best-fit-chars fb-skip fb-html fb-xml fb-java fb-perl fb-subchar fb-subchar= ms-ucs-map utf8mac-input prefix= %s
 can't malloc can't realloc Shift_JIS NKF nkf guess1 guess2 guess AUTO EUC SJIS BINARY NOCONV UTF8 UTF16 UTF32 UNKNOWN 2.0.8 (2008-11-08) 2.0.8 NKF_VERSION 2008-11-08 NKF_RELEASE_DATE =?EUC-JP?B? =?SHIFT_JIS?B? =?ISO-8859-1?Q? =?ISO-8859-1?B? =?ISO-2022-JP?B? =?ISO-2022-JP?Q? =?UTF-8?B? =?UTF-8?Q? =?US-ASCII?Q? base64 jMB euc euc-input fj jm help mac sLm mime jM mime-input msdos sLw sjis sjis-input unix eLu version windows h1 katakana h2 katakana-hiragana h3 utf8 utf16 w16 utf8-input W utf16-input W16        nkf internal module connection failure.
                dhpP8x`8 șzȘpH0x`ܷ\4ܶTԼ                /"  9"  B"  I"  Q"  ["  k"  q"  z"  }"  !#  /#  :#  @#  [#  `#  {#  ~#  t$  ~$  w%  ~%  9&  @&  Y&  ~&  B'  P'  r'  ~'  A(  ~(  TO  ~O  %t  ~t                                                                                                                                                                                        !   !   (   )   )   )   *   +   +   +   2   2   2   2   <   <   F   F                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/                                B   B   Q   B   B   Q   B   Q   Q                               
                                                                                                     @                                                                ,. :;?!  '` ^ _          - /\  |  `'""()  []{}<>        +-   = <>           $  %#&*@                                                                                            %Q%T%W%Z%]                                                                                                        %t    %,%.%0%2%4%6%8%:%<%>%@%B%E%G%I          %P%S%V%Y%\                                                                  !!!#!V!W!"!&%r%!%#%%%'%)%c%e%g%C!<%"%$%&%(%*%+%-%/%1%3%5%7%9%;%=%?%A%D%F%H%J%K%L%M%N%O%R%U%X%[%^%_%`%a%b%d%f%h%i%j%k%l%m%o%s!+!,                                LMNOPQRSVWXYZbj|CDPX^npru|}~BIK                                                                                                                                                                        @ABCDEFGHIJK                                                                                                              J                                                                                            F                                                                                                                                                                        HG                                                                                                  A                          C                    D      E                                                                                                                                                                                                  @                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    e                                  ^                                                                                                                                                                                _                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ]                                                                  `                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  x                        y            z      {                                                                                        sq              t                                                                                            v                                                                              o                                                                                                                                                  e          g  ih      j                              k                          l                m                                                                                                        ]                                                      _                                                      `      a      d  b      c        f                                                  Y                  Z                                                                                                  [  \                                        M        N  O                                                        Q                R                              T          S                    VW            U                                        J                                                                                                      K                                    L                                                                                            @      A                  B                        E        H    F  I                      G                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          d                        c                              f                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                g                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        w                                                                    {                                              }                                                                                    ~                                                  p      o  r    q                            a    s                  v                            wu            t  z  x                                y                                        h                                                            i                  k  l                            m                    n                                                                  C    P    `                      U                                                                                                                          stuvwxyz{|}~!"#$%&'(L"C)*+,-h"c_ix!;.-|P?t)H/RTcn'#,)>_XHWcta#0;f  mu|15X[en{23@GP^4*5/Dh6Bdhg789Nauwx|/7>[*a:k38;J<=P^tuydm~>Bg?p0,@3=MId(IDdt&Au|Bx+!%C8:DDRW[^mpE!5I9FX~GLHYj}I'56JU8W`jc!+GCKOYKLfn|kp1ex&+-MJSic|tuN3=oq.OJfjptn%y+.-2BPYP;Q;R:CSr]UbimTUV  WeXihYZl;[ah'\]Tr.^^_"7AQtFHQ`abcdSHTjz$0e5Kf9gChiYjkblmnG(&)/0*+<A?UXV_caTi&qrKAC>o@G?`^Qp\R[Tzo3?IPbjkqrsho,t.u1v216wx]yzQ{mM|[fj%{z}V~                                                                                                                                                                                                                                                                                                                                                                                    \]^_`abcdefghijklmnopqrstuvwxyz{|}~  @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~  @ABCDEFGHIJK    @ABCDEFGHIʁUVW            TUVWXYZ[\]ʁ@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ab  cdefghijklmnopqrstuvwxyz{|}~@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ab  cdefghijklmnopqrstuvwxyz{|}~                                                                                                                                                                                                                                                                                                                                                                                              ;                                             A                                           A                                           A                                          A                                        A                                        A                                        A                                         A                                           A                                           A                                          A                                        A                                        A                                        A                                         A                                         A                                           A                                        A                                           A                                           A                                         A                                           A                                           A                                          A                                          A                                        A                                        A                                           A                                          B                                          B                                          B                                           C                                           C                                           C                                           C                                           C                                          C                                        D                                           D                                          D                                          D                                          D                                          D                                           E                                           E                                           E                                          E                                        E                                        E                                        E                                        E                                           E                                          E                                        E                                         E                                           E                                           E                                          E                                           E                                           E                                           E                                          E                                          E                                        E                                         E                                          E                                          E                                          F                                           G                                           G                                          G                                           G                                           G                                           G                                           G                                           H                                          H                                          H                                          H                                          H                                          H                                           I                                           I                                           I                                           I                                           I                                           I                                           I                                           I                                          I                                        I                                           I                                           I                                           I                                          I                                           I                                          I                                           J                                          K                                           K                                          K                                           K                                          K                                           L                                           L                                          L                                          L                                         L                                          L                                          L                                          M                                          M                                          M                                           N                                           N                                          N                                           N                                          N                                           N                                          N                                          N                                           O                                           O                                           O                                          O                                        O                                        O                                        O                                         O                                          O                                        O                                         O                                          O                                        O                                         O                                           O                                          O                                           O                                           O                                           O                                           O                                           O                                          O                                        O                                        O                                        O                                        O                                        O                                          O                                         O                                           O                                        P                                          P                                           R                                          R                                           R                                           R                                           R                                          R                                          R                                         R                                          R                                           S                                          S                                         S                                          S                                           S                                          S                                        S                                          S                                         S                                          T                                           T                                          T                                           T                                          T                                          T                                           U                                           U                                           U                                           U                                          U                                         U                                          U                                         U                                           U                                           U                                         U                                         U                                         U                                        U                                           U                                           U                                           U                                           U                                           U                                           U                                          U                                        U                                        U                                        U                                        U                                        U                                          U                                           U                                          U                                          U                                          V                                          V                                          W                                          W                                           W                                          W                                          W                                          W                                          X                                          X                                          Y                                           Y                                           Y                                          Y                                          Y                                           Y                                          Y                                          Y                                           Z                                          Z                                           Z                                           Z                                          Z                                          Z                                          `                                             a                                           a                                           a                                          a                                        a                                        a                                        a                                         a                                           a                                           a                                          a                                        a                                        a                                        a                                         a                                         a                                           a                                        a                                           a                                           a                                         a                                           a                                           a                                          a                                          a                                        a                                        a                                           a                                          b                                          b                                          b                                           c                                           c                                           c                                           c                                           c                                          c                                        d                                           d                                          d                                          d                                          d                                          d                                           e                                           e                                           e                                          e                                        e                                        e                                        e                                        e                                           e                                          e                                        e                                         e                                           e                                           e                                          e                                           e                                           e                                           e                                          e                                          e                                        e                                         e                                          e                                          e                                          f                                           g                                           g                                          g                                           g                                           g                                           g                                           g                                           h                                          h                                          h                                          h                                          h                                          h                                          h                                           i                                           i                                           i                                           i                                           i                                           i                                           i                                          i                                        i                                           i                                           i                                           i                                          i                                           i                                          i                                           j                                           j                                          k                                           k                                          k                                           k                                          k                                           l                                           l                                          l                                          l                                         l                                          l                                          l                                          m                                          m                                          m                                           n                                           n                                          n                                           n                                          n                                           n                                          n                                          n                                           o                                           o                                           o                                          o                                        o                                        o                                        o                                         o                                          o                                        o                                         o                                          o                                        o                                         o                                           o                                          o                                           o                                           o                                           o                                           o                                           o                                          o                                        o                                        o                                        o                                        o                                        o                                          o                                         o                                           o                                        p                                          p                                           r                                          r                                           r                                           r                                           r                                          r                                          r                                         r                                          r                                           s                                          s                                         s                                          s                                           s                                          s                                        s                                          s                                         s                                          t                                          t                                           t                                          t                                           t                                          t                                          t                                           u                                           u                                           u                                           u                                          u                                         u                                          u                                         u                                           u                                           u                                         u                                         u                                         u                                        u                                           u                                           u                                           u                                           u                                           u                                           u                                          u                                        u                                        u                                        u                                        u                                        u                                          u                                           u                                          u                                          u                                          v                                          v                                          w                                          w                                           w                                          w                                          w                                          w                                          w                                          x                                          x                                          y                                           y                                           y                                          y                                          y                                           y                                          y                                          y                                          y                                           z                                          z                                           z                                           z                                          z                                          z                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      q!r!L"1!Co!                                                    @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_                                                                .!a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#t#u#v#w#x#y#z#P!C!Q!A!    !"#$%&'()*+,-./0123456789:;<=>?.!a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#t#u#v#w#x#y#z#P!C!Q!7    !"#$%&'()*+,-./0123456789:;<=>?  *!*t!p!s!u!)J!K!v!\!$!]!%!?!0#1#2#3#4#5#6#7#8#9#'!(!c!a!d!)!w!A#B#C#D#E#F#G#H#I#J#K#L#M#N#O#P#Q#R#S#T#U#V#W#X#Y#Z#N!@!O!0!2!                            478=DGHNOSUVWXZ[^`bceijkmopswxy}                                                                                            r                                                                                                                                                        E                                                                      6N  XYZ[  \|s]^        }sTc_  ~s`ab  c                                                      ?  @ABCD    ns7c    Zlmp    osEpsFGHI  J    KLrssstspNqs    usvsMNxs  wsOPQRSzsT  U{sys    V    W        #$      gshs%        $E&'()]8*js+,  -./      0MAks1      2      34ls    5  67  8    9  :;!I<=ms>        +2  q  r    sTsP5UsVsWs~u9  Xst    T`[L  cBYs[sZsu\s      v]s  w^s      xyz_s{|}  `s~asbs!cs  dsesfs  "\Fs]^_`  aGs    HsIs  bc  LsJs<O  KsdoNe    f  Msg[N        hNs~G  iOsQs  jRsklm    nop    Psm9MLcKwV  `]{K                                                                                                          Cs    48DsYZ[Es  /<    N        O    M      P  QRS    TU    V@sAsWXBs                                                                    2s8s81s  6s9  :;        7s      :s<=>?  9s@      ABC        D<sE  F  G  =sH>sI  IOJK      ;skBm:    ?sL        #$  %)s  (s&    '(\7    )*  +,-.  -s            /    .s        /s0*s1  2tr  30s  aD4    4s55s3s6    7  zrnowrl}rp~r  q          %s$s  rs        &s    -1!s"stt99Lvu#sw      xyz2K    +s{  's      |}    ,s~!  "      ^pr    qr>Fnrmr  ]    *2    _yr    xr  `a    u1bcdvr      ur    sr  {3  rr2<)2    ef  ghi          jc9km|r{r                                                                          ;DYjr  7H  orkr      lr  Z1KDL  PF[  \              <  =>?crar-C@A      BCD  pKEF  GZNH  erIPJKLfr    M      grRNOQ    S  T  U    VhrWir    X        %  &  Zr  Vr  WrSrYr'Urb3  (LO)XrTrRrQr*  +,-\r.  /    _r01^r]r23456    II[rs0`r7br    89:  o3Mr71  ;dr  Arn        Dropq8Br      qErrFrGr  Kr  *;st    dB  u  v  LrIrHrJrw  x_7  yz      {PrOrNr|  30  }~!"    #  $R    9rSTUV  WXY  Z>0[\:r+J8r]  ;r<r    ^    _`=r>r          ab?rcnK-;dz:/A  efg  @r    hiCr  jk  lm  !32:1r0r%L    :    ;<3r4r2r  5r    bK=>?6r  {5@    A    B  C  DE  F  GHIJK%O    |L7rM  NOP          Q{|}~!""r  #$  %&'(  )  *      +  #r,$r-.    %r/  &r'r  (r0)r*r+r,r1  2-r.r  5]/r345  6  78xd459    oqb  cq?  d  e          fpqgqqhrqsqijkb9{  lm  tquqn  vqwqopxqq  r1Hzqs&I{qyq  }qtu|qv  ~q  wx!r  y  z                                                                                |9  V  WlqXYmq  Z  [\]  <3^  _nq  `a^qL]q_qM\q  K    NOPbqQ    R    SaqTdq    C6cq  U  eq    fq  hqgq      iqkqjq                                          Uq789Wq          :;  35Vq<={A38    >    Yq        ?  @  ABC    DMB    Zq  EF  -F    G  HI[qJ          `q    }G  %LBX1n6  o6&            sCNqp6'(o2    Mq)*Kq+Lq,Jq    Xq        -    ./0OqPq  1QqRq  23    Tq4  Sq  56Y=                                            s<DqEqa9  w  xzy          Fqz  >3      OGGqHq  {|}ZCkF~      !"  Iq#  $hi;q    =qjkl<q  ?qBqmn  >q@qAq  oCq  B6pq  rs  tuv                                                                  P-q  _L  QR.q\M  B1      A;S/qn20qTUV1q  WXY3q4qZ6q2q[  5q  \][4    ^7q  8q    _`abc      defg9q:q      D)q(qE*q  F      G                            tHLf    )?  H25I  JKL  +qM,q  ,R;]SH    {0N;0  O          t;0K~>                                                                                  wI  $q:  ;<%q=&q    >  'q?@  AB      C        *  yp+    ,{pjB[3\3zp  -./i42801j423?E    `N      45  67\8    8|p9    }p~p!q  #q"q                        GJ:D":  `9g=s\?  t  spvwrpBMh4RH\Fx  y|?NNu[7  z  {  |vp  }up(~        !KK,F"#$  %&P1'  wptp    QIjMxp)    X  gpYZhp[ip\]jp^_`  ab  Z4c    def  jkpgh  ik    l                lp#Gm  nnp;2oqppppq  r$1      A6B[p    s3Yp]p    C  ^p  H0  _p`p        DEFd>GH  ap  IJG5  Kdp    cp  bp    qkL\JM    NOepfpPQ  RST  U  VW  -Np.Kp  Lp  MpOp/    u01  vD@    2wL34E@56Pp  sH  QpSsLL7Rp  Sp8TpW39Vp  Y?:    Wp  ;$7  <=>Xp\p?Zp@  A{<  ~!<p"=pL?>p#nN    9p@pBp  Ap  ?p    Cp    Dp$%zA&b2    '()Ep    8L*  Fp          Gp+*O,        1[Hp  t  IpJp  }?g4    :Mm28=[8  5pr4ps;6p3p    (;s    :p-j  uVRvw?8pwxy    %NqF        +1zc@6<      {7J|@1      mNkM  ;p}EE          `abcy64N  (7dbB!g  &p,3o?  e    V3(pf)p'pd7g]:c>h  i#1    YNjkl+p.nm*p      no.p,p-pp/p  0plN1p2pqI@;H      KBSxo  mI            {oyo_9  zoB8  T  U  VWX    EJ}o!p~o"p  Y!1X?|=Y4#p      fG  %p  Z  "1  $pDD[MN+F|o&N  18\][M^_                                                        lIDE    toF  GHI  uo  e:  J  vowo  KIKL      MNOPKAQR  $0      jo    4G056ho7loko    89:;nomooo  .F<=  po>?@Aqoso  BroC                                                  gL  Yo.A"    Zo#DJ[o+3$%&<1  W4qV4\o  ]o  ^o_o      '()`o*X4U3^96H+boao,  -.co        \1  /  0    fo1eodo2go3                                                                                                              9D}~        !    Wo  |{                                                                                                                        Go  iIoj    k  l  m        U4HozL  n      oToJop  MoqKorLos        t  Nou  vwxPoyz    Qo  Ro        UoSoVoXo  TU?oV    @oWX      YZ[Ao    >o=o\]^b>*F<o        _  Eo                  Co    `a  bcdeDoBo  xB  Fof  h  g  <  7o=>?@:oABCDE    9o-E  F    2o3o6oG    H8oIJ  @6K  ;o5oLM4o                            OPNQR  S    $%&          '  ()y3*  +    ,  0o-?:yA.  JD/    0    1  23  4;35;  6.o/oCD  -o      789    1o:                  }n    hij  iF  UE    klm  WDn,oop  qCC(o  r  )o      st  u  vw  -7x+oyz{  |}08~      !  *o"a>#S  T      ,;  U        V  {nm?W    XY    n?!o#o  Z[\]{>^"o$o_`S6aEIbcb<#O  ~nx:    ?Ode&ofg    %o'o        2345  6789    :;<=wn>  /K?  @  ABC    DE  FGH  I{=J  KLzn_J  MT1N  O  FIrC        x5P|nQ]9    Rd6    F=  <F    xyz    {|    -A}tn  nnsn~CL!8Dunrn    "#      $%  &'    (  ,A  )    *      +yn,xn-./0  1X  YZ4Ejn[\mnkn]pn  ^_`qna          inbcvnt1dehn  fg-H  lnh`>ijk        lmn[9      opqrs  tuvHKw89    :;<=  >?  @_FC3  AgnBCdnfnD  E      FGbn        HIJK  LOo    en  MNO    PkNQRZ8STU  V  WonVnWn!"  #PHS:a<Xn  Yn$NE=nLLNZnb6  $%  [n&#E'(^nx3K?)\n  ]n  `D*+UK|6  ,-  ./0123      `nan4  5  6_n7  cn  dNne  fgf=  MnhLn  iBi  o8jC@klm  0Hn      9=  o    pOn  _>  q  r  RnPnstuQnvwxyTnSnz  z>  Un{|}  ~      S      TUSFDn6=`<[GqCV    r<Wl?  EnXFnYZ[          \]?Gn]Hn  ^  InoM  7=_        KnJn`Z9  s9@;abc        5  ?n  678  9        :    ;  @n  <n=>?An@  A  B  C  EF  D  G  H      "EIJCnKBn  L  MN  OP  QR      j0  ~!"  #$  Y9  |  :O      -    %  &'(  >n)*l+  47;n  <n,    tI    /  T3  01      29M.?6          TE343n2n0ndcT4g  nmh5n4nij  k6nl8M      m  nop  q        rstaF  u.K  7n  Y<        8nv9nwxy:nz  !E        {}    [Fk?[\YC  x6  &n7M?1]WJa2!n"n#n$n;F#Cc0(n  )n#t  ^=B_*n  s1LA`/8  ZMab+n,E    cxAW<,nd  /n  ee=-n+A*Afd0  KN1n  rH`BwAK(FLpmU5  M    ymNvm%n)F`Csm  ~DSEtmxm`?OgGLDP  B@wm.B$Bum)0"O      zmQRT  UVaBS  5=J?WX|m{mYo0}m    /I  'nZ78*1  xKW?9      :;  <^7  =a6>?VJ@        im          A  kmBCjm`2  DvFlmwG  3EEmmR=F    omGHBL~mqmrmI  IDJ                                                        I?cm--<dm./  em012!R~Q        fmpegm$C+?@G    34hm5  UJTD~9  6)C}~Xm!m3Wm\m"  [m    Zm2E]m#  $%&'(  ^m)      _m*+l9  %7`mambm,                                                    e  fS3  Jm  gh\:Im  Rm    ij  LmNmeJKmklmMm  QmOm15nPmop  q  rSmstZGXN  uvw4=      Tmxyz{"MVm|Um    YmAMTU  VW@m=mXAm  V<Bm0537  Y  Z.8  [            Cm\    pF    >EDm        ]    Gm  d^  _`          a4<bcFmEmZ7Hm    /mAB2m1m  0m  C4m3m  vL    D6mE5m7mF      8mGH  IJ    :mK        L  M9mH?;mNOm6<m>m  P  Q        RS    ?m  +,zl  }D    !m%m"m~l-#m./0$m      1+m      &m  2345X@(m67*m'm        8    9:  ;<=-m  3=  ,m    >?@.m        t    uvw  sltlYMx      'Fxly    z  {            vlwlyl|}~!    "#    )m          |l$  %}l{l&'()      *    ^  el    _`ab  cmlkl  dhl  e    fgjlh  iilll  w5  pl  W@  qljk  lY8  nlolm    )Onpq7Dr)A            rls  ul  clK  L6D    M  [1    N    OP      Q      dl        RST    q<    U  v?    VW    X    Y-B  Z  [  \gl]o  fl                                                                          V@FO<_l  G  R3H`lI  vAal  blkI  h/5              J  @  ASlTl  Vl#BBUlf4  Xl  WlYl  C[l]l  ^lD      E                                                                        l2Ll(OBDEO,-q;Kl.1B/  \l(A0  xF  PI  21    3Ol?;r;4^>  eG5-8NlMl  jI  6  A<  7RE  89  :  g;  <=  QlRlX9Pl>?    :l    <l~!  ;l=l"FK>l?l  #  $%@l      Bl&  '(-3gD  iIb:W9  )    OI_2NHElS4U@DlIlyCcL  GlHl.5  JlcG_B*+qH=EFl  GK  /l      f&Fg1lh-Ki2l  3lj4lk  lm5l  norZFp  q      ]>6lst  u  vwk9.P7lx          y  z{  8l?I9l|Al  }                                                                                                                +Cbc.l    de0l&lW  >;XY        NZZ'l[(l\2=  )l*l]^+l    ,l-l  _  `a                                                                  vkDEFGH  Izk    wkNykxk    JKL  {k  1<M}k|khI  O!l      P    Y7        ~k"lQ  #lD5Afy>  $l  Rn8ST    U%lVfEKZ1b0  %F89ik    ?:hk  fF  mk;    bk  lknk  ,8jkV9<U<=>okXM        rk  uk    sk5I@    A    pk      B  `6    C  tk      [k%Yk  &LC'()A@R4Zk  [?  *JN+,-@O.    \kgk5D/fk0ckkkdk  `k  |D_k      ]k1!Mp;  2ak  ^k345ekt=  A8  6  zB7o  PkpQkOkqX8  @M  ro;'G  stTku@@  BCvw6MxWk      l8y?@Sk  Xkm8UkVkzRk{    b@IF|}/C  ]2~    !"  pH  #C5  $4DWFk  X  YIkZJk[      \]  >:BBHk^[>>I_`a    Gkbcl;  S1dNkX7  en;f  m;  MOMkLk'A  M5CO:3\>  ghi  jklKk  mn@8  {D>kCD  EW7  V?  Ak  $FF@kGH17IJ?kwB-5    Bk  CkKY>L  Mm7NDkO      ,KPQ_@  R  v5  uLJASEkT    G?pCZ>UV  7k                                  Q3  45678  8k  9k:k          r2  9(?;k  :  ;  <      =  ><k  ?  =k@      A  B  WM  )k    $JFG*k$+k+8  %  ,5&    ,k'(k;AG-k  P3)*    +,.k      -0kwM  /kF?  1k    2k.  3kQ4/012    4k  35k  6kkvjlqjwjmn    o    {j7p  p    q      (2r    stu  ~j_6}jvwx"k  !k      $ky  #kz%k{  1=|&k}  'k    ~!"#(k>@  Uhj  mj  V#J    oj  njWXYl3  +Kpj  Z[  \]^  _|jrj  `        sjabc  tjuj        def    gyj  zjhixj    j  D[:vNajbjuA        EFGHI"N  JKLcj5M    djej  MdJfjN@:  #N          Okj            PQRljX>jjS  TgMgj    ij=@~?  8OjVj          67    ^B  \j        Xj      5BWj9Zj:;<  Qj=>  [j  ]j      ?  @oH    Yj  ^j`j    S8Tj  A0    A    BC_jl7#Ij$Hj%0=  &'()T9'^*    +JjQ=  ,-93.Kj/R10W>Lj12U9Mja03      =I4  Nj        j?5Uj    Rj  oC  6  7  SjPj^6  h  i  $jjd  klm  8j<j7jn>jpqr@j?j  sotuv  wx  BjAjZi      Fjy        z{  |Cj}    ~Dj    Ej!Gj"      +jR    /j  2j1jSTU)j    V  ,j  =j    WX    YZ  [    \6j  ]^_          `a  b  4j  c5jd    :j;je*3fB5    9jg    'j89:;<=>  ?@;M    A    B  C  DEF        G&jH  %jI      J      .jKLM(j  N  0j  O        fM3j  *jPQ+    ,  -      f@  9Oxi.yi        !j  *?  {i/~i      0  viui1  "j23\2  |i  #j      }i4  56  zi  3D  wi    7      hGfi  *Kgiqrdiseijimit  kiuvwiicixy      XCzti  *L  {|  }  ~  ri    !si        "#  $%  ni    pi  &'qi()*oi_`  aVibWiX<  Yi  AC  V7B3    cd  \ie  f  ?3gaih  ]i`ii    j:Hk  l  ^i    _iHIZHbi                }Blinhiopk2                  m  c2RiSiL      M  Ni  =;N  O  P  Q        R  OiBG  STUPiQi[i  V  UiXiW  XYZTi[\]          ^6f7      8            HiW8  T5  9:Ji]Q;<=>u5  :N?s6Ki@ABCD    Li  E  nCF    G  Mi      HIJ  zFK:0        "  "i  #$CiIA    >i@i  %&  '()?i    1]"]*+Ei,    -    .Di        /  0      vM  <bFi          1  2  3  45  Gi  NOo        p  4iqr  uMs6i8i        9i    u  v  <i:i  wx      #F;iy  zMH.i    {          |    }s=  =iBitA~  Ai!%iX    vGYZ/i'i[)i\]    ^3i(i  _,i    r1`eF  -i0ia  bc  d  &ie&Af*i';E?07tLtyLr=a      g  hij7i5i  klmn{h!i  YH    A  ~hV>I<#i    >6BCDEF  $iGyI}hHVh  IJKLMNO|hP      OO"FsIQ  +i  R              1i  STU  V2iWC<  -.    Qh/        0  1  2NJ  "Lyhxh  thuh  61  3  4wh  qh5678UD9    :;vh~0  <    )=>"B?            CJ  @xmhy  _C  nhz{VMch83|ih  }lh,L  ~    oh    hhkh  !                    "    #  )K  !O$%&'  sh    (    *+zh,  rh  h\h  Whi          U>        /=  jk,<l      XL    GI  mgh  ph        n  opq    Zh  r  sw3  t      x>ehujhsAvwfh          O^hPQUMR    S*NT  UV      WxCXYZk3[      \rIdh!F]^10_  ]h`YhrASh[h`ha,G  bc*0dXheahxI  fg      E  Dh:F  FIh    GFh(KLh`0H  I  @h  J      K            Nh  Mh            kGTh  _h    M  ~3      bh    PhN    UhnM    6Gh      {?  7  8F5  ]6  Bh9:;  [2<  T>  Eh      Z:=  QEJh              ?nJ@Ah      Z2V8)IKh  ?h  AHhBC  RhDCh    #  $  %.h&6h  =h7h    '5h      (vg)*3h  +,/h-./P41h<h  2h      01>h20h|G3L      iM      9h              Oh45&h  stu)h  v  pAU7    wxA1(hyS9>cz{|qA                  _                          }    :h  ;h  Y2~    .28h!  "]^PLwgX2}3{g_`}gab    T7              #h,h-h    d+0efg  hi4h        q0    +hjkl*hm%h$hn"h!hcCo{B'hp  qr              #4N                  Oq1rgjN]BP  DI  ~gQW2|g  zgqgRogSpgTc<l6wCU  VQF  W  X  Q1  tgsg  YZ  ygugxg  [\  /0  12    3  45r0  ig6    7jg  8  9  :gI;<  G<  lg=>  ?@)320ABCDkgngNGED?FV2G'KH    I]7\6JmgKj2LMYg    {|}~zD      !    "#  $        %  [gZg]g  &\g  ^g'  `g(_g  O4)ag  bgcg  *1:IN  eg'?  +  p1fggg    ,  -hg.mMgNgn  Og  Pg=6*ZQg  e@RgK<oSg  0Ppq  Tg^J\4rs$AX=tqI.=  uv          wUgR9VgLH  dg      xXgyIBuG?8Wg%Az          =g  >gV  W22  Eg@gXU  AgYZ  Bg  !B  [  \DgCgFg]  ^_GgHg`  C?ai2  IgWN  +<bc-=    defj;WCgh  ijJgKg11kLgl/gE0g,gGHI  -g  .gJ    KQ9F    6g  2gL  M  fINlK(IO  1g  P4g3g      DK7g        Q  8g  R7AS9g    ;g  ?gT  <g:g?G          7"g8    9~f:  U?  eI%g;$gP9SO  <              5g=>      )g*g?@A  p<  B(gCx9'g    +g    D2D"J#A        \B    i;(  <6H@FO.LwfT@)                    *+,  S5zf-  .  /    |f0    1  {f    2    }f3&C  >G  4      1D5  6  #g        _0tf  @C  t      XGu[Bv    w  xyvfz{rfufpf  sf&K  |U8    }0qf              }~xf!yf"#9F  $  ;6%&  &g=G'    j    gfifhf%HkyF  >O)H  l        kf    S>  *I  lfjfmN4n    T8h;    nHop  *8CKqofmf  N9  O9i0  h:      rsYG          b      c  Yf      Xf              Zf      ;@  [f  \f      9J]fdoA^f  e  f  _f        g  ~Nbfhaf`f0Dicf&?  df      ef8OffTM7O  M9NfT<MfHI  JOf)<KLMQBNPfOPL9QWLQfRf    SfRSTUTf    V  W  Uf      X  Y  Z    *<[\mL]  ^_Wf`?CaVf6'2  7  BfCf  8  Df  bM  9:    ,=  FfEf          ;      <i?Gf  =  >Hf  ?If  e4@  ABM4  CJf          KfD]KcMEFG%  0f2f  eM1f4f3f  SM&5f'~H()*    6f  +,    9f  -8f7f    ./:f27  0  "AA51    2>f;f    <f  3  ?f  @f=f    4)1  5      pq!f  r        "f#f$fs%f&ftu(f'f    )f    vwx  *f+fy  z{|}.f,f-fa:S7  ~VC  3H!p=    MG  mH/fmX      "#$                                                                                                            L4  }e  ~elkmno  `<;me    abresec  tedze;Eveeuewexefye  g  h{e|eij                                                                    KH  ^eOPYeQ    !AR7  +=R  S  T  %?6Ade  Ufege    ceeeV  WX    YZebe  jeieZ  zK[\+7    ]        ^he  lekeoe_qe3o1    lFOe    ?VePeWe        @ASe    B  C      {GDEJ<UeFReXeQe    D=GH    %KIJL=K  Te`eL  \eM_e  ]eae[e  AeS@N    )*+,->e    [6lH./0mA  PNo=    ne]1He2~@  DeIeKe  yDNe4  Je56  TJK478KL9  ^0  :Me  }N;<    =>Le          rst  uv  w5e  xyz  7e  {  4e    |}  Q73B9enA~!Fe\  Be<e    "#    $@ez<]0;eCeGeK9VL%VD=e&'Ee(:e>C  ?e=0JL^_*=>8HA%e+e`a    &eP7b.e2ek7c  d    -ee  fg6ehiJ9    mM<03e  jk5k0e  l      1e  m}E/e,e  (3d@  n(8op  8e  q*5  !eKsLH9~dLMN$efL  <G  O3IPQRc=#eSS<I9f;i56J"eTU  GABKw:V    W      Xg;]DY'e_NY:Z(eB?  *e      R>0:  [\])eqd  sd  :rd  ;<=R8    >8A?    ud@AB|ECtdDE  vdF5JlAG9  wd      GHN  H  I      yd    zd  {dJ|d  e;  }dO7    j5    N6)7cd    ,-  4J  h?  0L  .dd  3N  /tG  FA4G    M=    0@01idgd  ed!42Q>jd    hd  fdnd  3mdldkd    45  od678pd:@9Zd    Wd    s      t  VdR@  Yd[dvwxXdu_d  \dyz{|}~]dFd!  "^d`d  #  $    ad%&  '  (FJ  bd      )    *+bL  Gd\]^_  `Hd  a  bcMdde  BdURIdCd    Ld  f  g      RdhJ4  Od  ijPdk  QdTdl        m  no  pSdvHqr    Ud|NmJa@;dH  OHI?dSJJ[CK:d<d    =d        L  MN  OPQ  @d    D<      FFEdDd  RAdS    6O        TJdUVNdKdWXY  Z  [          4  OJU2  5  5d  2d67d786d  sG'L9;;0d9d4d:3d/d;1d<I4      =        =C  >}@  ?@"HA  >dBC  $H  DEFG    %&      &d.I'&HyE  Z6%d#d(5H~c^C{E  zE)v:            8d    *      +(d,*d  -.  -d/.d0+d,d12)d'd  3    !d              sc  "d  vcsh5  uc$d      tc  P>    t      xcyc  +E    zcu^3    v  Z?dIw|cxyzhB{|}~!  wc"{c}c    {:      #  $      v3bcacdec^cefc)Nfgcghc  htTjc  ic      kclci5Nmc  opO>ncocW=  8FpcYjk(Clmqc  <Crcn    o  %6  ?Q]C3<p  qrH4RMFS`@u:TU  Xc  VW        XYbCkAZZc\cYc[c          ["7\    ]          ]c&7  ^  g5RM_c    _  ``c    a.1bc    ccr9  fJNc?@TKABPc    CQ@O1:2,0        DEOc  F    GH  IJQcRcw>  K  L  ScMO3  N    Uc      j7Of5  PVcu6    WcQ|@)5  *+      ,Cc-.xD/DcG@    0    -L1  #IEcFcUC2GN  3HcGc4          5      6  7o<89Jcp0  :;  Mc<=>KcT2N7LcF9(=d;t  u    vw=cx)=      y  J2CI  z>c{  kH  |    }~EA!Ac"BciG#A??c  aC$%@c&    N>'            (    \0)      IcX6    =O5A        4cabR2wD!J  c  defg  h    ij5c      k        z56clm8cn    9co)Gp  :cq      r;c<cs  Y6S2EF+c77    NOP@5'5c;QR      S4MT  1cU0cDA-cV  /cWXK=@?.c,c  *G    M>  Y<IZ  [  W:        \        xE  ]2c^_  `3c6L>        <%c        =  CA  >'c&c            (c?  @  ABC        DhbE  Fjb*c)cG    TH    IJ        (<KiNLR<M  '<      |bwb$%&}bxb'  (  XHvb)*yb+,      "c.      /01    -  2!caK  3  ~b    k0    45$c  78    9:  #c  ;  k8        nbvD    o  qb73lbp  jH  01ql:  ROr  pb    tuv  s  rbw    KJxY@tb  yz  ub{|}~  sb        N3!{b"zb#      ]^kb  _`      a  b      c                  dK>e  fg  hi      j  k2NE9  l'8    #H  mb          m  ob  n      =:    NO    P    fbQR    Sgb  &8U:              T    ibUVW  VEV:N5          XY  Z  $K  KG[  \    WE        \9      <      ^b  =      _b      >?    @  `b  Aab7Lbb  BCD  pLcbENCFjG  k6G  H;Cdb:6IJ  P@K      L    Meb      +      ,            Sb-.Rb    Tb    /01      2      Vb3Ub  4    MJ  5    6  V=FN78Wb9  7F  :Xb    Yb  ]b[b\b;ZbeC  p    qrIb    s    tuv    w      xy    JbMbz  {|}g?~DF!NbSK"Kb  #Lb$      %  &'(        Qb)    *PbObZJ>    @b  [?b>b}H\G4)8  ]      ^  _`  a  bcFbd  Cb??2L  e  BbDbEb  fAb      ghi        jklGbHbm/D  c4no    I3bVG  J_K  N1KW1LM4bN      6b  O  5bpE  P  9@9]  7bALQ8b  F4WH9bR:bS  ;b  T  \L  UVUL  >D  W  jAX  =bY  b=  %b5Q&b*E6'3D9'b    (b78)b  );    +b  9*b    ,b-b:;<R=>  ?@ABCDE  F    GiH  .b      /b    is0b1b2b    H  .;$%EN&'(tarasa)#*b4          ~L    +JJ  va,    ua    -  waxa  ./  |ayaza{a  }a012~a3!b  4  "b  #b  /HPE$brG4I  caadef    ghhaifajga  k    lm  no    p  qrstiakalamaunavwja  x      y    pa  z{oa|    }~!qa"      PQPaRaRBISI>    Ya  TXaUV    Za  &</:  WwE[a  KDX  ]aYZ[!N\a\    ]  iA    ^  _`baadaeaTC        bca  `a  ^a_a  CJa    DEaFa  IaHa%I    BAAAE?5FGKaH      ILa  JMa        KOaLNa          V1          WahHQaMSa    Ua>?N  VaTa@<O0    17a  <a23:a9aBZ&38a4Z05*H6  JH    7  1N=a;a\C&@89+H:-I  ?a,NM7@a  >aVHAa  Ba  ;[0<  v>Ga  DamFCa=>?@AB&5  P  ,a+a-a~          .a0a/a    y9!2a  1a"#E4  S?  <E  3a8@$%  :;&y14a'QM()cJ5a    *DE3MC9=?    +KC4R,.Dh26a-./                jk{`  l    |`m    n}`      o  pq;1  rs!a  ;I"at  $4#au$avw    %ax'a(a&a  y  SI*a)a  z{|    }KL  ~M  MNO  P  x`      QRST          UVW  X  y`YZ[e`\    ]z`^_`a    bcD4de    f      g  h  %<  i7p`  89  :;      <  =      >?    l`  @  o`j8M1q`Ap?n`\N  Bt`$t  CDEr`u`F  GHg`s`IJ<:    v`              w`  "#  e5$f`}M%  0N&            '                ()            vB  *h`+  ,-./012345j`VNW6|HJG    6k`        m`a`  Q2    hi  ]`j9;klAD_`m    no    p    q      rd`  n<s  t  b`uv  w>7    IHc`    ~`    xy  zi`{|}  ~=8!MN  O<8PQ(N  L6  &2    R  S    T  Uj6VW      X  YZ[  \    ]^    a4_`  a        hN^`  b  c  d  ``ef  g      8v9b;              9R`S`:  ;      <U`=        >?@A    C=    BCW`DV`EF  GHX`IM3    Z`  JY`K\`[`L          "  #$  %    I`&  '        ()    K`H`*+  TLJ`L`,DN    -  .P`  /0O`vC-G1  %8N`  23  M`41M2M    56  7Q`n1  r86=`?`  >`s  t    u  @`  Q8  A`    vwi6x@A  }9      yC`D`B`    z      m<    HF96          {|    F`,CE`}~5ObG!  T:5`4`  f    6`  g      hi      7`j    8`        k        >5  9`        :`l      $8mnHH  o<`  p  u>    ;`        q  .`MNO  P/`RJGH    0`WG  QRS  -DT  UV  1`g2Wm5XFLY6LZ424O[      RK\*J  ]    ^_  `7@  2`    abCF  cd#83`e>          zG?@A      #`    $`    B      C    D%`  E  F        G      &`  ^DH(`'`  I)`  *`  J_<cI  KLlL+`,`VA$<-`23  3G4      uEw_  56  y_  UN  v_7x_m18s_  9:  ;    [Sz_        gA8;|_        {_$?YR            }_    <!`  n_~_  ="`#      o_$  %g_  '7  &    m_    '  PMp_      &t()      O=*  +          q_      r_    ,-.G./          t_0      u_1  r      stu  {Nvwj_  y@  x  y    f_k_z  l1{  |  }  ~  i_  aGe_h_H>!QH    l_  Q<                    "      z@          bcdef  a_  gh    i        k1        d_2J  c_  j  k5L        G>        l  m  nop        3A  q      F>                      uN  X^_      (1  Y  Z[\]  ^`_    ___  ]_        `                        X_              #Ka    b_      I      JK    'Of?      j1      V_  LMNOPU_  Q                R            SY_:C\_W_TU  [_V    WZ_@EY0.              78      9:;<u^  A    S_    =>    gF        ?@        T_BC          P2D  EtE%3        FG  d5      ^<R:H  *G_      +,-  C_  D_  .  H_  F_      NI  /N_  K_J_  M_TFO_0    1    uCmBM      %@    2P_  R_  3    4  5    6  Q_  c7yB2_;G  {9_|}  ~                  >_<_    ?_  !B_    ";_j9(G    9^      #$  tM=_  A_uB%@_  +_  &io    'E_  ()I_  (_'_-_c!@  $_de    fgh0_  i1_jkl  mB4    n        op6_  5_7_qrst  :_      uvwCE  4_  xy    8_    z        s^      C4                  T  UVWi7    X/_YZ*_x@[\c3  ]^  a=  3_  _      `,_,D)_YD      L_      &_  %_  ._ab    y5:I  A  ?<  Bw9C  DE  3O  t^  "_i1fAF  G  HI        yG  A4zN    J    KL!LRDS  MN{^}^O    P  2A    QR  !_y^23q^4k^GL  56f^7"<~^89:  j3  h^m^n^              lBZB                        ;v^<=|^    z^  )E    #_w^>  ?  @x^`^~K  c^                  .H'  o^;8    (    `=  e^)    /NB9  r^*  n0    p^  +    d^    ,-j^  .l^/    OMg^    .E0  i^  1      \^qr    st+Lu  Z^^^v  wxyz  P8{E>    9C|}~T^    !"      /M#    W^    P^rE    S^$    Y^        %  &QO><g      h6@  i3Q:D>=^B=              L7  <^      R^m=:8  a^i[^t5OEjV^_^/021k  92  X^,BO^Q^A9    l      m  b^n]^op  U^  dM      UH^B^?^V  WTNE^  XY  J=G^    L^Z  qEJ^  [  \D^]^8C_  K^`@^  F^aM^|0C^  N^bc<?L_=d%Je.:K;^I^:Ef          F    :^  GC>      0M  7^    HI2^J8^KLM^N  sEBF                          N  O    63    U1  P>^  QA^R    CNS  T  .N    t>u@                                  =  6^4^  MI  >?  @  1^3^A:1B  @92O  =3  bICD      aM    $3;?5^    E              +    ,    -NM0^  ./  0/^1      v@  ,^2lM    6F&^          ED345L1?9)^    78  9'=.^  -^(^  +^:  h3;*^IG<  76v  u]z]w    t@qG  gHx  yz{|w]}!K~y]  $^!"^"{]    #"KHGc5  %E  $mC%%^&'  (#^YBv])K1*                        n]k]`M  ijk@Dl    YFl]    t]  s]#7mn-2op;:m]o]q    r  WKtB                wK    |]  s}]tO2u      (J}L!^#<B>x]~]h1uDA=a5              XY  ZFH[.<  \  ]h]  @4  ^x1_`rFg]>9SC  i]        6q]  j]a  b  cAB  b5r]d  e  fgh7h  %5p]      C  DE    a]F      GHa;I1LJb]c]    $5  K  d]      L      f]e]  MNO      P  Q        Re?ST9IJ1  UV    EHWLT    45#5X]    6  Y]7lJhK      GFZ]fH  8  {H  9SL      []  :  ;    <=      ]]\]  >_]  ?  ^]      @  A          BH]  "J]I]#XK    ^=l<D;  K]              M]#?$L]    %    N]&'  ()O]      *+P]Q],-.R]/T]S]U]%2JC  V]01&;L3W]23BE      =]    q<]  >]r  N2s7C  ?]  t?4A]  u  v@]  B]  w  C]xD]_;5@!:  pIy  bJDOz    {u;|    P:rN}    E]F]  `;  ~!G]    ]^sM0]_`  a^\        bcd3]      4]e      f  51g6]g7!<  U6h    $2i    jk    l    _M    mn8]7]:]=5o  V6>4p  j\%]$]    K  ML    N      O*]  &OPQR      -]{6ST)]+]    J  U    V'H  .]  W      XYZ              2]/][\    IC7  8|\  9:  ;  <  z\i8  y\=          !]      >X[?@A{\  }\~\  B        ,]C(]  m[DEF  ']G      &]    #]  HIJ        m\&'r\v\()66    *  +,-    ./  L5t\  0      !5  KFs\  1  u\2    3I          4o\5        q\          6`3rs[\t  b\        h\uHn\    u  vi\l\f\w  tC  8Ix\\  yd\@>zOLx\k\{      |"8#2_3    S\  }  ~  !A>p\"w\y<r3#  .C$%  I\  Q\  e  "tf  N\=9HDdAL\  G\g  J\    hiMMjK      O\Y\      j    k  a\Z\    g\  e\lm  n`\o  p      _\  PD  eAq]\UC\53              g:    V]1    T\W  1OW\X  Y    :?V\      U\Z      [\R\]    ^  _F\`  c\E\  X\    ab  cP\d  K\H\    B    C      DLM      E        vI8\JB  F  >\?AG5\B\A\  oF@\jFHIJK  LMD\7\NH6:\]=OPQ`G<\K6  4\6\3\RS0OZ39\TPOv[    &\X05  x[67:L}["?GDs[89%\:    ;<  z?/\q3!8        1\z[0\  )\{[  -\  .\          ?\=  >NF?$\  @;\  A  =\  XD        ~4{2\  |ILw[}4}~[  ~!"@K#!\#\$'\y[%*C  &'  oE+\|[  (\  (  "\)  *+,-9?,\./3@    01    *\=4234      BNkl[l_Gm  n        t[  g[      40i[  o<9p  qk[rj[  f[q[s?>t  umTh8|Mvw    h[xtD#3-:y`[  p[a3    n[r[znE      \[e7K7mEXYZ[  F0  Z  [][_[  M6,7I<4K5\  ]^b[  _y:qK  7;      c[      0I      `    abcde  o[f32d[  ghij  u[e[  FNDJFI1                            r@J  4@*7  K      LY[M  ;9|3        ON[[t3a[PQ  RST^[Us@      K3,:  VJ3O:  W9HB:;AJ<V[  =>"I      U[pG?K;4?w@@=    @SDA.M  BQ[P[    CR[  O[  DW[  M[    K[  S[I[ElCFxLF<t:GH  8  ::    oKA3  '    (G[  zH  >[  D[C[  )*O@+  ,  mK-SN./gK0L2^;    HOF[u?      E[    @[          O8123L[J[4M2H[N[T[  567      5[      x8[yzy?    {  {MI0`:<B  ]<|}s>    ;[    NE~9[+B:[r>]L<[=[hM!      B[  ":9#UG?[lE^ZbZ$O5%GG      &A[  >>DHG:    rP  n  on7-M  ~J  ~Ip,[      qs:?D-[/O  r  >Ks+D.[|4t  u      /[0[ZL  $LvK\K%;2[    k<  vQK  4[7[6[  y4    `5w3[_zZ`a![    ^Fb|Z    c  de        f  #[    l=$[gKMxG  h%[          '[  i([  jk  l  )[  J6H199*[  +[q=bAm?XR>A=AXBKG6  sZwZ    K2tZvZ  MNOuZ  Pk=Q      HCE0xZRSTUyZ  VW  *D  X  qN        C;  YkJ    Z[  =K\    "[{Z  ]~Z  }Z^1jZ~;89hZ23    iZ48?5  7gZ  6/;        89:  ;<lZkZpZ=>qZ  mZC"3nZoZUH@AB  aIJ7rZ    D2@E=>GHIRCJL  CFu  79`Zv  +::>wx_Z  ;>y@L*:  z{W0N@|}          fZ~!1@G1"#$%U=&fKr:'()*<>+'@,-  .eZcZdZ0  /  BkC    &[  UZeSZVZ9NTZ  fg  {@WZ  h2Bi  XZ  j  kz4lZZ  YZ      m[Z\Z{4    |F6Cl5];aA    \=00    n]Zo  pq      r"2aZ    st  VLZMZ  W  8J]UF@X  LI  X:  eHCHY    Z  ME[AN  OZP<\  PZ]60  ^T6M@_`I      QZB;GC`[;7?  abc    RZ  }J    w1\;  d      J  N8  KCZL      FZARIM_5N  OEZDZTGGZ56      IZHZPQ  :46;    XFR      SI7      t?  JZ  0@(E  _IKZ  T    U    5Z5    69Z    789        :      ;<  =  7Z>  ?8ZpY@A    B;Z:Z  C    DxY<Z0Z  EY;  F    =Z>Z@Z?ZAZ~2G69HI|J/@  JM'Z  !#Z  $Z  "#$%`A&  '("Z  ?Y)  *&Z  !Z          +Z,Z'E.Z+,$;)Z  -.  <5/  /Z0(Z3Z  2Z11Z2    4Z3  6Zq>4      b7  l  m}Y            nop5;zY  yY    qr2Gs  t5Fu  v  w1E{Yx  y|Y  oIzEG#;  q@  PK{          I3  %Z~Y|}~    ]@                Y    wYZ  [\]^      &E  _`ab  cde  f      tY  `K      g  uY      hi  vY  NL  "@j  k                lY    GH    ;B  sYI  JmYK  jYqYL      SY  M  N  O  PQnY  rYRS  BHkE  TU      kYVoY      H7    Wq:XcY5  7BiY6dY  7fY        8AIsD9gY:;<,M      HM94=      >.0  eY  ?      bY@  A  x4      BCg1DhY  EFIM          WY  %]A&    'x<\Y(  8>  VY[Y)  SG  *+UY  !7,-]3    .]Y+NN:5CZY/\@059d?f1<AXYE5123    G7  OD^Y          _A  4aY    klmn  o    *Bpq+;RYrTYPY  stuaJ  =Dv    w\A                xy{JN<`Y  _Yz{x?    |~7  }~YY9>!  hF1G"#  $  };LY[\    X;MYD0]^HY_    `)D  a    b  cs5          46              KY'0deC:  f  6?          gh    irD  jTHQY^A    DY  Q4C>YEY@YGYCY  BYoGR<Y}2:Yq5sB6YST9Y49[@U7>AYRG    r5H3                V  g3!?IYNY  JYW}7XOY";i9        YZ&==Y;5  0Y7Y6>        1YDG    EFGH^M3Y4Y8YjE5Y39^@    FY4H  rB              I  J    dH-Z        zJ  K  qDLM  uKN;Y!2jCOPj=(Y345  6p@=nbH  j<7M:)Y  89:GB;'J<  qB  =,Y>  *Y  -Y    +Y?      .Y        @1JA  70  B    ^I    cHC  /YD2Y5>xX$  %&    'yXzXjJ  |X{X?=  .@f2|2(}X)?0      L@~X*Cl!Ya7+"Y,-    o@.  /#Y0    $Y:5%Y  &Y'YWB      M81  aL  2  <KpqriX    jX):hXfXeXlXdXnXst{2        u            vwxy  z{pX  ~oX|  }    !"  #    (D  sX  qXgX|7  rX  vXuXwXtX[\+M]^    \X    `X_  `~A  yNaXab^X  [XcdZX_X  ef  gh      0Ji  4FjF7kbX]XlcX      {7      12  mnkX  o  84    OJX  KXPQ@X|;RDXVB292X5?        XX  iJ    NXOXPX    WXSVXT  }K74  TX  E743    QXU  8NSXV0UXVLXRXYXD7MXW    XY  ]MZ7X%=8:X    4X9|L{L:  ;>X?XU0<=>?@3XAB  Cr6&0D  E64@;XF        CXBX  GHGX      IJ    HXKLM  N    FXIXAXEX    #  $p>/XWF%&'(    )*  GO  +X+,    1X-{9.K@/0T0*X(X1ZA  2  |W4;              FB=X3[A8X45X6X5f<9X<X67      zWm}W!X?n  o=<p'XpD{Wq    r%Xsy2t#X$Xu  ~W"X  vwg8*M  x54yzY1&X{:G-0          |}aH\W,X0XeL~)X    !iE.X"  ^lWvWtW    qW_`apWxNbrW    26c19  dz=ef  yWkW    g  oW_Whz2sWuWQC  i(:82mWxWwW36  )Bf3j      C7  nW            kl              Q    R    ScWiWaW  \ETUfW]IVW`WXeWgNW;  YUB^W    Z^5hW-@e1bWx2gW  [  16  dW  \  ]        jW                4?8,I  9:;  <w4&G    =>?@A  VWV;:K;K    ~1[WB  iCCD  XW      EFGw2HIJK-XZWLM  0GN  YW  OWWPz9  ]W}1,@IWHWB7TB  NWLW)KW'Ne8*  +y=MWLE>=    ,@FQWPW    -.OW  RWf8/  2    0SW|I[=13TWyH456  AF'D    >70E    UW+5    r;W    st  u<W  06  =Wv>W  w@W  vEx  AWBWyCW  z4W3W    {DWA7|}  'I~  L:7I&DKIEW  !4>F1"FW#$  GW%rL&  `H'(JW  [J\1W.O  ]^_2W@J5W!P1P`0<uF6W  ]5$Dz07W&J09a  PCbc  oD  defgoL98L8h8W  ij9Wk?Wle<    m%Dn/6:W    o+IpFCq  zV{VQG    P  |VwN-ORQ  S~V}VTUG3VW!W      $W%WX#WY@I3>'W&W"W  Z    (W)W  [*W      -W+W  ,W.W  d1nD/W  z7v26G  0W{FB#D  -91>    _H    2>C    Dx=          lDyJ9E    .9  \I      yV  E  FGYEB:H  IK8JmD      K  L  C0n=/9GM        MNOlV    kVjV}I  sV  4  2ZK  mV  35    oVkK6nV7    89  :pV  (HqV>JrV      ;  <=>?@  A  34?J/GtVuV  ,944vV88DM)Mv4xV$  T;[I    AH%      cVu4&      fV'  ()!D  *eVdVgV  kD  +,        c?    .    U;  J@-SB"5  /"D  0hViVo>        9K1        v      w  ZV  x`4[Vz  y  ]V\V    ^V  {|  _V  n@#=  }d=  cA~)98:*9p5!  `V    9:    J8aV&LCGbV  +9"#  ,4  'CR6    dQVePV    OVf  ghE:V      WV  hijk      l  m  SV  no  RV        p      qTV  UV  r  t  s    XVtufN  YVVV        PQ    R  S  WKVHV  JV  rMUIV<  T      V    ?V    XYZ[  \        s?]  LV^  7:_    MV    NV    `a      bc  B        Cr?      <V  Dj:    BVE  CV=V33>VGVFVEVAV      @V    DVGH  IJ  xJ  F          K    L        M      N  O          2V  4V  9  :            ;        =  5V      <    =F.6            e26V;V    9V>wJvJ?@  A;gE      8VT=  7V                  )*  +  )V    ,t4*V-  +V                .  /0,212    3  ;Ad44-V(L        RB5Y367/V1V_4  8.V0V  3V  I6{U      o5|U  ~6  OF02  S;}U"V!V}6  ~U  8E      wx  y  0B  KEH<z{XAzM  |}~    $V!%VVF"3;    #$'V    (V%&'(      uIl@  M<qU->rUsUS0:BR?itU3F.>  />  uU    m@j    0>      klvU  wUm`L  n  xUo  pqF6r  s"=t    uv  yUzU\<,?tFT?xH"G[\d<cUs4RF)LdU  eU    YI]  ^gU  (4w6fU  _`abc24  2?kU!;dI2jU  hUlUiU+GM\3?  mU:  @NenUf  pUg~CoU  #@  {;    hPBw<_UG  `UHpBI'1i<B0JWA045<K(9LM  NOfEP!=14hCjD8095uJ  B<    R5k@<<(MaU  QR    ST\5UK:VW23c1,>H2XbUFMY  Z    I=RU:  PU  QU          ;<      R;SU=  &9TU>z;8B  UUVUZ;'9?RL      (5I8WUX3  @XU  9B    ABYU#V  ZU  [U    \U  ^U  CDEF./            0r4  IUHU                  JU1  3  4  5      6n>    7        MU  \D8    E1  KU  2  NU  9          OU    G2?U  !  "  #;<  >Uy7    $LU          EUBU    %  &      'dC  AU  (CU    DU)      *            +,      FUGU  -                          k        l  ^Gm    n    o;U2Ip  qrs  t        u        v        wxy  z    {  |}<U@U=U~4U,O    [\LG]^6U    _      `        a        ':      b      9Uc  dXIe    :U  5Uf                  g    hi    j;LLR0  #0M        2U    NOP    0UQR        <L  3U  1U  S/U1?    TU.U  VWZJX    Y  d8Z        7U8U          +>        9  :;  (U  <P;=O;  >    90H8?+@Q0        ,U-U  *U@AB      CD81/4E)U  EL1I    FG  HI  J  (0K      y0      Q;  "U!G^HQL          %G()+U*      +85  ,EM-  /L  ,V  #U  .      &U/EB  08K      JE1234  'U5      6  eK7J:8  *>        rb1  sq4`FtJ        wTUAvT@7tu[KuT  eEyTvxTw  xyz{T{zT|  |1  |T)>~T%C}}T~3J!    "w=[E#$  !U%  &'%9        iT    _`    QJjTab    F2kT  cde<M03  IRH=?BlTkLg      h4LijnT  gBk7E@BWIoTpT{1lm:<qTn  opP0rT          sTq  IJQ  OYT  ECR  u2  m>ST  U[TVZTWh9X\T^T]TY  `TZUTbT  [\  aT_T      ]  N;Q?  TAcT<@m0dG^      [D  eTdTfTgThT    ;<  -6  PT  =>?@  AB  CD    hJE  F}A        FDG9RTHIJ      K  OKL  ST    XT    MN/J        WTQTTTVTP  &:  =J]N              -t2JT./  01:AMT  cE2  IEdE9HMD      I:3  4IT  5    67v1  6E        KT  GT    P?    8OT    9  N=:YK  2Fz{x7OB  |}ATDT!"              DB      ET  #  FT$%&HT    iD  '(    .4    )  !ta1sJ*  l>HE      +f:    NT  ,1T    <T    =Tgh    dKi  k>j    ?T@T>TkBT          8Glmh0VI~  CTn  op  q      r    s      }>tu9<v]Gp4  k:wxy  Tb?U        2T5T  ?7V            6TW`  X  YZ  [\]^7T_$9@39T    abc:T  d      ;T    8T        e        f    .T  d:    <=Q6    7K  >?,T/TA:#9@            6              3TA  %:B3CCD0TZDE  FGHIJ  KLM  N  OPQR  S4T{S#$`J}S    %!T~S&"T'#T  w7  (`1$T  )&T  %T  *+(T,  ZE-  ./01)T50_:23  4=756OC    78    *T+T    -T  9:;sSqSoSrS  j    tSklmpquSnovS  wS      xSEQr|<M;sts2ux0v  DCwxyz{    }  ~yS  $:|O0^?    !"  zSG8    q9  |SfS      TUeSE3V  gSWX    jS        iSY      Z[    \]^hS  9G    kS_`ab  cdelS    f  gnS  mSh        pS  i  >?=1@A  B    C  D9AEYSFZS      G            z3    H  IJKLaS  M  o4NdS`ScSO  P  QR  .JS    UF  8H                    *2C  +E2,    -./012  RS  TS(>313  WS                          ^2    4    bS5|>^S6\S7]S8_S9  :;<  =  v  wNSLSx'T  y  z{  |    }~!QS    "#  KS$OS  %MS    &L;PS        '                        (SS  XS      VSUS)=SfgGS1A  hISi"9?S}C    jk  lmno    pCS<S-4  n4e3DS@S      qr    v7JSHSSAJ5,6sES  t6  t      D1                u1SV    oB6S&>W  XY  3SZ  dL[\  <7    7S8S]  ^_5S;S`  ab  2Sc  d                                        ASFS  BSeEF    41G6:0?HI    JKL)SbE      *SM"0                                      NO    4S#M  '>P:S  QR  9S0S  STUCB  %0JI"S  |R  9wR}RH::    ;<                  &S              =w0/S    'S(S  %>iK>  ?-S,S@    /E      A      .S  B+SCDrR!  "tR#vR  $%5p:BO&kRiRuR'pR    ()          *    +  ,xR  #SzR-.~R/0!S{R12>S  3i:13      4yR567%Sv0$S8`R  $Oop  rJqhDb8p9    rhRs  ]F                        tlR    u  v  wx~<yv<z  {|  oRmR  #L}jRsRnR      qRF8?L  ~  ^RdI5F3      g9H5_D%11F>L!9yMGE~8  e            f/7  gR  c6JKg        ]HhifRj^4aRbRdRk  l    mneR  [5a?  -JcR_Rc8  W  2;TR  X    tK5:Z5'MPA?H}<Y    Z[G=\h<u<  v=]@H  ^_WR`C1QA}8E8g6ab[R!C~B+6$>\RZRD2fB8<K;&1  cp3f9J;  ]R              LRCqL    DE          F        GH  MR  RNI|8    J  68NRK    LPROR  _?91MN  ^1QRORR  P78QRSRST  Un5  V    ?R==6i@  AR@R#>a8CR>H87DR      \H4BnB(6    nF1C9nG:NK  FR  j@;  <  =57    GR    >?HR,1u0m4@(BQ5qM  KR72A  JR    B*6{hLwF|  qJ2R23R  }~!5R  7R6R"  #  8R=2LK$|:9R%&YA'(">)6  :R3)  *+,[H-./  ;R0<R1=R  2    >R$Ih6e0345?Fe&R  VKf<Dg&MhYJ    i'R  j  kUp  l0Fm(R*43L  no!>)RgJ-Rp*@*RP6q+R+4rst  u      vw.7.Rx/Ryz0R1R[<      {8^LM  ND3  O  `7|Q-NP  QxQ      }QzQRyQSTUV  WONX    y8C2    tNYZ[\  u=XEe9"R#R  ]^eN    +O%R_`az8bc$Rd/3        fDmQ>  'B  ?o:nQoQ0A  lQ        qQ@6KAB  Cd9D  pQEFG  u7^:mGH    tQrQ      I{Ij>{Qd3uQsQOA  JKL      wQ  vQaE01O?cQ2,JZ@"4  )4dQ    fQ    :734eQ56sN7        i=        8  =HLJ  gQ9xMhQ      iQ  ~E:;jQ  <)@~:t7kQI;o9=          ~  (@YQZ=  !ZQ  |C?N`E  "  #$%  &ER  '    [Q%tE6(  \Q^K)    *h=|B  ^QdF  1_Q+  `Q.3,-.aQ'6/LFz1P=    !HbQ  CQ  DQpqbF_1    GQ}:rFQF:sHQnfIQAKJQ  KQLQi>tL<      u    '4vOQwMQ=LNQ  ZIPQQQRQ_Ex    VQTQUQSQc:WQjLdNy  z  {XQ|}:Qt0e58;7<={C$6h@w8fn9<QHLFEgy;  ;Qh=Qi  jk  ^E  u3    l    >Q  m~Fn  4A@QAQ,Hx8;OBQ    &6      <J6Bq65E      s7  o  75.Q/QI/2  JKL-Q  MNOP  R  t<  2Q1Q0QSVPT3QUVWX~=  4Q  Y      Z[  %M  \]  ^  _YL`ab  6Qcd5Q8Q7Q    9Q2  $Q34O6  5  !Q"Q  6/F7|A8#6  9:MK%Q  ;  =N  <=&Q>    ?)Q@'QANABC      (Q*QD  EQ  0,QF    +QGHJ    H  zPw  xy|Pz      {    5K|}~f7!"#  $  1;wH{P%&  '()*+              ,  E:CM  -.  ~P#Q}PD:  }=  /0    197  _`apP  bcqPuPN0d  e  fPJtPghi  sPwPj  kvP  dD    lm  no  r7pq    r  xPs    tuE<  &BeDv6  yP        65    IJ    KfPoPL  RAMD8N\GOG`PnP]EQcP  v8RSu8aPTUVWZ<  iPXoJMCePq7YbPjPdPQNkPAOZ  [  \]  ^f6    p7  v        6787%Bd289  :;S=<=>YP?^P\P@  WP    /BZP  ]P[PA]J  XPB.?CsK_P`P                $=mPD  EPG  6IhP  pJ  62  FGlPH  |}&4~!TP  LP"#cN$x;%MP&RP'()  UP*NP+,!6  M0-."6A2                  %U  yKnIt8    /    /?7N0  1  2345XJf  gQD    "CJPhi  jkL0cD;=4:$MlNBm?2nIPo>MEPGPn:HP$Up_    q          PPr  s  tSPQPu  B2  ;JKPvwxyOPs8z{H;Rk4ST        UDPK0VW`8l4zI2HY5X    YZ[  \q2  gPAE                                ]lGFP^  `<HabNb-?cG;dw;@2e  :=N?>PC<P  =PX5    #:p2  ;P:P)JD      F;E;>B?PUIg@EF  8!@PBPGHIeBaNJ0    J        AP>2KD6LgCM  No7CP      $G/OPQ55  ,P    -P;N  =MhA/Pv;sF=2P    >1_8  ^8f0>?KOJO  3:!0@3P4P5P4K6P  r8g0rK  |5    }5~5bD<NA7P    8P    9P    BM?          /0)P5G1W5  2      7G  cFC83K  3      Ii*Ph>+P524  5e6p8iL    &V6        78              pM  }F9:      ;        %4<l0zC!7<"#  |Kf>0;e><2$TI?M  "P/1%  n3#P$@BRV5:J        g>&  >N  '(  BJ  )  $P*  fC+,-%Pz6    .&P  ]40C  g<'P    (P        U-                c-                                                                                                                                S-T-                        P-Q-R-    V-                                                                              @-N-    C-      H-          I-                                                                      _-o-n-m-        F-                  J-            A-      D-                  B-L-    K-E-      M-                    G-        O-                                                                                e-f-g-h-i-                                                                                                                                                j-k-            l-            @%A%B%C%D%E%F%G%H%I%J%K%L%M%N%O%P%Q%R%S%T%U%V%W%X%Y%Z%[%\%]%^%_%`%a%b%c%d%e%f%g%h%i%j%k%l%m%n%o%p%q%r%s%t%u%v%        &!<!3!4!  `$a$b$c$d$e$f$g$h$i$j$k$l$m$n$o$p$q$r$s$t%            +!,!5!6!    !%"%#%$%%%&%'%(%)%*%+%,%-%.%/%0%1%2%3%4%5%6%7%8%9%:%;%<%=%>%?%`$a$b$c$d$e$f$g$h$i$j$k$l$m$n$o$p$q$r$s$              +!,!5!6!    !%"%#%$%%%&%'%(%)%*%+%,%-%.%/%0%1%2%3%4%5%6%7%8%9%:%;%<%=%>%?%  !$"$#$$$%$&$'$($)$*$+$,$-$.$/$0$1$2$3$4$5$6$7$8$9$:$;$<$=$>$?$@$A$B$C$D$E$F$G$H$I$J$K$L$M$N$O$P$Q$R$S$T$U$V$W$X$Y$Z$[$\$]$^$_$!!"!#!7!  9!:!;!R!S!T!U!V!W!X!Y!Z![!)"."L!M!              `-  a-                                                                !!"!#!7!  9!:!;!R!S!T!U!V!W!X!Y!Z![!)"."L!M!            A!`-  a-                                                                j!  i!                                                                              v"    u"  t"                                          z!y!                                                                                                                              !"~!      {!    }!|!                                                              ~"                                                                                                #"""                                %"$"                '"&"        @(                6(                                                                                                        !(,("(-(                #(    .($(    /(&(    1(%(    0('(<(    7(    2()(>(    9(    4(((    8(=(    3(*(    :(?(    5(+(    ;(                                                                !-"-#-$-%-&-'-(-)-*-+-,---.-/-0-1-2-3-4-                                                            ^"                                                                                              >"?"    <"="                                                          ]"                                                  y-                                    b"                          b!a"        e!f!    c"d"                                        O"  _"P"      `":"    ;"          t-                e"    g"g!x-\"        B!  J"K"A"@"i"j"  s-          h!h"              f"    O"  _"P"      `":"    ;"          t-]!              e"    g"g!x-\"        B!  J"K"A"@"i"j"  s-          h!h"              f"                                        M"  N"                                                                                                                      +","*"-"                                                                                                                                                        5-6-7-8-9-:-;-<-=->-            stuvwxyz{|                  n!                                    b-                    d-o                r"                                                                        >!        =!    F!G!    H!I!    w"x"      E!D!                  s"  l!m!              ("                                        >!      =!=!B!  F!G!    H!I!    w"x"      E!D!                  s"  l!m!              ("    ~                                   >!      =!=!B!  F!G!    H!I!    w"x"      E!D!                  s"  l!m!              ("    1!  b'c'd'e'f'g'h'i'j'k'l'm'n'o'p'q'  W'rstuvwxyz{|  }~                                                                  ''BCDEFGHIJKL  MN!'"'#'$'%'&'(')'*'+','-'.'/'0'1'2'3'4'5'6'7'8'9':';'<'='>'?'@'A'Q'R'S'T'U'V'X'Y'Z'['\']'^'_'`'a'P&Q&xR&S&T&U&V&W&X&uzwy|                                                                                                          89a  bcd  g  ilv!&"&#&$&%&&&'&(&)&*&+&,&-&.&/&0&1&  2&3&4&5&6&7&8&ejqrst{A&B&C&D&E&F&G&H&I&J&K&L&M&N&O&              0                                /265  3                                                                                              &&CCUUggppmmoonn                                                9                    I(HMMOONNJ+KWW    VV-MYY[[ZZ\\]]__^^aa``/Olliiffkkhhjjqqttsuuwwvv  ''%%((++,,//--00"B77    668855::;;==<  >>$DGGEE    FFDE&FHHIIGJJLLKK)A A A A A A A C E E E E I I I I D N O O O O O _!O U U U U Y T s a a a a a a a c e e e e i i i i d n o o o o o `!o u u u u y t y "!$*#)!.2143@?BA  PRQTXS_!,cbedr0N"!$*#)A.2143@?BACPRQTXS`!LcbedrPs                                                                  ! q!r!  \ | x!/!c a c"L"- R 1!k!^!2 3 -!L&y"&!$!1 o d"                                                                          Bq!r!p\ Cx!/!ml  L"  n4k!^!    -!  y"  1  k        D                                                                  Bq!r!po!Cx!/!ml  L"  n4k!^!    -!  y"  1  k        Dabcdefghijklmnopqrstuvwxyz{|}~                                                           "!    b!c!d!e!f!g!h!i!12!!!pNPQS$STYWX[\S]_` aNe;fef)hkjjmm(puvv0yz}}b !"v#$%ސ&'();MQ*+,ٚr-ў                                                                                                                                                                        p!q!r!s!t!u!v!w!x!y!`!a!    	"&*+/12479:<=?ACDEFGSUVWXZ]^himnopqsuz}                                                          |~Ýǝɝʝԝ՝֝םڝޝߝ
z{|ƞȞ˞՞ߞ     "#&'()*1567=ACDEIJNOPSTVX[]^_cij\khnpruw{/0234:<E=BCGJST_cbeijkpvw{    	 &+-34579:=HKLUVW[^acefhjklmnsuwxyǛțΛЛכ؛ݛߛ    Ùəәԙٙڙܙޙ "#$'-.3568GADJKLNQTV]ÚƚȚΚКҚ՚֚ךۚܚ     +./0235%>DGJQRSVWYZbcefjlŘȘ̘"&'+123459:;<@AFGHMNTXY[\^_`    	!"#(13ACJNOUWXZ[cgjnsvwx{}ėŗǗɗʗ̗͗ΗЗїԗחؗٗݗޗۗ
 #&    ~ƕȕɕ˕Еѕҕӕٕڕݕޕߕ"$%&,13789:<=ARTVWXant{|~ʖҖ]ؖږݖޖߖ    z}ēœƓǓɓʓ˓͓̓ӓٓܓޓߓ	./1234;?=CEHJLUY\_achkmnoqrxy    ÒŒƒǒȒ˒̒͒ΒВӒՒגْؒܒݒߒ !$%')*3467GHIPQRUWXZ^degijmopqstv    Ñőӑԑבّڑޑ 	
#$%&(./035689:<>@BCFGJMNOQXY\]`aeghinopuvwxy{|}    ĐŐǐȐՐאِؐܐݐߐҐ  %"#')./14679:<=CGHOSWYZ[adgmtyz{    CGOQRSTUX]^eƏʏˏ͏ЏҏӏՏ()/*,-347?CDL[]bfglpty̐Ð    #&'136789=@AKMNOT[\]^abilmopqyz{ÎĎǎώюԎ܎  !#%'(,-.4567:@A    ŌƌɌˌό֌Ռٌ݌	eilnōƍǍȍʍ΍эԍՍ׍ٍ !"    ÊƊȊɊʊъӊԊՊ׊݊ߊ
-07<BCDEFHRSTYM^cmvxy|~89=>EGIKOQSTWX[]Ycdfhimsuv{~    {|}ԉՉ։׉؉ "$&+,/57=>@CEGIMNSVWX\]aeguvwyz{~    :<ACEHIJKNQUVXZ\_`diqy{ʈˈ͈̈Έш҈ӈۈވ &'(01259:>@BEFIORWZ[\abcknpsuz    (./129:<=>@CEMX]adeoqr{ȇɇʇ·Շևهڇ܇߇	
(-.025     !')68:<=@BFRSVWXY]`abcdilouvwzÆņц҆Ն׆چ܆熈!#    ܄2"#$%'*+/346?FOPQRSVY\]^_`abdkoyz{}ǅʅ˅΅؅څ߅    }ǃɃσЃуԃ݃S
/9EGHJMOQRVXYZ\`degjpstvx|}ǄȄ̄τӄ    KNOQV\`cgmt{}ƂЂՂڂ 
T!",-.037:<=BCDGMNQUVWpx     $',05:<EGJLRW`aghimowˁÁŁʁ΁ρՁׁہ݁ށ !"(24:CDEF    q}~
 $&,.04579:<>@D`dfmquȀ̀πҀԀՀ׀؀    }}}}}}}}}}}}}}}}}} ~}}}}}}}}}}}~~~~~~~ ~'~(~,~-~/~3~6~?~D~E~G~N~P~R~X~_~a~b~e~k~n~o~s~x~~~~~~~~~~~~~~<;=>?CDGORS[\]acdefm    a|c|g|i|m|n|p|r|y|||}||||||||||||||||||||||||||||||||}}}	}}}}}}}}#}&}*}-}1}<}=}>}@}A}G}H}M}Q}S}W}Y}Z}\}]}e}g}j}p}x}z}{}}}}}}}}}}}}}}}    1{4{={?{@{A{G{N{U{`{d{f{i{j{m{o{r{s{w{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||	||||||| |%|&|(|,|1|3|4|6|9|:|F|J|U|Q|R|S|Y|Z|[|\|]|^|    yyyyyyyyyzzz	z
zzzzzz!z'z+z-z/z0z4z5z8z9z:zDzEzGzHzLzUzVzYz\z]z_z`zezgzjzmzuzxz~zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz{{{#{'{){*{+{-{.{/{0{    xxxxxxxxxxxxxxxxxxxxx yxxxxxyyyyyyy y%y'y)y-y1y4y5y;y=y?yDyEyFyJyKyOyQyTyXy[y\ygyiykyryyy{y|y~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy    dwgwjwlwpwrwswtwzw}wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwxx	xxxxx!x"x#x-x.x0x5x7xCxDxGxHxLxNxRx\x^x`xaxcxdxhxjxnxzx~xxxxxxxxxxxxxxxxx    :v<vJv@vAvCvDvEvIvKvUvYv_vdvevmvnvovqvtvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv ww
wwwwwwwww"w(w-w.w/w4w5w6w9w=w>wBwEwFwJwMwNwOwRwVwWw\w^w_w`wbw    uuu u!u$u'u)u*u/u6u9u=u>u?u@uCuGuHuNuPuRuWu^u_uauouquyuzu{u|u}u~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu vvvvvv
vvvvvvvvvvvv#v%v&v)v-v2v3v5v8v9v    s tttt
tttt$t&t(t)t*t+t,t-t.t/t0t1t9t@tCtDtFtGtKtMtQtRtWt]tbtftgthtktmtntqtrttttttttttttttttttttttttttttttttttttttttttttttttttttu    rsssssssssss"s$s's(s,s1s2s5s:s;s=sCsMsPsRsVsXs]s^s_s`sfsgsiskslsnsosqswsys|sssssssssssssssssssssssssssssssssssssssssssssssssss    hqyqqqqqqqqqqqqqqqqqqqqqqqqqqqq rrr	rrrrrr$r+r/r4r8r9rArBrCrErNrOrPrSrUrVrZr\r^r`rcrhrkrnrorqrwrxr{r|rrrrrrrrrrrrrrrrrrrrrrrrrrr    ooooooooo pppppp p#p/p4p7p9p<pCpDpHpIpJpKpTpUp]p^pNpdpeplpnpupvp~ppppppppppppppppppppppppppqqqqqqqqq q+q-q/q0q1q8qAqEqFqGqJqKqPqRqWqZq\q^q`q    bncnhnsn{n}nnnnnnnnnnnnnnnnnnnnnnnnnnnoo
ooooooo&o)o*o/o0o3o6o;o<o-oOoQoRoSoWoYoZo]o^oaoboholo}o~ooooooooooooooooooooooooooooo    llllllllllmm
mmmmmm&m'm(mgl.m/m1m9m<m?mWm^m_mamemgmompm|mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm nnn"n'n2n6n9n;n<nDnEnHnInKnOnQnRnSnTnWn\n]n^n    ~kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkklll	lllllll&l'l(l,l.l3l5l6l:l;l?lJlKlMlOlRlTlYl[l\lklmloltlvlxlyl{lllllllllllllllllllllll    4j7j;j>j?jEjFjIjJjNjPjQjRjUjVj[jdjgjjjqjsj~jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjkkkk	kkkkkkk$k(k+k,k/k5k6k;k?kFkJkMkRkVkXk]k`kgkkknkpkuk}k    hhhhhhhhhhhhhhhhhhhhi	i
iiiiii1i3i5i8i;iBiEiIiNiWi[icidieifihiiilipiqirizi{iiiiiiiiiiiiiiiiiiiiiiiiiiiiiii jjjjjjjj j$j(j0j2j    fglgngtgvg{gggggggggggggggggggggggggggggggggggRhhhhh(h'h,h-h/h0h1h3h;h?hDhEhJhLhUhWhXh[hkhnhohphqhrhuhyhzh{h|hhhhhhhhhhhhhhhhhhhhh    f!f"f#f$f&f)f*f+f,f.f0f1f3f9f7f@fEfFfJfLfQfNfWfXfYf[f\f`faffjfkflf~fsfuffwfxfyf{ff|ffffffffffffffffffffffffffffffffffgggggg g"g3g>gEgGgHgLgTgUg]g    ddddddddddddddddddddeee	e
eeeeeeeee"e&e)e.e1e:e<e=eCeGeIePeReTe_e`egekeze}eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee fff	fffffff    xc|c}cccccccccccccccccccccccccccccccccccc	d
dddddd d"d$d%d)d*d/d0d5d=d?dKdOdQdRdSdTdZd[d\d]d_d`dadcdmdsdtd{d}dddddddddddddddddddd    aaabbbbbbb b"b#b'b)b+b9b=bBbCbDbFbLbPbQbRbTbVbZb\bdbmbobsbzb}bbbbbbbbbbbbbbbbbbbbbbbcc
ccccccc)c*c-c5c6c9c<cAcBcCcDcFcJcKcNcRcScTcXc[cecfclcmcqctcuc    ```````````````````````aa
aaaaaaaaaaaa"a*a+a0a1a5a6a7a9aAaEaFaIa^a`alaraxa{a|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa    o_r_t_u_x_z_}_~_________________________________________`
````````$`-`3`5`@`G`H`I`L`Q`T`V`W`]`a`g`q`~````````````````````    ]]] ^^^^^^^^ ^.^(^2^5^>^K^P^I^Q^V^X^[^\^^^h^j^k^l^m^n^p^^^^^^^^^^^^^^^^^^^^^^^^^^^________!_"_#_$_(_+_,_._0_4_6_;_=_?_@_D_E_G_M_P_T_X_[_`_c_d_g_    m\p\t\u\z\{\|\}\\\\\\\\\\\\\\\\\\\\\\\\\\]]]]+]#]$]&]']1]4]9]=]?]B]C]F]H]U]Q]Y]J]_]`]a]b]d]j]m]p]y]z]~]]]]]]]]]]]]]]]]]]]]]]]]]]]]]    ZZZZZZZZZZZZZ [[[[4[[[[![%[-[8[A[K[L[R[V[^[h[n[o[|[}[~[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\\\\#\&\)\+\,\.\0\2\5\6\Y\Z\\\b\c\g\h\i\    oYrYuYvYyY{Y|YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY ZZZZZZZZ#Z$Z'Z(Z*Z-Z0ZDZEZGZHZLZPZUZ^ZcZeZgZmZwZzZ{Z~ZZZZZZZZZZZZZZZZZZZZZ    XXXXX X&X'X-X2X9X?XIXLXMXOXPXUX_XaXdXgXhXxX|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYAY!Y#Y$Y(Y/Y0Y3Y5Y6Y?YCYFYRYSYYY[Y]Y^Y_YaYcYkYmY    VVWWW
WWWWWWW W"W#W$W%W)W*W,W.W/W3W4W=W>W?WEWFWLWMWRWbWeWgWhWkWmWnWoWpWqWsWtWuWwWyWzW{W|W~WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXX	XW    UUUUUUUUUVV
VVVVVVVV,V0V3V5V7V9V;V<V=V?V@VAVCVDVFVIVKVMVOVTV^V`VaVbVcVfViVmVoVqVrVuVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV    TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT UUUU	UUUUU*U+U2U5U6U;U<U=UAUGUIUJUMUPUQUXUZU[U^U`UaUdUfUUUUUUUUUUUUUUUUUUUUUUUUUUU    SSSSSSSS%S'S(S)S+S,S-S0S2S5S<S=S>SBSLSKSYS[SaScSeSlSmSrSyS~SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTTT!T'T(T*T/T1T4T5TCTDTGTMTOT^TbTdTfTgTiTkTmTnTtTT    QQQQQQQQQQQQQQQRRRRRRRR"R(R1R2R5R<RERIRURWRXRZR\R_R`RaRfRnRwRxRyRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SS
SS    PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQQQQQQQQPQQQQQQQ#Q'Q(Q,Q-Q/Q1Q3Q4Q5Q8Q9QBQJQOQSQUQWQXQ_QdQfQ~QQQQQQQQQQQQQQQQ    OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO PPPP
PPPPPPPPPPP"P'P.P0P2P3P5P@PAPBPEPFPJPLPNPQPRPSPWPYP_P`PbPcPfPgPjPmPpPqP;PPPPPPPPP    NNNNNN#N$N(N+N.N/N0N5N@NANDNGNQNZN\NcNhNiNtNuNyNNNNNNNNNNNNNNNNNNNNNNN OOOOOOOOOOO.O1O`O3O5O7O9O;O>O@OBOHOIOKOLOROTOVOXO_OcOjOlOnOqOwOxOyOzO}O~OOOO          	       !%      +/)57:><DHF     QM UYW[]a_ec    mqksoiu  wz~|                          
      " $    0*.(469=;CGE     PL TXVZ\`^db    lpjrnht xvy}{                     &  2  A?  J R  f                                   '138B@IK S g                                                                                                                                                                   	
                                                                      RSTUVWXYZ[\^_                                                                                                                                                                                        ^                                                                                                  "! !                              בޑ
:@<NYQ9gwxגْВ'ՒӒ%!(pWƓޓ1EH)3;CMOQUWe*+',Nٚܚur pk-ў    p!q!r!s!t!u!v!w!x!y!    בޑ
:@<NYQ9gwxגْВ'ՒӒ%!(pWƓޓ1EH)3;CMOQUWe*+',Nٚܚur pk-ў    p!q!r!s!t!u!v!w!x!y!     r$swssssssts&t*t)t.tbtttuouvvvvvFwR!xNxdxzx0yyyzzz{H}\}}}}R~GbǃHSYk !7yߊ"Sv#ώ$%gސ&'ڑ    _]````` a`a7a0aabbc`dddNe ff;f	f.ff$fefWfYfsffffffg)fggRhghDhhhiii0jkjFjsj~jjjk?l\llollmmommmmmmm9n\n'n<nnooopp(pppqq\qFqGqqqr    ~H܄Op1fhfE_(NNN OO9OVOOOOOO@P"POPFPpPBPPPPJQdQQQQRRRRR SS$SrSSSSTTTTUYWeWWWWXXYSY[Y]YcYYYV[[/u[[\\\\']S]B]m]]]]!_4_g__                                      3                    1              0        569:    78?@=>ABCD;<                                                                          /XiYdtQq                                                                                                                                                                                    ]^dQPYrozĝƝϝٝӝuy}a̞ΞϞОԞܞޞݞv!,>JRTc_`afgljwrv    "#%'()*./2DCOMNQXtʛƛϛћқԛ:	
.%$!0G2F>Z`gvx	*&#DA?>FH    qtsĘØƘ	!$ ,.=>BIEPKQRLUߙۙݙؙљ+7EB@C>UM[W_bedikjϚњӚԚޚߚ    ]_frlΖ˖ɖ͖MܖՖ$*09=>DFHBI\`dfhRkqy|z×Ɨȗ˗ܗOz8$!7=FOKkop    "#:5;\`|nV֓דؓÓݓГȓ6+5!:ARD[`b^j)puw}Z|~ʕoÕ͕̕Օԕ֕ܕ!(./BLOKw\^    OPQRI>VX^hovr}Hbې20JVXceisrɑˑБ֑ߑۑ,^WEIdH?KPZϒD.    GILPHYd`*cUvr|ƎŎȎˎێ
&3;9EB>LIFNW\bcdڏ!'659    _lot}:A?HLNPUblxz|bȌڌ
N͌gmqsύڍ֍̍ۍˍߍ	B504J    fdmjotw~ډ܉݉%6A[RFH|mlbĊ͊ڊފۊ 3&+>(ALONIV[Zk    ScjˇЇ֖ćǇƇ҇"!169';DBRY^bk~u}rÈĈԈ؈و݈
C%*+AD;68L`^    AKUmꅇw~ɅυЅՅ݅܅
"0?MUNT_gqĆƆɆ#Ԇކ߆ۆ 	
4?7;%)`_xLNtWhnY    5421@9PE/+#|su΃؃" 8m*<ZwkniF,oy5ʄbل̈́ڄЄƄք!,@cXH    F>SQqneft_Ɂ́сف؁ȁځ߁
)+83@YX]Z_dbhjk.qwx~߂҂ނ܂	ق    ELMNPQUTX_`higxqܘ!(?;JFRXZ_bhsrpvy}Qۀـ݀Āڀր	)#/K    }}}
}E}K}.}2}?}5}F}s}V}N}r}h}n}O}c}}}[}}}}}}}}}}}}=~}}}}}}}}}}}}}~
~#~!~~1~~	~~"~F~f~;~5~9~C~7~2~:~g~]~V~^~Y~Z~y~j~i~|~{~~}}~~~~~~~~~~~~~8:    z{{M{{L{E{u{e{t{g{p{q{l{n{{{{{{{{{{]{{{{{{{{{{||{{`| |||{{||{#|'|*||7|+|=|L|C|T|O|@|P|X|_|d|V|e|l|u||||||||||||||||||||||;|||||}    xxxxyyyy,y+y@y`yWy_yZyUySyzyyyyyKyyyyyyyyyyyzzzz zzy1z;z>z7zCzWzIzazbzizpzyz}zzzzzzzzzzzzzzzzzzzzzzzzzzz{{
{{3{{{{5{({6{P{    rvvvxv|vvvvvvvvvvvvvvvvvvvvvvvv/vwww)w$ww%w&ww7w8wGwZwhwkw[weww~wywwwwwwwwwwwwwwwwwwwwwxx&y x*yExxtxx|xxxxxxxxxxxxxxxx    ttttttttttuuuuuuuuu&u,u<uDuMuJuIu[uFuZuiudugukumuxuvuuutuuuuuuuuuuuuuuuuuuuuuuuuuuvuuuuvv	vv'v v!v"v$v4v0v;vGvHvFv\vXvavbvhvivjvgvlvpv    qqrrr(r-r,r0r2r;r<r?r@rFrKrXrtr~rrrrrrrrrrrrrrrrrrrrPs
ssss4s/s)s%s>sNsOs؞Wsjshspsxsus{szsssssssssttot%ts2t:tUt?t_tYtAt\titptctjtvt~ttttttts    >oonozoxooooo[oomoo|oXoooofoooooooooooooooo	ppopppopptoppp0p>p2pQpcppppppppppppp	qpqqeqUqqfqbqLqVqlqqqqqqqqqqqqqqqqqqq    lllllmM6m+m=m8mm5m3mmmcmmdmZmymYmmmommn
nmmmmmmmmmmmmmmmmm-nnn.nnrn_n>n#nkn+nvnMnnCn:nNn$nnn8nnnnnnnnnnnnnnnnnAooLpnnn?on1on2on    jjjjjjjjjjjjjjkjkk1k8k7kv9kGkCkIkPkYkTk[k_kakxkykkkkkkkkkkkkkkkkkkkkkkkkkkllll$l#l^lUlbljllllll~lhlslllllllllllll    hhh6iiihh%ihhh(i*ii#i!ihyiwi\ixikiTi~ini9iti=iYi0iai^i]iijiiiiiiiii[iiiii.jiiiiiiijji
kiiijijiji
jjj#jjDjjrj6jxjGjbjYjfjHj8j"jjjjjjj    fffff?ffffffggg&g'g8.g?g6gAg8g7gFg^g`gYgcgdggpgg|gjggggggggggggggggggggggjhFh)h@hMh2hNhh+hYhchwhhhhhhhhhjhthhhhih~hihih"i&ihih    ddddddddd	ddbdd,edddd edeee$e#e+e4e5e7e6e8eKuHeVeUeMeXe^e]erexeeeeeeeeeeeeeeeeeerg
ffesg5f6f4ffOfDfIfAf^f]fdfgfhf_fbfpfffffffffffff    b!b*b.b0b2b3bAbNb^bcb[b`bhb|bbb~bbbbbbbbbbbbbdbbbbbbbbcbb'cccbbPc>cMcdOcccccvcccccckciccccccccccd4ddd&d6ded(ddgdodvdNd*edddddd    ````````````_````Maaa`` a``a!a``aaGa>a(a'aJa?a<a,a4a=aBaDasawaXaYaZakataoaeaqa_a]aSauaaaaaaaaaaaaaaaaaaaayaaaaaaaaaa bb	bbbbb    ^^^^^^^^^^^^^^^^_	_]_\____)_-_8_A_H_L_N_/_Q_V_W_Y_a_m_s_w_____________________`_!`````)``1```+`&``:`Z`A`j`w`_`J`F`M`c`C`d`B`l`k`Y``````    P\O\q[l\n\bNv\y\\\\Y\\\\\\\\\\\\\]\]]]\]]]]]"]]]]L]R]N]K]l]s]v]]]]]]]]]]]]]]]]]]]]]^^^^^6^7^D^C^@^N^W^T^_^b^d^G^u^v^z^^^^^^^^    xYYY^OOYYYYYYYY%ZZZZ	ZZ@ZlZIZ5Z6ZbZjZZZZZZZZZZZZZZ[[[2[Z*[6[>[C[E[@[Q[U[Z[[[e[i[p[s[u[x[ez[[[[[[[[[[[[[[[[[[[\\\\\ \"\(\8\9\A\F\N\S\    WWWWWWUW&W7W8WNW;W@WOWiWWWaWWWWWWWWWWWWWW
XWWXXXrX!XbXKXpXkRX=XyXXXXXXXXXXXXXXXXXXXXXXXXXXY
YYYh%Y,Y-Y2Y8Y>YzUYPYNYZYXYbY`YgYlYiY    TTTTTTTTUUTTTTT9U@UcULU.U\UEUVUWU8U3U]UUUTUU{U~UUUU|UUUUUUUUUUUUVUVUUVUNVPVq4V6V2V8VkVdV/VlVjVVVVVVVVVVVVVVVVVVVVVVV WVW	W    RRRRRRRRRRRRRRRSS8uSSSSS#S/S1S3S8S@SFSESNISMSQ^SiSnSY{SwSSSSSSSSSS|ٖSfqSSSST=T@T,T-T<T.T6T)TTNTTuTT_TqTwTpTT{TTvTTTTTTTTTTTT    PPPPPPPPPPPP	QQQQQQQ!Q:Q7Q<Q;Q?Q@QRQLQTQbQziQjQnQQQVQQQQQQQQQQQQQQQQQQQQQQQUQQQQQRRRR'R*R.R3R9RORDRKRLR^RTRjRtRiRsRR}RRRRqRRR    _NN*N1N6N<N?NBNVNXNNNkN_NNNNNNNNNNNNNNNNNN	OZO0O[O]OWOGOvOOOO{OiOpOOoOOOQOOOOOOOOOOP(PP*P%PPOO!P)P,POOPPCPGPgUPPPHPZPVPlPxPPPPPP    #,BTojp2RAZ^_g|iijmobrr{~KΐmQy2֊-PTqjkČ`gNNkh i~nxU                                                                                          uψ̑x_szNceuRAmn	tYukx|zOnae\NNP!NQ[ehmsBvwz|oҊ|ϑuR}+PSgmq3t*W`tAXm/}^N6OOQR]`s<yӂ4
bftkRRp^K`a#oIq>|}o    8/UQO*QRS[}^`ac	gggnm6s7s1uPyՈJĖYNYON?P|^Y[^ccdfJiimnq(uz IɄ!
e}
~ab2kltmmeg<ma}=jqNuSP]koͅ-)RTe\Nghtt    +osT*gE]{\[JnфzY|l wR"Y!q_rw'aiZZQT}TfvY]rnMQh}}bxd!jY_[ksv}2Q(gٞvbgR$\;b~|OU`}S_NQY:r6Α%_wSy_}3VgS	aalRv    llp2x+~ހ*JҒlONNPVRJWY=^__?bfgghQ!} ~2 T,SP\SXd4ggrfwFzRlk XL^TY,gQvidxTWY'fgkTiU^ggR]hNOSb+glďOm~Nban    yym_UblNirR;TtVXanbqnY||}e^NuOuQ@Xc^s^
_g&N=[s|PXVvx%Rw{OP	YGr{}ԏMOR)Z_OWUcik+u܈BzRXUa
bfk?|#POSFT1XIY[\\)]^bgc>eeg    ;gz9Suf_񃘀<__buF{<ghYZ}~v,Oj_j7lothyhUy^cuyׂ(򒜄-Tl_e\mpӌ;OetNNW+YfZ[Q^^`vbweenfnm6r&{P\tDOdfkaj\SizWOoR_E^g    Q{rx{H{ja^Qu`ukQbnzvOpbO{zVYX䆼4O$RJSSS^,deg>lNlHrrsTuA~,酩{Ƒiq=cifjuvxC*SQS&TY^|_`Ibybbekluvxy}w^ۘj8|P>\_gk5t	w    Y?\NY_oyby[q+sqt^_{cdq|CN^KNWV`o}3]bdwgl>m6t4xFZuO^bcWeogvLr̀)MPWZhsidqrXjyw)/OeRZSbgl}v{|6f or~    ciFv-0ؕPRTX\admwzS\?S__myrcwy{krhajQz4iJ\[IpxVo\`felZAQTfHYQMNQXpzcKbi~wuWS`iߎ]lN<\_Sьy^esNeQ    -ؑlXdduenv{iѓnT_dMDxQkX)YU\^m~u[pOko0uNQT5XWXY`\_e\g!n{v߃M%x:xR^WtY`PZQQQ RUTXXXWY[\]`b-dqgChhhvmonmopqS_uwyI{T{R{|q}0R    ^3^^_5_k__acfgnoRr:u:wt9xv܊󍚒wRWcvglsÌs%mXiiuZXhciCO,og&}T?ipojWX,[,}*r
T㑴NNO\PuPCRHT$X[^^^^_`b:cch@lxyz}GD    SFOTjY1]zh7rH=j9NXSVfWbceNkm[npwz{}=ƀˆ[VX>_efjk7uǊ$Pw0W_e`zf`luznE{\uzQ{Ąyz6Z@w-NN[_b<fglkw;NЙj&p*sWNFQQU[    Ӂ5 OtPGRsSo`Ic_g,nO^\ʌe}RSvQcX[k[
\dQg\NY*YplQ>UXY`Sbg5Ui@ę(SOX[\/^_ `Ka4bfln΀Ԃ .۞ۛNS'Y,{Ln'pSSDU[Xbbblo"t8o8QS    J~z9nΌxwMRU8o6qhQyU~|LVQX\cffZiruuyVyy| }D}4;a PuRSS	PUXOY=r[d\S``\cc?ccdef]iioqNuvz|}}aIXlňpmPXa    ozd[N,p]u/fQ6RRY_'`b?eteftfhhcknrruv|VXˊRYez-^`befgwMzM|>~
d_xRbcBdb-z{v}INHQCS`S[\\]&bGbdh4hlEmmg\oNq}qez{}    bikqT~wrߘU;\8OOOU Z[[_Na/ceKfhixmm3uuw^yy3}は:2ݑNNRuXX\u=\N
ŏcm%{ϊbVS9TW%^c4lpaw|pBT^tĚ]i]pegۖncIgiŃ    R SGSSTFU1UVhYY<Z[\\\\^^^p_bbbcwcff-fvf~ghj5jlm	nXn<q&qgquw]xyeyyz{|9}փI]<Tsaތf~
NNNWNQpRW4XX"[8^`dagVgDmrsuczr 1VW    [1\]Oab2myyB}M~Frt/1KlƖNOOEQAS_bgAlncs&~͑SY[m]y.~|~XqQSO\%fwzQ_eoikmndov}]uQR@bffn^}rfRSsY^_U`dPQ    !knl>rtux:y3ꁔPl_X+z[NSW1YZ[`nouꌟ[ {rPga\J~Q\hcfenq>y}ʎnǆPR:\Sg|p5rLȑ+[1_`;NS[Kb1gkrs.zkRQSjT[c9j} VShT    [bdd-gkіv֛LcvRf	NPSq\`dce_hqs#u{~یxefkNN:OO:RSSUVXYYYP[M\^+^_`c/e\[eeegbk{klEsIyy|}+}󁖉^ifǌ܌̖okN<OOPQW[[HacBf    dkNVdWXZZh`aff9hhmu:}nBNPOSUo]]]glstxP߈PW^+cPPQ gT^XY[i_Mbc=hskn}pǑrx&xmye0}܃	dR(WPgjQBW*:XiT]Wx\OJRT>d(fggzV{"}/\h9{SQ7R    TUQWW}YT[][[]]]x^^^^_R`Labbc;efCffmg!hhi_l*mim/nn2uvlx?z|}}^}}T*RLaʐuq?xMؚ;[RRSTXboj_KQ;RJTV@zw`ҞDs	opu_`r    i)j}rr.sxoxy}wҎcuzUxCQSS{^&_nnssC}7 PNNPS|TVYd[]^'_8bEegVnr|N7ǖgNNOHSIT>T/Z__`hjZtxw^NɛN|OOPPIQlQRRRSST    czltazq|hp~QhlRT͎fSAyOPRDQSU-WsWQYb__u`vagaac:dleofBhnfu=z|L}}K~kJ͆cfΏ蛇RbdoAhP kzlTotzP}@#gN9P&PeP|Q8RcRUWXZ^aabrc    OOPGQzqQQTS!SSSUX\7_J_/`P`m`cYeKjlrrwNWZNQ-\fmi@\fuisPh|PRGW]&e#k=k4tyyK{}̃_9яёT]N6PS:Srsw悯ƙșҙwQa^UzzvP[G2NjQ\H\    _j0^kl}luHyc[ z }_w̎<N}P QY[/bbd:kruGypcʃ	TTUThXjp'xug͞tS[PNENNOS8T[_%`Qe=gBlrllxptvzz{}|f}e[rSE\]bbc nZ1ݍoyZNNN    |Rłt~NOQ[
RRR]U*XY[[[r^y^`acaacbegShh>kSkWl"ooEotuvwz{!|}6f̊Qeӗ(8N+T\]sLv<w\TXOOqSUhVWGY	[[\^~^_c:geeghh    AffhwmppLuvu}QRYT[]haimx˄WrlmنWgΆRVT^bd<h8hkrsxkz҉k퐣if[\}iMNc {+jjh_orRUp`b;mnn[DN9Si:j*h\Qzܑ[V("h1    be*j'kksV,Ğ\l{QK\aƁvharYNOxSi`)nOzNSNUO=OOsORS	VYZ[[yfggLklkpsyy<z{ۂwӃf)VNO\bYr;u偽ŖՙNOVJXX^_*``b`abb9e    bpTS[poS\zNx&nVUk;YSfmtBVNKOSU0[q_ ffh8ll)m[tvNz4[`풲muvř`iSQW0XDY[^(`cclopqYqq?s~vт`[iXeZl%uQ.YeY__    NUZ?Ta(cY"uPz`c%nefh'Weqb[Y{b}}b|[^	cfHhǕOgN
OMOOIPV7YYZ	\`apafipOupuy}}ÀcUz;SNNWx NXn82z(/AQpSTTVY_m-    ."""                                  00                                    0  0000                                                                                                    I3"3M333333N336333'3Q3J393W33B3#3&3;3+3               33*313G3                                                                      ~3}3|3{3                                  3        `$a$b$c$d$e$f$g$h$i$j$k$l$m$n$o$p$q$r$s$`!a!b!c!d!e!f!g!h!i!  I33"3M33'3363Q3W33&3#3+3J3;33333333                {300!3!!22222122292~3}3|3R"a"+"."""" """5")"*"  2    d&g&a&b&`&c&e&f&                         0&0                                  &&&&!!!  !!!!                                                                                        33333  33333  3333!33333	!333333                                                                                                                          !3!!      `!a!b!c!d!e!f!g!h!i!j!k!                p!q!r!s!t!u!v!w!x!y!z!{!                                                        $$$$$$$$$$$$$$$$$$$$$$$$$$                    `$a$b$c$d$e$f$g$h$i$j$k$l$m$n$o$p$q$r$s$                    t$u$v$w$x$y$z${$|$}$~$$$$$$$$$$                    v'w'x'y'z'{'|'}'~'                        $$$$$$$$$             %%%%%%%,%$%4%<%%%%%%%#%3%+%;%K% %/%(%7%?%%0%%%8%B%                                                                                                                                 !"#$%&'()*+,-./                              012345Q6789:;<=>?@ABCDEFGHIJKLMNO                                                                                                                              00000000000000000000000000000000000000000000000000000000000000000000000000000000000000                    A0B0C0D0E0F0G0H0I0J0K0L0M0N0O0P0Q0R0S0T0U0V0W0X0Y0Z0[0\0]0^0_0`0a0b0c0d0e0f0g0h0i0j0k0l0m0n0o0p0q0r0s0t0u0v0w0x0y0z0{0|0}0~0000000000000000000000                                                                      !"#$%&'()*+,-./0123456789:            ABCDEFGHIJKLMNOPQRSTUVWXYZ            %%%%%%%; 0!!!!0                      """"""*")"                '"("!! ""                       ""#""a"R"j"k""=""5"+","              +!0 o&m&j&  !          %    %%%%%%%; 0!!!!0                      """"""*")"                '"(" !! ""                       ""#""a"R"j"k""=""5"+","              +!0 o&m&j&  !          %     000000 @ >?00000N0000  <^%"\& %     	00;=[]0	0
00000000   `"f"g""4"B&@& 2 3 !
  &&%%%%     000000 @ >> ?00000N0000  <0 \& %     	00;=[]0	0
00000000"   `"f"g""4"B&@& 2 3 !   
  &&%%%%;  O   4.  /  1  2  4  T5   64  6H  7  8  9  :  T:  t:  $;0  ;D  =h  ?  @  B0  tF\  G  G  TH  tJ  N  DN   QL  tT  U  U  V  V   V4  VH  X  X  Z  Z  Z   [@  ]  4^  ed	  $h	  k	  k	  k	  4l
  d
  
  
  
  
    $4  Tl  4  t  đ    ,  @  $`      $     @      Ĭl      $$  D8  dL             zR x  $      +   FJw ?:*3$"       D   ,p             \    /.          p   /            1    H f
B        ,2             2       4      T3n    BRD C(D0H(A ABB      3   E\
O        5J    E   ,   <  P5    FFE 
CBK      l  6J    E        D6            P6            6             h7   ED0
AH \     T9   FBA C(F0z
(A ABBN`
(C ABBHT
(A ABBFP   H  :O   LAC 
ABIP
ABE^
CBMA
CBJ        ;>      (     <U   AGD0D
AAF 0     A    BDD L@u
 AABA       |Aw    H l
D     ,  A    H c
E    H  B   H0
H $   d  D   H F
B
Fp       H,       (     H   gHH JEA      K   LAC g
ABFi
ABDQ
HBM
ABFK
AHTb
EBGY
EBHZ
FDL    P  M          d  N          x  N            pO            lO
            hO
       H     dO   FBB B(A0D8DH
8A0A(B BBBI     P
       L   (  P   FBE B(D0A8Di
8A0A(B BBBE      x  R
            R'            R    D
HS \     S   AAF 
AAHN
AAHO
AAGn
AAH@
AAF   (      T    ECF o
AAI     L  `Uv   FBB E(A0A8DP
8D0A(B BBBF
8A0A(B BBBHf
8A0A(B BBBH
8A0A(B BBBK H     H\p   BBB B(A0A8DP
8A0A(B BBBA   0  l^U         D  a4    EAU     `  a    EAF     |  aJ    Gx   H     b   BBB B(A0A8D{
8A0A(B BBBE     }    ^Z
Hz ,     ~   H i
GW
Ay
G
G   4  ؀V          H  $       8   \  f    bEE D(C0k(A BBB        ԁ)   H `
H  4     0   EAD 
CABY
CAC X         ECF F
CAHT
EAFS
EAGM
AAAN
AAH    H	  d8          \	  C    KO
Fb    |	  K          	  v    TnN     	  `I          	  =    Dg
EH   @   	     [l
IG
Ie
K`
HDTV
JQ @   $
  H   Es
Hj
Fs
ET
Lx
H|
Do
Is   h
  #   j   
     H0X
H     
  u   H t
D
F  `   
  <	   RBB A(A0^
(A BBBC
(D BBBKn
(A BBBK t   $  h    BEH E(A0A8D@l
8A0A(B BBBHj
8A0A(B BBBDH8F0A(B BBBL        ET
GV
Jh
Hh
HQ
O
K
EK
E L     P   BIB B(A0A8DL
8A0A(B BBBE      <  кO   H 
E H   X  >   FBE H(D0D8DP
8C0A(B BBBA                         0        FAA G
 AABB      l   H0        `   E              GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 #                             H          ؇          ߉                                                  )          .                                   	          $     (     +     -          8     =     A          I     $     i     Q     T     ]     `     r                                              u     &     z                    D          L          T          c          [          k          v                              &          2                    ܇                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             y+             +             +             +             +             +             +             
,             P                         #                          #                   o    `             U                   
       7,                             $            (                           (             p             Y      	              o    0      o           o          o                                                                                                                                                                                                                                                                                                                                                                                           #                                                                                         0      @      P      `      p                                                                
   BB             ?                                                 0B     0B                                     ^     j     y                         Ɖ     щ                    @            @     P=            @            @     P=      !      !      !      !      !      !      !            !                           ͆                             0L                                                0J                   H                             `H     0B             r                                                                                        P                                                                             @            @            @            @                   GA$3a1 P                    GA$3p1067                        GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY            N               GA+GLIBCXX_ASSERTIONS   nkf.so-1.8.7-16.el8.x86_64.debug    7zXZ  ִF !   t/-}] ?Eh=ڊ2NĊ_9ĴIy _3YRfB)U:NX[4F|4}I}|=δS\?Ұ^F*h	jϕ+#/#]݂hW(+MNCU$
5$&EUo-Jr;vr:G@xxLpH9O~Q#**O{xPi lz8?b57I
1揱GXFuV^.7p-Tpe@J({Yf;8	>*gxX1Wj F>KmmEt6uBˇmZ߹ASH7ڌcה_PWiYj}#Vairs/C
0+	4%y=6G=ԨSMUsF
E۳\20L|m:ԢZ* P
Xv\7Б,y.Άɱ`{݄+ ,)Vaw2lx
T0u[\d	sm7*Gο4|l<,T%ĀJ.c`h՝fzu FG+i	Ѯz~uq]ɴSh~qLپnłÓ%z3z5g0Onߌ̜*dAĿF %ɸ~<4@y9a[.&u}i|v`"Y'6w8vݹxlXYpF1Vyi57<VK!Aj<
ڻ1n|,=Kq՞MJ2Z}x=WSI;텲+
kuIbt#(dٯA<ks2msUYt(iЦE|y5af^)޵J?n]fd鰊&i8^4ğ-COȶ͓`H"c]D[Ѱ_F}F9tcI|&%}\*ףK	5?]}՚˅tQ 0|AXu1֋Lfyb`یvm_ ]2|~kDOTQ,-Ef܆1V4K_
P;+)CIneWwѹ4_vLMJ;=#8'j7\ے.l`R*%,`Q!f U%D*89 PHq "e)rߒ5rz2ݵvq2}/v'7Y4/S{
O]ƂuM{omզ֠6أ8jB&x	z[l${ O,kr+-}L->IGy"@J@YpnQKyDŌ-OmtNSZk^5pNQpwcΨNz+ԫ  Ŷu0?t45vG^zpU2q"
*f;u(S#ĕ]𞕙]T=W+M~,q5
j-#e.cT&b]9[eu.UP"l    =2/ZQ Z  5sg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                     8      8      $                                 o       `      `      T                            (                          ?                          0             U      U      7,                             8   o                   @                           E   o       0      0      @                            T             p      p      Y                           ^      B       (      (      (                          h             P      P                                    c             p      p                                  n                         p                            w             `      `                                   }                                                                              /                                          <     <                                                         8                                                                                                #                                                    #                                                    #          5                                           #          0                                        #                                                      $                                                       $                                                       $                                                      d          H                                                  @     (                              "                     h                                                        (     1                             PK     Y\wAC      x86_64-linux/curses.sonu ȯ        ELF          >    P-      @       Ⱦ          @ 8 	 @                                 @      @                                      0      `                                         P      P                   8      8      8      $       $                                                                Std                                               Ptd                                        Qtd                                                  Rtd                                                 GNU Őh^%}Zړ+0z       v         @    v   x       BE|qX                            V                                                                                                                                                                           ,                                                                V                                                               
                     a                                          N                                           }                                                                                                                                                     z                                          l                                                                                                         q                                                                                    p                                                                 W                                          v                     +                                                                                    -                                          h                     '                                          ^                                                                                    [                                                                                                                                 O                     [                                           `                      d                                                                                                                              E                                          ]                                                                                                                                                   i                      ;                                          U                                           n                     7                                                                                                                                                                                                                                        M                                          8                                           ,                       C                                                               '                     F   "                   I                     7                     g                                                                                      B                                                                   8                  h                   ]      ,          8               __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize LINES COLS stdscr isendwin rb_gc_unregister_address rb_eRuntimeError rb_raise ruby_safe_level rb_check_type rb_num2int wattrset rb_fix2int rb_eSecurityError wattr_on rb_block_given_p rb_yield wattr_off wresize wscrl wsetscrreg wcolor_set wmove mvwin delwin free ruby_xmalloc rb_data_object_alloc rb_scan_args wborder waddch rb_num2long __stack_chk_fail rb_uint2inum wtimeout nodelay wbkgd wbkgdset keypad idlok scrollok winsdelln wdelch stdin rb_read_check wgetnstr rb_tainted_str_new2 wgetch rb_str2cstr waddnstr winsch winch wnoutrefresh wrefresh wclrtoeol wclear subwin rb_obj_class rb_obj_alloc rb_secure initscr newwin reset_prog_mode def_prog_mode rb_num2uint mousemask rb_int2inum mouseinterval ungetmouse pair_content rb_ary_new3 color_content can_change_color has_colors init_color init_pair start_color resizeterm curs_set keyname rb_str_new2 ungetch flash beep nonl nocbreak noraw noecho doupdate Init_curses rb_define_module rb_define_module_under rb_gc_register_address rb_cObject rb_define_class_under rb_undef_method rb_define_method rb_define_module_function rb_define_alias rb_cData rb_define_alloc_func rb_define_const __sprintf_chk rb_set_end_proc rb_cFixnum rb_cFalseClass rb_cNilClass rb_cTrueClass rb_cSymbol libruby.so.1.8 libncurses.so.6 libtinfo.so.6 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.3.4 GLIBC_2.4 GLIBC_2.2.5 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                                                                                           ti	        ii        ui	                       .                   -                         p                    x                             	                                                                                '                    ;                    @                    B                    E           ȯ         L           Я         T           د         U                    _                    g                    l                    u                                                    (                    0                    8                    @                    H         
           P                    X                    `                    h                    p                    x                                                                                                                                                                                                        Ȱ                    а                    ذ                                                  !                    "                    #                     $                    %                    &                    (                     )           (         *           0         +           8         ,           @         -           H         .           P         /           X         0           `         1           h         2           p         3           x         4                    5                    6                    7                    8                    9                    :                    <                    =                    >           ȱ         ?           б         A           ر         C                    D                    F                    G                    H                     I                    J                    K                    M                     N           (         O           0         P           8         Q           @         R           H         S           P         V           X         W           `         X           h         Y           p         Z           x         [                    \                    ]                    ^                    `                    a                    b                    c                    d                    e           Ȳ         f           в         h           ز         i                    j                    k                    l                    m                     n                    o                    p                    q                     r           (         s           0         t           HH  HtH             5B  %C   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   h2   h3   h4   h5   h6   h7   qh8   ah9   Qh:   Ah;   1h<   !h=   h>   h?   h@   hA   hB   hC   hD   hE   hF   hG   qhH   ahI   QhJ   AhK   1hL   !hM   hN   hO   hP   hQ   hR   hS   hT   hU   hV   hW   qhX   ahY   QhZ   Ah[   1h\   !h]   h^   h_   h`   ha   hb   hc   %  D  %  D  %  D  %  D  %݈  D  %Ո  D  %͈  D  %ň  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %}  D  %u  D  %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %݇  D  %Շ  D  %͇  D  %Ň  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %}  D  %u  D  %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %݆  D  %Ն  D  %͆  D  %ņ  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %}  D  %u  D  %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  H=  Hڅ  H9tH  Ht	        H=  H5  H)HHH?HHtH=  HtfD      =m   u+UH=   HtH=6  dE  ]     w    H  Hc HD ff.     Hu  Hc HD ff.        fD  HHI  H8 t	vt"H      H=  Hg    f     PXH5[  HH  H81bfPXH5[  HH  H81BfUHSHHu	HubH  8hH߾"   )H[ H; tJHu'H;HH[]HD f.         H   u1.H  H5c  H81fD  ATUHSHuH   H  8   "   HsLc I<$    H@u+I<$1҉yHcH\\upH[]A\I<$1҉NHcH\1tHHI<$1 H[]A\     H   S>fD  HHx1H~  H5b  H81uD  UHSHHu	HubH~  8hH߾"   YH[ H; tJHu'H;1fHH[]HD          H   u1^H?~  H5a  H81fD  AUIATIUSHHuH   H ~  8   "   HHk H}  tyLAu>ALAt>AH} H[]HA\A]fD  LAu    H   t_1oHP}  H5`  H81    UHSHHu	HubH}  8hH߾"   H[ H; tJHu'bH;H[]HfD  K    H   u1H|  H50`  H81&fD  AUIATIUSHHuH   H`|  8   "   HHk H}  tyLAu>LAt>H} H[]HA\A]fD  sLAuS    H   t_1H{  H5A_  H817    UHSHHu	HubH{{  8hH߾"   H[ H; tJHu'H;1H[]H fD  H   u1Hz  H5^  H81fD  AUIATIUSHHuH   Hz  8   "   HZHk H}  tmLAu6LAt6H} TH   []A\A]@ LAu    H   uk1;Hz  H5]  H81 AUIATIUSHHuH   Hy  8   "   HzHk H}  tmLAu6!LAt6!H} H   []A\A]@ LAu    H   uk1[H<y  H5\  H81 SHH?HtH1y  H;8tH[vfD  H?Ht_        SH   NHH1H     H[fPXH57\  HHx  H81"fSHu	Hu:Hsx  8>"   HHC H Ht H@
[HD f     H   u@1yf     SHu	Hu:Hx  8>"   HHC H Ht H@[HD f     H   u1	f     SHu	Hu:Hw  8>"   H1HC H Ht @[HHD D  H   u`1f     SHu	Hu:H#w  8>"   HHC H Ht @[HHD D  H   u1)f     AWAVAUATUHHQ  SH(dH%(   HD$1HLL$LD$@uH  Hxv  8R  "   HH] H; +  H|$@  HAAH<$@  HAHH;E1Ej DDj j H|$0H H   @#  HHAH%  D0DxH1H    .  H)DhH1[H       FHhH;11OH;DtH;1҉8H;D]H;D H;DEH;D1H;D-H;DDHL$dH3%(         H([]A\A]A^A_    HE    cND  SAHHAEfD  [Hh HDhfH|$A@uXH<$A@H<$A@u;12Ht  H5W  H81HAHHff.     @ SHu	Hu:Hs  8>"   HaHC H Ht H@[HD f     H   u1f     SHu	Hu:HSs  8>"   HHC H Ht H [HD f.     H   u 1Yf     PXH5V  HHr  H81rfSHu	Hu2Hr  86"   HaHC H Htx[@ H   u SHu	Hu2Hcr  86"   HHC H HtHcx[K H   uX# SHu	Hu2Hr  86"   HHC H HtHcx[ H   u SHu	Hu2Hq  86"   HAHC H HtHcx[ H   uc SHu	Hu2HCq  86"   HHC H HtH8[+ H   u8 HHt kHH	%  Hf     ;HH	%  Hf     PXH57T  HHp  H81"fUHSHHu	HuZHkp  8`H߾"   	H[ H; tBHuH;H   []@     H   u1QUHSHHu	HuRHo  8XH߾"   yHC H8Ht81H@H[]Hf     H   u1f     UHSHHu	HuRHKo  8mH"   Hm H} HtLt7HH,H[]Hf.     HE    u@ HxH} 1$@ UHSHHu	HuBHn  8]H"   IHm H} Ht<t'HH<H   []HE    u@ HH} 1Y@ SHu	Hu:H#n  8@H߾"   HC H8Ht 1N   [    H   u11'    SHu	Hu:Hm  8@H߾"   QHC H8Ht       [@ H   u1~1    UHSHHu	HuRH;m  8XH߾"   HC H8Ht81H@;H[]Hf     H   u1)f     SHu	HuBHl  8HH߾"   QHC H8Ht(   [HfD  H   u1vUHSHHu	HuJH;l  8PH߾"   HC H8Ht01H@H   []    H   u11UHSHHu	HuJHk  8PH߾"   YHC H8Ht01H@;H   []    H   u1vSHu	Hu:HCk  8@H߾"   HC H8Ht       [@ H   u11G    SHu	Hu:Hj  8@H߾"   qHC H8Ht [   [@ H   u11    SHu	Hu:Hcj  8@H߾"   HC H8Ht    [f     H   u1.1g    USHH  dH%(   H$  1u	HuoHi  8z"   HvHk H}  t[Hi  HH8yH}   HHH$  dH3%(   uH  [] H   u`1i1fH-i  SHH8	u	Hu;H$i  8AH߾"   HC H8Ht![Hc     H   u11'    HtvUHSHH@tLHh  8eH߾"   KH[ H; tGH1H;HH   [] HtH   u@    1S1ff.     S1HQH[ff.     UHSHHu	HuBHg  8]H"   Hm H} Ht<t'HH<H   []HE    u@ H(H} 11fUHSHHu	HuBH[g  8]H"   Hm H} Ht<t'HH<H   []HE    u@ HH} 1	1BfSHu	Hu:Hf  8@H߾"   qHC H8Ht [HD     H   u11    SHu	Hu:Hcf  8@H߾"   HC H8Ht 0   [f     H   u1.1g    SHu	Hu:He  8@H߾"   HC H8Ht    [f     H   u11    SHu	Hu:He  8@H߾"   !HC H8Ht    [f     H   u1N1    SHu	Hu:He  8@H߾"   HC H8Ht    [f     H   u11    SHu	Hu:Hd  8@H߾"   AH[ H;Ht PH       [fH   u1n1    AVMAUIATIUSHH   LA   LAA   ~LAA   iAuH   Hc  8   H߾"   gHC H8H   EDDHHH   H["   HHHC H(H[]A\A]A^     H   unfLALAALAAmAH.c  H5<=  H81m1Hb  H5XF  H81Nff.      U   SHH5f  HtHH[]fD  Hb  H;HtAGH+H=f  HtE3"   HHHC H(HHe  H[]Hdb  H5<  H81HLb  H5Z<  H81ff.     AWIAVIAUATMUHSH   H51H߾"   aLk I} HtoLAtvHAtvLAtvALAt5DDHH&Im HH[]A\A]A^A_    HAu{LAukAfD  H11HHff.     H1HHff.     S1HH߃t!H`  H83   [@ ff.     @ S1HH1[     S1HQH߃tt[HK    S1Hu	Hu;H_  8AH߾"   JHC H8Ht![H@ H   u1aU1SH   H=b  1H5H     HH3   HHE H   HEHH[]D  S1H1H߃tT[H%  HD  +[H%  Hff.     SHHdH%(   HD$1H߃tWHT$Ht$HT$Ht$1   HTHt6HL$dH3%(   uH[     SHHdH%(   HD$1?H߃tgbHL$HT$Ht$HL$HT$1Ht$   HL	HTHt6NH\$dH3%(   uH[     qH1HHff.     H1HHff.     AU1IATMUHSHH?LAtvaHDtvPH߃tv@LAt4/DH[]HA\A]f.     fD  HDuH߃uD  AT1IUHSHxHtXH߃tXLAt'z[]A\HfD  CfD  3H߃u#ff.      H1,HHff.     U1HSHHH߃tAHt"ǉH[]Hf    {    S1HAt,HHHZ  H8[Hf.     HH@ S1HtHHHZ  H8G   [H@ S1HH=]  H1[ff.     @ S1HH=]  H1[ff.     @ S1HQH=]  H1[ff.     @ U1HSHHH߃tQ<Ht2-HY  H8H[]H             S1HH߃t)HSY  H8C[HfD      S1HQH߃t!t[HfD  Cff.     @ S1HH߃t!$Ht!H[    Hu߸   [H1HrX     H8   H H1HBX  H8   H H1QHX  H8   H     SH  dH%(   H$  1H	HW  H8zHW    HH8HH$  dH3%(   u	H  [jf.     HH9W  H81HSW  H8HHc7    S1HaHt!1HHH
W  H8*   [ S1H!tHHHV  H87   [H8@ S1HtHHHV  H8   [H@ H1HbV  H8HHD fD  H1qH2V  1H8`   HfD  H1AHV     H8-   H U1HSHH	H߃tI,Ht*HU  H8jH   []fD      ff.     @ S1HH߃t]   [fD  D   [ff.     fH1Al   HfH1!   HfH1<   HfH1L   HfH1|   HfH1|   HfH1   HfH1a\   HfH1A,   HfH1!l   HfH1HS  H8R   H     H1HS  H8R   H     H1   HfH1HBS  H8B   H     H1QLHHff.     H1!tH]V         H kf     AUH=-  ATUSH(dH%(   HD$1H5,  HH%V  H=U  H
V  mH&R  H=U  H5,  HpHU  +  H+  H+  H+  <+  HxH5,    Hl$H=U  1HrH5j,  L-2  H=`U  1HH5.  H=DU  1HsH5,  H=(U  1HH5,  H=U  1H{H5+  H=U  1HH5+  #H=T  1HCH5+  H=T  1HH5+  H=T  1H;H5+  H=T  1HH5u-  H=|T  1HSH5+  H=`T  1HH5m+  {H=DT  1HH5W+  _H=(T  1HH5F+  CH=T  1HCH5(+  'H=S  1HH5+  H=S  1HH5*  H=S  1HH5*  H=S  1HSH5*  H=S  H*  H5*  H=fS  H*  H5*  H=LS  1HH5*  gH=0S  1HH5k*  KH=S  1HkH5T*  /H=R  1H/H5=*  H=R     HH5$*  H=R     H!H5*  H=R  1HH5)  H=R  1HH5)  H=fR  1H=H5)  H=JR     HH5)  bH=+R     HH5)  CH=R     H H5)  $H=Q  1HH5:)  H=Q  1H(H5U)  H=Q  1HH5@)  H=Q  1HH5*)  H=}Q  1HDH5)  H=aQ     HH5)  yH=BQ  1HH5(  ]H=&Q  1HH5(  AH=
Q     H.H5(  "H=P     HH5(  H=P     H H5(  H=P     HH5x(  H=P     HH5a(  H=oP     H3H5I(  H=PP     HH52(  hH=1P     HeH5o)  IH=P     HH5'  *H=O     HH5'  H=O  1HkH5'  H=O     HH5'  H=O     HH5'  H=zO  1HqH5'  H=^O  1H%H5'  yH=BO     HfH5}'  ZH=#O     HH5l'  ;H=O     H8H5Z'  H=N     H)H5F'  H=N  1HH58'  H=N     HH5'  H=N     HH5'  H=lN     H`H5&  H=MN     HH5&  eH=.N  1HH5&  IH=N  1HYH5&  -HJ  H=M  H5&  H`H59HHM  H=M     HH5&  KH=M     HH5m&  ,H=uM  1HH5X&  H=YM  1HpH5v$  H==M  1HH5`$  H=!M  1HXH5&  H=M  1HH5%  H=L  H]H5%  H=L     HH5%  bH=L     HH5$  CH=L     H0H5%  $H=mL  1HDH5u%  H=QL  1HH5^%  H=5L  1H<H5G%  H=L  1HH50%  H=K  1H$H5%  H=K  1HH5%  |H=K  1H<H5/#  `H=K  1HH5#  DH=K  1HH5	#  (H=qK     H5H5"  	H=RK     HH5"  H=3K     HH5"  H=K     H(H57$  H=J  1HH5R"  H=J  1HH5m"  tH=J  1HH5X"  XH=J  1HH5B"  <H=J  1HlH5/"   H=iJ  1HH5#  H=MJ     HH5z#  H=.J     HH5d#  H=J     HH5!  H=I     HH5!  H=I     HH5!  iH=I     HH5"  JH=I     HwH5"  +H=tI     HH5O!  H=UI     HH58!  H=6I     HH5 !  H=I     HH5	!  H=H     HH5F"  H=H  1HH5'"  tH=H     HH5"  UH=H     HRH5>!  6 ܿH=H  H5!  H1迿H=hH  H5!  H   蟿H=HH  H5!  H   H=(H  H5!  H   _H=H  H5!  H   ?H=G  H5w!  Hy   H=G  H5_!  HY    H=G  H5E!  H9   ߾H=G  H5,!  H   迾H=hG  H5!  H  @ 蟾H=HG  H5   H   H=(G  H5   H   _H=G  H5   H   ?H=F  H5   Hy   H=F  H5   HY   H=F  H5   H9    ߽H=F  H5x   H   @追H=hF  H5^   H   蟽H=HF  H5I   Hٿ1肽H=+F  H54   H輿   bH=F  H5    H蜿   BH=E  H5
   H|   "H=E  H5  H\   H=E  H5  H<   H=E  H5  H   ¼H=kE  H5  H   袼H=KE  H5  Hܾ   肼H=+E  H5  H輾   bH=E  H5  H蜾   BH=D  H5t  H|   "H=D  H5d  H\   H=D  H5[  H<@   H=D  H5R  H    »H=kD  H5B  H   袻H=KD  H53  Hܽ   肻H=+D  H5#  H輽   bH=D  H5  H蜽   BH=C  H5  H|   "H=C  H5  H\   H=C  H5  H<    H=C  H5  H @  ºH=kC  H5  H   袺H=KC  H5  Hܼ   肺H=+C  H5  H輼   bH=C  H5  H蜼   BH=B  H5  H|   "H=B  H5  H\   H=B  H5  H<   H=B  H5|  H   ¹H=kB  H5h  H袹H=KB  H5S  Hܻ   肹H=+B  H5D  H輻  bH=B  H5:  H蜻  貵H=A  H5  H|  "H=A  H5  H\  rH=A  H5  H<  H=A  H5  H  2H=cA  H5  H  袸H=KA  H5  Hܺ  H=#A  H5z  H輺  bH=A  H5_  H蜺  貴H=@  H5C  H|  "H=@  H5&  H\  rH=@  H5  H<  H=@  H5  H  2H=c@  H5  H  袷H=K@  H5  Hܹ  H=#@  H5  H輹  bH=@  H5  H蜹  貳H=?  H5f  H|@ DLH1E      藹HoH=?  HH=E   HH     1_HH3H=d?  HHHH  uH  A   A   蓶H=<?  H5  L-  HƸH  ܲH=?  H5  H覸I  LH=>  H5  H膸I  蜲H=>  H5m  HfJ  H=>  H5P  HFJ  \H=>  H5/  H&K  ̵H=u>  H5  HK  H=M>  H5  HL  茵H=5>  H5  HƷL  ܱH=>  H5  H覷M  LH==  H5  H膷M  蜱H==  H5  HfN  H==  H5p  HFN  \H==  H5T  H&O  ̴H=u=  H58  HO  H=M=  H5  HP  茴H=5=  H5   HƶP  ܰH==  H5  H覶Q  LH=<  H5  H膶Q  蜰H=<  H5  HfR  H=<  H5  HFR  \H=<  H5r  H&S  ̳H=u<  H5X  HS  H=M<  H5<  HT  茳H=5<  H5"  HƵT  ܯH=<  H5  H覵U  LH=;  H5  H膵U  蜯H=;  H5  HfV  H=;  H5  HFV  \H=;  H5  H&W  ̲H=u;  H5~  HW  H=M;  H5b  HX  茲H=5;  H5H  HƴX  ܮH=;  H5,  H覴Y  LH=:  H5  H膴Y  蜮H=:  H5  HfZ  H=:  H5  HFZ  \H=:  H5  H&[  ̱H=u:  H5  H[  H=M:  H5  H\  茱H=5:  H5n  HƳ\  ܭH=:  H5R  H観]  LH=9  H55  H膳]  蜭H=9  H5  Hf^  H=9  H5  HF^  \H=9  H5  H&_  ̰H=u9  H5  H_  H=M9  H5  H`  茰H=59  H5  HƲ`  ܬH=9  H5n  H覲a  LH=8  H5Q  H膲a  蜬H=8  H55  Hfb  H=8  H5  HFb  \H=8  H5  H&c  ̯H=u8  H5  Hc  H=M8  H5  Hd  茯H=58  H5  HƱd  ܫH=8  H5  H覱e  LH=7  H5w  H膱e  蜫H=7  H5L  Hff  H=7  H5C  HFf  \H=7  H5  H&g  ̮H=u7  H5  Hg  H=M7  H5  Hh  茮H=57  H5  Hưh  ܪH=7  H5  H覰i  LH=6  H5  H膰i  蜪H=6  H5  Hfj  H=6  H5h  HFj  \H=6  H5f  H&k  ̭H=u6  H51  Hk  H=M6  H50  Hl  茭H=56  H5  HƯl  ܩH=6  H5  H覯m  LH=5  H5  H膯m  蜩H=5  H5  Hfn  H=5  H5  HFn  \H=5  H5  H&o  ̬H=u5  H5X  Ho  H=M5  H5m  Hp  茬H=55  H5!  HƮp  ܨH=5  H5  H覮q  LH=4  H5  H膮q  蜨H=4  H5  Hfr  H=4  H5  HFr  \H=4  H5  H&s  ̫H=u4  H5  Hs  H=M4  H5  Ht  茫H=54  H5L  Hƭt  ܧH=4  H50  H覭u  LH=3  H5  H膭u  蜧H=3  H5  Hfv  H=3  H5  HFv  \H=3  H5  H&w  ̪H=u3  H5  Hw  H=M3  H5  Hx  茪H=53  H5~  HƬx  ܦH=3  H5b  H覬y  LH=2  H5I  H膬y  蜦H=2  H5J  Hfz  H=2  H5  HFz  \H=2  H5  H&{  ̩H=u2  H5  H{  H=M2  H5  H|  茩H=52  H5  Hƫ|  ܥH=2  H5  H覫}  LH=1  H5t  H膫}  蜥H=1  H5X  Hf~  H=1  H5>  HF~  \H=1  H5"  H&  ̨H=u1  H5
  H  H=M1  H5  H  茨H=51  H5  Hƪ  ܤH=1  H5  H親  LH=0  H5  H膪  蜤H=0  H5~  Hf  H=0  H5e  HF  \H=0  H5I  H&  ̧H=u0  H5.  H  H=M0  H5  H  茧H=50  H5  HƩ  ܣH=0  H5  H覩  LH=/  H5  H膩  蜣H=/  H5  Hf  H=/  H5  HF  \H=/  H5o  H&  ̦H=u/  H5U  H  H=M/  H59  H  茦H=5/  H5  Hƨ  ܢH=/  H5  H覨  LH=.  H5  H膨  蜢H=.  H5  Hf  H=.  H5  HF  \H=.  H5  H&  ̥H=u.  H5~  H  H=M.  H5b  H  茥H=5.  H5H  HƧ  ܡH=.  H5,  H覧  LH=-  H5  H膧  蜡H=-  H5  Hf  H=-  H5  HF  \H=-  H5  H&  ̤H=u-  H5  H  H=M-  H5  H  茤H=5-  H5x  HƦ  ܠH=-  H5\  H覦  LH=,  H5B  H膦  蜠H=,  H5&  Hf  H=,  H5  HF  \H=,  H5  H&  ̣H=u,  H5  H  H=M,  H5  H  茣H=5,  H5  Hƥ  ܟH=,  H5  H覥  LH=+  H5o  H膥  蜟H=+  H5S  Hf  H=+  H5<  HF  \H=+  H5   H&  ̢H=u+  H5  H  H=M+  H5
  H  茢H=5+  H5
  HƤ  ܞH=+  H5
  H覤  LH=*  H5
  H膤  蜞H=*  H5
  Hf  H=*  H5f
  HF  \H=*  H5J
  H&D$ HKEY_CTRLHD$_x  fD$     AL      H1#LHIH=2*  Hɣ[u1H=VHD$dH3%(   uVH([]A\A]H\&  H84HU&  H8%H&  H8H'&  H8HP&  H8   HH   already closed window no such mouse event 21 failed to create window can't initialize curses Curses Key MouseEvent new eid z bstate init_screen close_screen closed? stdscr doupdate clear clrtoeol noecho noraw nocbreak nocrmode nonl beep flash ungetch setpos standout standend inch addch insch addstr getstr delch deleteln insertln keyname lines cols curs_set scrl setscrreg attroff attron attrset bkgdset resizeterm resize start_color init_pair init_color has_colors? can_change_color? color_content pair_content color_pair pair_number ungetmouse mouseinterval mousemask timeout= def_prog_mode reset_prog_mode Window initialize subwin close noutrefresh box move color_set cury curx maxy maxx begy begx << scroll scrollok idlok keypad keypad= getbkgd nodelay= A_ATTRIBUTES A_NORMAL A_STANDOUT A_UNDERLINE A_REVERSE A_BLINK A_DIM A_BOLD A_PROTECT A_INVIS A_ALTCHARSET A_CHARTEXT A_HORIZONTAL A_LEFT A_LOW A_RIGHT A_TOP A_VERTICAL A_COLOR COLOR_BLACK COLOR_RED COLOR_GREEN COLOR_YELLOW COLOR_BLUE COLOR_MAGENTA COLOR_CYAN COLOR_WHITE BUTTON1_PRESSED BUTTON1_RELEASED BUTTON1_CLICKED BUTTON1_DOUBLE_CLICKED BUTTON1_TRIPLE_CLICKED BUTTON2_PRESSED BUTTON2_RELEASED BUTTON2_CLICKED BUTTON2_DOUBLE_CLICKED BUTTON2_TRIPLE_CLICKED BUTTON3_PRESSED BUTTON3_RELEASED BUTTON3_CLICKED BUTTON3_DOUBLE_CLICKED BUTTON3_TRIPLE_CLICKED BUTTON4_PRESSED BUTTON4_RELEASED BUTTON4_CLICKED BUTTON4_DOUBLE_CLICKED BUTTON4_TRIPLE_CLICKED BUTTON_SHIFT BUTTON_CTRL BUTTON_ALT ALL_MOUSE_EVENTS REPORT_MOUSE_POSITION KEY_MOUSE KEY_MIN KEY_BREAK KEY_DOWN KEY_UP KEY_LEFT KEY_RIGHT KEY_HOME KEY_BACKSPACE KEY_F%d KEY_DL KEY_IL KEY_DC KEY_IC KEY_EIC KEY_CLEAR KEY_EOS KEY_EOL KEY_SF KEY_SR KEY_NPAGE KEY_PPAGE KEY_STAB KEY_CTAB KEY_CATAB KEY_ENTER KEY_SRESET KEY_RESET KEY_PRINT KEY_LL KEY_A1 KEY_A3 KEY_B2 KEY_C1 KEY_C3 KEY_BTAB KEY_BEG KEY_CANCEL KEY_CLOSE KEY_COMMAND KEY_COPY KEY_CREATE KEY_END KEY_EXIT KEY_FIND KEY_HELP KEY_MARK KEY_MESSAGE KEY_MOVE KEY_NEXT KEY_OPEN KEY_OPTIONS KEY_PREVIOUS KEY_REDO KEY_REFERENCE KEY_REFRESH KEY_REPLACE KEY_RESTART KEY_RESUME KEY_SAVE KEY_SBEG KEY_SCANCEL KEY_SCOMMAND KEY_SCOPY KEY_SCREATE KEY_SDC KEY_SDL KEY_SELECT KEY_SEND KEY_SEOL KEY_SEXIT KEY_SFIND KEY_SHELP KEY_SHOME KEY_SIC KEY_SLEFT KEY_SMESSAGE KEY_SMOVE KEY_SNEXT KEY_SOPTIONS KEY_SPREVIOUS KEY_SPRINT KEY_SREDO KEY_SREPLACE KEY_SRIGHT KEY_SRSUME KEY_SSAVE KEY_SSUSPEND KEY_SUNDO KEY_SUSPEND KEY_UNDO KEY_RESIZE KEY_MAX KEY_CTRL_%c     Insecure: operation on untainted window Insecure: operation on untainted mouse  ;  w   @       4  КH  \  0x  P  p     @  D        0  P       @  p       p,  H  Pd  @       @  4   P  `l       p     	  8	  Pd	  	  P	  	  P	  
  @H
  t
  0
  
  
  в   P   X  t    0      (  H  `h  з  p  0   0L  `d  |      P    0  8  \            4   `  p|        @    4  `P  p      @       @  ,  H  `   x  P       @  `  $  <  T  l        @  `        ,  @D  `             zR x  $      XP   FJw ?:*3$"       D   @             \   h          p   t             
             |G    Hl
L            AAK            AAK  (          EDG L
CAP 8     <   FAD q
ABAD
ABI  (   T       EDG N
CAN 8         FED A(G0n
(D AEBG (     X    EDG Q
DAJ 8     ܙ    FED A(G0n
(D AEBG (   $      EDG T
DAG 8   P      FED A(G0i
(F ABBE 8         FED A(G0i
(F ABBE      \*    E`        p            |.    Ed            AAK     0  g    E|
O   L  g    E|
O   h  <g    E{
P     g    E{
P\        FBB B(A0K8D`hKpHxBN`
8A0A(B BBBH         tg    E|
O     Ƞg    E{
P   8      AAK     T   ]    Ez
I   p  d]    E{
H     ]    E{
H     ]    E{
H     0]    E{
H     tG    HQ
WI             AAK  (         EDG L
FAE (   H      EDG N
DAM (   t  p    EDG M
DAN (         EDG H
FAA      Hi    EC
H        i    EF
E   (         EDG N
DAM    8  Lo    EA
R   (   X      EDG I
FAH (         EDG I
FAH      Di    EF
E        i    EF
E        i    EA
J   (     4    EAJ
AAD   <  ȧy    LD
P   4   \  (    KDG G
FADXF           EN   (         EDG H
FAA (         EDG H
FAA      \i    E|
O   $  i    EA
J      D   i    EA
J      d  Pi    EA
J        i    EA
J        i    EH
C   <     @   FEE D(A0
(A BBBI   4   	      EFD U
DAGR
AAA H   <	  (    FEE B(D0D8L@
8D0A(B BBBA    	  ܭ$    HU    	  $    HU    	  A    En
E   	  @(    E\      	  T9    E_
L   
  xo    EC
P   $   ,
  Ȯk    ECD YDA   T
  D    EX
SF     t
  @    EG j
AI     
      EG z
AI    
  ($    HU    
  @$    HU 8   
  X    FGD D(G0]
(D AEBK ,   (      FFD C
ADP      X  \$    HU (   p  ti    EFG s
DAF       L    Ee
V     <    Ej
A     !    EW        $!    EW        8!    EW   (   (  Ly    EFG }
DAL     T  I    Ei
R   p  ԲA    E_
T     P    Eg
LW      8-    Hd      P-    Hd      h(    H_       v    EGc
AA     ܳ9    Hi    0  =    Ew      L  (<    Ej
A   h  L<    Ej
A     p*    HZ      *    Ha      -    Hd (     q    EFG x
FAG       C    Ed
GR      <    HU    0  D    HU    H  L    HU    `  T    HU    x  \    HU      d    HU      l    HU      t    HU      |    HU          HU      (    H_       (    H_    8      HU    P  ĵ(    H_    h  ܵ$    HU      7    Hd
D  8     ,   FIA A(DPI,
(A ABBA             GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      .      -                   $             3             C             Q             a             l             w                                                                                                                              o    `                                
                                                 `	                           8             @                   	              o           o           o          o                                                                                                                                                                                                                                                                                        !      !       !      0!      @!      P!      `!      p!      !      !      !      !      !      !      !      !       "      "       "      0"      @"      P"      `"      p"      "      "      "      "      "      "      "      "       #      #       #      0#      @#      P#      `#      p#      #      #      #      #      #      #      #      #       $      $       $      0$      @$      P$      `$      p$      $      $      $      $      $      $      $      $       %      %       %      0%      @%      P%      `%      p%      %      %      %      %      %      %      %      %       &      &       &      0&      @&      P&      `&      p&      &      &      &      &      &      &      &      &       '               GA$3a1        ŉ               GA$3p1067  .                      GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY     .      $.               GA+GLIBCXX_ASSERTIONS   curses.so-1.8.7-16.el8.x86_64.debug %:7zXZ  ִF !   t/%] ?Eh=ڊ2NaemL\&$n(w5=v_|ʁt}YJCƴϥIPF0?lt7X#<suxBT!m{㇋jȓSzxV mk`!$Ǜx7}FXE
?8ݼ(YqXp._F?m&wRbMCKa@@U˾4ibɳxE/zg5)|Bf7ӋS#0~eay>pA(ǠNjX"۝JÏ55]p׮"@xO(/V|}zOoRUMNa5?Wju Pfv'6K(kk1$	OCn0p\~@-N[;p\b\PzO@Hjsq&ND*PO?ϥZ?۹s2_PyMeYB\7cEP+*iύ3,ʠ23_7ÑG~5b]e]!	]Ybe/`⾱YP[bV2cɉeX1!(*nW)٬UBE :Iu&K`DpGBgV-ٯa_md';<1XaMƔ0hW؟c?OWި.mN"M3'FlA?MJ }E,AL[U9Ϥ[KoNճBoFD`tFE7[{2) 8*JKMm^V9nt	 -|`F*߇]n6ʚ9Ϸ^D!VR4w0ݷOy2HڥSL'Tu5"	UlqjHT2a~E5@L(lKf׿:J=YGؿec&6Ƭg-̞U[.	$8XK):P/29q9bYUsr?Â=54 c@[KEOl(U嵱!_JRa+<7J,@&2m6DA6Q mPiߏRg+Uʲ1;LfKFZ Ja~~	@xId)ȣnfmw&]P sNdTg10~.ӪČ ?00fܠq=Hףճo&!ReeOF)&!ϯk|3fZ	5 C!A)w[y{|L hᾈ
RdyoO-9}OZYsHθ6xr? <sJ/CK-p}Φ-X*ᅝ\8C4,!v\䧐cbG/оVPX{*b"( CDbCUS%9#hce6hM`%dG]D,Aܑz}9AiD򅨠RDt~h80jJ\I+rXIl T;(Ibec*qĠe5P]SƝxU 5jͽtKzɒKۮ%U8܆}%:^нВp3Y]QpF 8RUU'{vW跌we%eNg(1q}w!*U8c?~0[tZsmMﰥ4ISYVJ\"6H1    <5Ol K  sZg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                               8      8      $                                 o       `      `      4                             (                         p                          0                                                       8   o                                               E   o                     @                            T             @      @                                 ^      B       8      8      `	                          h                                                         c                           P                            n             '      '      @                            w             P-      P-      e\                             }                                                             2       ȉ      ȉ      	                                                                                               H      H                                                                                                                                                                                                                                                                                           P                                        p      p                                                              8                                         8      8      0                                            h`     8      H                                                        (                                                                                                                  +                             PK     Y\
(h@  h@    x86_64-linux/pty.sonu ȯ        ELF          >          @       (9          @ 8 	 @                                 @%      @%                    h-      h-      h-      X      p                    -      -      -      @      @                   8      8      8      $       $                     %       %       %                             Std    %       %       %                             Ptd    #       #       #      d       d              Qtd                                                  Rtd   h-      h-      h-                                  GNU f:mlôow	u؀       <         @    <   >   ?   BE|qXuU                                                                       $                                                                                       J                                           &                                                               >                                                                	                     ,                                                                 z                                                                                     Z                                                               _                      U                     U                                            )                                            s                      9                                           6                     r                                                                                     k                     |                      v                                          ~                                                               e                                          ,                       k                      D                     F   "                   P                                          P                                          1                                                                    1              .    1              "    1              \    0!              __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_intern rb_ivar_get rb_warn rb_yield rb_thread_kill rb_funcall rb_detach_process rb_f_exec __snprintf_chk rb_exc_new2 rb_last_status rb_iv_set __stack_chk_fail rb_waitpid rb_cFile rb_obj_alloc rb_io_close free ruby_xmalloc openpty rb_thread_current fork read rb_io_mode_flags fdopen ruby_strdup rb_ary_new2 rb_ary_store rb_thread_create rb_thread_schedule rb_block_given_p rb_gc rb_eRuntimeError rb_raise getenv rb_str_new2 rb_ensure getuid getpwuid setsid ioctl write dup2 seteuid rb_protect sleep _exit rb_sys_fail Init_pty rb_define_module rb_define_module_function rb_define_class_under rb_define_method libruby.so.1.8 libutil.so.1 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 GLIBC_2.4 GLIBC_2.3.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                                   ui	   3                 ui	   3                 ii   ?     ti	   I     ui	   3      h-                   p-             `      x-             x-      /                    /                    /                    /                     /         .           /         1           /         4           /         :           0                     0                    (0                    00                    80                    @0                    H0         	           P0         
           X0                    `0                    h0                    p0                    x0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                      1         !           1         "           1         #           1         $            1         %           (1         &           01         '           81         (           @1         )           H1         *           P1         +           X1         ,           `1         -           h1         /           p1         0           x1         2           1         3           1         4           1         5           1         6           1         7           1         8           1         9           1         ;           HH  HtH     5  %   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   h2   h3   h4   %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %}  D  %u  D  %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  H=  H  H9tH  Ht	        H=  H5  H)HHH?HHtH  HtfD      =U   u+UH=z   HtH=  d-  ]     w    SHH=Q  lH[H@S1HH=  zH[D  S1HH=  Z   PH[ff.     SHHH=  H{1H13{   [@ Hw?UHcIL  S   Hպ   H  dH%(   H$  1HHVH߾   H=  XHZH5=  HH  HHH=<  <H} Hٺ   H1vH$  dH3%(   u
H  []$@ ATLgUSHHdH%(   HD$1Hl$     {   HtQ|${t!1sLu(H=  fLH=  1 H=  1HL$dH3%(      u	H[]A\g    AWAAVAUATUSH   H  Ht$H;dH%(   HD$x1H;I	I} ItLwI}nIE    0   IEI|$ HH     H@    H@    @    H@     H@(    tLI|$ID$    0   ID$HH     H@    H@    @    H@     H@(    E  HD$,Lt$`E11Ht$0LHHD$Ht$bY  HD$Hj    |$,L|$P   D$L|$0YL$D$,H=  L$DD$@M|$@H5  E:LHE H=  HE |$@CH5  LH   HC (1LHHL   HHcT$D   HHTHt$@H=HD$XD$DD$T   HL$xdH3%(   H   HĈ   []A\A]A^A_     {Ht$E11H|$LH$  H5  H81 H=y  HHtLA   HD$8HD$8HD$D  H=  HLH   4D  +H=  HtHx(H  HHD|$,a|$01ҾT  1?|$0   H5  j|$01|$0   |$0   |$0
HD$HT$4Ht$PH=xD|$PHD$Xy   o   |$,|$0H=C  g    HH=8  HH5$  HHg  H=[  HwH5  {H=<  1H[H5   _H=   1HH5   CH  H=  H5   H1HH5&   H  HH   HH   status value pty - %s: %ld raise stopped changed exited /bin/sh SHELL openpty() failed fork failed r w PTY getpty spawn protect_signal reset_signal ChildExited PTY::reset_signal is no longer needed   PTY::protect_signal is no longer needed ;d      @                  `0  pD  0    0             zR x  $      `   FJw ?:*3$"       D   P             \        ES      x       EU         %    E_         <    Ev         (       8      $    ANTZAUD]
AAA0         FEA G0
 AABA L   P  49   FEB B(A0A8Gu
8A0A(B BBBI        $    H             GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           `      x-                                                                                                                     U                            "             h-                           p-                    o    `                                
                                   0                                        (                                 	              o          o           o          o                                                                                                                                                           -                      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                           GA$3a1        "               GA$3p1067        !                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA+GLIBCXX_ASSERTIONS                        GA*FORTIFY     pty.so-1.8.7-16.el8.x86_64.debug    =m7zXZ  ִF !   t/G] ?Eh=ڊ2N	INwb̺xiZ\yR+/6=$hɬUDMاk/u}3ۖ@쀢$$+!GimvDCe!
N\˻	PnQQ=aQSSg1(n/}qkNl6c	I'eA1%o$OҨ 'BlasW(lK,XɃUq[?)B4-ATrzި޿c#=NM4!>
ȐJ/M;,Vsm`L59#9?+.^{uR8>`]	OqzPl>RbH]w#/4eލ6zH)l~{Q-idVlO;)n04Et}"  zT^MKERy#'ם}UbatozV4TBhVv1_Dqw	vIYTJ#-Zz9:_B|ĎcE<P(Hz弄4 ]4,Cr
H$h\@P}r-qg#ӯ2mJQ!Ǎntug&6uS)sXFbj{!z - Ziulgȝ$YtF|t`<.hzb<nuYRC)zG{͌y
hqi$m.uZ+ߥm^ˬ! NsA 0N8[8X#6Yz1<34uL/!9\giIYt51ǧwMu    Sp䪃x   tg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                   8      8      $                                 o       `      `      4                             (                                                    0                                                      8   o                                               E   o                                               T                                                      ^      B       (      (                                h                                                         c             @      @      `                            n                         P                            w                                                      }              "       "                                          2       "      "                                                 #       #      d                                           h#      h#                                                 %       %                                                  h-      h-                                                p-      p-                                                x-      x-                                                 -      -      @                                        /      /      @                                           0       0                                               1      1                                                  1`     1      H                                                  4      (                                                   04                                                         7      +                             PK     Y\M{	  	    x86_64-linux/rubyio.hnu [        /**********************************************************************

  rubyio.h -

  $Author: nobu $
  $Date: 2008-04-15 12:35:55 +0900 (Tue, 15 Apr 2008) $
  created at: Fri Nov 12 16:47:09 JST 1993

  Copyright (C) 1993-2003 Yukihiro Matsumoto

**********************************************************************/

#ifndef RUBYIO_H
#define RUBYIO_H

#include <stdio.h>
#include <errno.h>

#if defined(HAVE_STDIO_EXT_H)
#include <stdio_ext.h>
#endif

typedef struct rb_io_t {
    FILE *f;			/* stdio ptr for read/write */
    FILE *f2;			/* additional ptr for rw pipes */
    int mode;			/* mode flags */
    int pid;			/* child's pid (for pipes) */
    int lineno;			/* number of lines read */
    char *path;			/* pathname for file */
    void (*finalize) _((struct rb_io_t*,int)); /* finalize proc */
} rb_io_t;

#define HAVE_RB_IO_T 1
#define OpenFile rb_io_t	/* for backward compatibility */

#define FMODE_READABLE  1
#define FMODE_WRITABLE  2
#define FMODE_READWRITE 3
#define FMODE_APPEND   64
#define FMODE_CREATE  128
#define FMODE_BINMODE   4
#define FMODE_SYNC      8
#define FMODE_WBUF     16
#define FMODE_RBUF     32
#define FMODE_WSPLIT  0x200
#define FMODE_WSPLIT_INITIALIZED  0x400

#define GetOpenFile(obj,fp) rb_io_check_closed((fp) = RFILE(rb_io_taint_check(obj))->fptr)

#define MakeOpenFile(obj, fp) do {\
    if (RFILE(obj)->fptr) {\
	rb_io_close(obj);\
	free(RFILE(obj)->fptr);\
	RFILE(obj)->fptr = 0;\
    }\
    fp = 0;\
    fp = RFILE(obj)->fptr = ALLOC(rb_io_t);\
    fp->f = fp->f2 = NULL;\
    fp->mode = 0;\
    fp->pid = 0;\
    fp->lineno = 0;\
    fp->path = NULL;\
    fp->finalize = 0;\
} while (0)

#define GetReadFile(fptr) ((fptr)->f)
#define GetWriteFile(fptr) (((fptr)->f2) ? (fptr)->f2 : (fptr)->f)

FILE *rb_fopen _((const char*, const char*));
FILE *rb_fdopen _((int, const char*));
int rb_getc _((FILE*));
long rb_io_fread _((char *, long, FILE *));
long rb_io_fwrite _((const char *, long, FILE *));
int  rb_io_mode_flags _((const char*));
int  rb_io_modenum_flags _((int));
void rb_io_check_writable _((rb_io_t*));
void rb_io_check_readable _((rb_io_t*));
void rb_io_fptr_finalize _((rb_io_t*));
void rb_io_synchronized _((rb_io_t*));
void rb_io_check_initialized _((rb_io_t*));
void rb_io_check_closed _((rb_io_t*));
int rb_io_wait_readable _((int));
int rb_io_wait_writable _((int));
void rb_io_set_nonblock(rb_io_t *fptr);

VALUE rb_io_taint_check _((VALUE));
NORETURN(void rb_eof_error _((void)));

void rb_read_check _((FILE*));
int rb_read_pending _((FILE*));
#endif
PK     Y\Q)3  3    x86_64-linux/node.hnu [        /**********************************************************************

  node.h -

  $Author: shyouhei $
  $Date: 2009-02-25 15:15:55 +0900 (Wed, 25 Feb 2009) $
  created at: Fri May 28 15:14:02 JST 1993

  Copyright (C) 1993-2003 Yukihiro Matsumoto

**********************************************************************/

#ifndef NODE_H
#define NODE_H

#if defined(__cplusplus)
extern "C" {
#endif

enum node_type {
    NODE_METHOD,
    NODE_FBODY,
    NODE_CFUNC,
    NODE_SCOPE,
    NODE_BLOCK,
    NODE_IF,
    NODE_CASE,
    NODE_WHEN,
    NODE_OPT_N,
    NODE_WHILE,
    NODE_UNTIL,
    NODE_ITER,
    NODE_FOR,
    NODE_BREAK,
    NODE_NEXT,
    NODE_REDO,
    NODE_RETRY,
    NODE_BEGIN,
    NODE_RESCUE,
    NODE_RESBODY,
    NODE_ENSURE,
    NODE_AND,
    NODE_OR,
    NODE_NOT,
    NODE_MASGN,
    NODE_LASGN,
    NODE_DASGN,
    NODE_DASGN_CURR,
    NODE_GASGN,
    NODE_IASGN,
    NODE_CDECL,
    NODE_CVASGN,
    NODE_CVDECL,
    NODE_OP_ASGN1,
    NODE_OP_ASGN2,
    NODE_OP_ASGN_AND,
    NODE_OP_ASGN_OR,
    NODE_CALL,
    NODE_FCALL,
    NODE_VCALL,
    NODE_SUPER,
    NODE_ZSUPER,
    NODE_ARRAY,
    NODE_ZARRAY,
    NODE_HASH,
    NODE_RETURN,
    NODE_YIELD,
    NODE_LVAR,
    NODE_DVAR,
    NODE_GVAR,
    NODE_IVAR,
    NODE_CONST,
    NODE_CVAR,
    NODE_NTH_REF,
    NODE_BACK_REF,
    NODE_MATCH,
    NODE_MATCH2,
    NODE_MATCH3,
    NODE_LIT,
    NODE_STR,
    NODE_DSTR,
    NODE_XSTR,
    NODE_DXSTR,
    NODE_EVSTR,
    NODE_DREGX,
    NODE_DREGX_ONCE,
    NODE_ARGS,
    NODE_ARGSCAT,
    NODE_ARGSPUSH,
    NODE_SPLAT,
    NODE_TO_ARY,
    NODE_SVALUE,
    NODE_BLOCK_ARG,
    NODE_BLOCK_PASS,
    NODE_DEFN,
    NODE_DEFS,
    NODE_ALIAS,
    NODE_VALIAS,
    NODE_UNDEF,
    NODE_CLASS,
    NODE_MODULE,
    NODE_SCLASS,
    NODE_COLON2,
    NODE_COLON3,
    NODE_CREF,
    NODE_DOT2,
    NODE_DOT3,
    NODE_FLIP2,
    NODE_FLIP3,
    NODE_ATTRSET,
    NODE_SELF,
    NODE_NIL,
    NODE_TRUE,
    NODE_FALSE,
    NODE_DEFINED,
    NODE_NEWLINE,
    NODE_POSTEXE,
    NODE_ALLOCA,
    NODE_DMETHOD,
    NODE_BMETHOD,
    NODE_MEMO,
    NODE_IFUNC,
    NODE_DSYM,
    NODE_ATTRASGN,
    NODE_LAST
};

typedef struct RNode {
    unsigned long flags;
    char *nd_file;
    union {
	struct RNode *node;
	ID id;
	VALUE value;
	VALUE (*cfunc)(ANYARGS);
	ID *tbl;
    } u1;
    union {
	struct RNode *node;
	ID id;
	long argc;
	VALUE value;
    } u2;
    union {
	struct RNode *node;
	ID id;
	long state;
	struct global_entry *entry;
	long cnt;
	VALUE value;
    } u3;
} NODE;

extern NODE *ruby_cref;
extern NODE *ruby_top_cref;

#define RNODE(obj)  (R_CAST(RNode)(obj))

#define nd_type(n) ((int)(((RNODE(n))->flags>>FL_USHIFT)&0xff))
#define nd_set_type(n,t) \
    RNODE(n)->flags=((RNODE(n)->flags&~FL_UMASK)|(((t)<<FL_USHIFT)&FL_UMASK))

#define NODE_LSHIFT (FL_USHIFT+8)
#define NODE_LMASK  (((long)1<<(sizeof(NODE*)*CHAR_BIT-NODE_LSHIFT))-1)
#define nd_line(n) ((unsigned int)(((RNODE(n))->flags>>NODE_LSHIFT)&NODE_LMASK))
#define nd_set_line(n,l) \
    RNODE(n)->flags=((RNODE(n)->flags&~(-1<<NODE_LSHIFT))|(((l)&NODE_LMASK)<<NODE_LSHIFT))

#define nd_head  u1.node
#define nd_alen  u2.argc
#define nd_next  u3.node

#define nd_cond  u1.node
#define nd_body  u2.node
#define nd_else  u3.node

#define nd_orig  u3.value

#define nd_resq  u2.node
#define nd_ensr  u3.node

#define nd_1st   u1.node
#define nd_2nd   u2.node

#define nd_stts  u1.node

#define nd_entry u3.entry
#define nd_vid   u1.id
#define nd_cflag u2.id
#define nd_cval  u3.value

#define nd_cnt   u3.cnt
#define nd_tbl   u1.tbl

#define nd_var   u1.node
#define nd_ibdy  u2.node
#define nd_iter  u3.node

#define nd_value u2.node
#define nd_aid   u3.id

#define nd_lit   u1.value

#define nd_frml  u1.node
#define nd_rest  u2.node
#define nd_opt   u1.node

#define nd_recv  u1.node
#define nd_mid   u2.id
#define nd_args  u3.node

#define nd_noex  u1.id
#define nd_defn  u3.node

#define nd_cfnc  u1.cfunc
#define nd_argc  u2.argc

#define nd_cpath u1.node
#define nd_super u3.node

#define nd_modl  u1.id
#define nd_clss  u1.value

#define nd_beg   u1.node
#define nd_end   u2.node
#define nd_state u3.state
#define nd_rval  u2.value

#define nd_nth   u2.argc

#define nd_tag   u1.id
#define nd_tval  u2.value

#define NEW_NODE(t,a0,a1,a2) rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))

#define NEW_METHOD(n,x) NEW_NODE(NODE_METHOD,x,n,0)
#define NEW_FBODY(n,i,o) NEW_NODE(NODE_FBODY,n,i,o)
#define NEW_DEFN(i,a,d,p) NEW_NODE(NODE_DEFN,p,i,NEW_RFUNC(a,d))
#define NEW_DEFS(r,i,a,d) NEW_NODE(NODE_DEFS,r,i,NEW_RFUNC(a,d))
#define NEW_CFUNC(f,c) NEW_NODE(NODE_CFUNC,f,c,0)
#define NEW_IFUNC(f,c) NEW_NODE(NODE_IFUNC,f,c,0)
#define NEW_RFUNC(b1,b2) NEW_SCOPE(block_append(b1,b2))
#define NEW_SCOPE(b) NEW_NODE(NODE_SCOPE,local_tbl(),0,(b))
#define NEW_BLOCK(a) NEW_NODE(NODE_BLOCK,a,0,0)
#define NEW_IF(c,t,e) NEW_NODE(NODE_IF,c,t,e)
#define NEW_UNLESS(c,t,e) NEW_IF(c,e,t)
#define NEW_CASE(h,b) NEW_NODE(NODE_CASE,h,b,0)
#define NEW_WHEN(c,t,e) NEW_NODE(NODE_WHEN,c,t,e)
#define NEW_OPT_N(b) NEW_NODE(NODE_OPT_N,0,b,0)
#define NEW_WHILE(c,b,n) NEW_NODE(NODE_WHILE,c,b,n)
#define NEW_UNTIL(c,b,n) NEW_NODE(NODE_UNTIL,c,b,n)
#define NEW_FOR(v,i,b) NEW_NODE(NODE_FOR,v,b,i)
#define NEW_ITER(v,i,b) NEW_NODE(NODE_ITER,v,b,i)
#define NEW_BREAK(s) NEW_NODE(NODE_BREAK,s,0,0)
#define NEW_NEXT(s) NEW_NODE(NODE_NEXT,s,0,0)
#define NEW_REDO() NEW_NODE(NODE_REDO,0,0,0)
#define NEW_RETRY() NEW_NODE(NODE_RETRY,0,0,0)
#define NEW_BEGIN(b) NEW_NODE(NODE_BEGIN,0,b,0)
#define NEW_RESCUE(b,res,e) NEW_NODE(NODE_RESCUE,b,res,e)
#define NEW_RESBODY(a,ex,n) NEW_NODE(NODE_RESBODY,n,ex,a)
#define NEW_ENSURE(b,en) NEW_NODE(NODE_ENSURE,b,0,en)
#define NEW_RETURN(s) NEW_NODE(NODE_RETURN,s,0,0)
#define NEW_YIELD(a,s) NEW_NODE(NODE_YIELD,a,0,s)
#define NEW_LIST(a)  NEW_ARRAY(a)
#define NEW_ARRAY(a) NEW_NODE(NODE_ARRAY,a,1,0)
#define NEW_ZARRAY() NEW_NODE(NODE_ZARRAY,0,0,0)
#define NEW_HASH(a)  NEW_NODE(NODE_HASH,a,0,0)
#define NEW_NOT(a)   NEW_NODE(NODE_NOT,0,a,0)
#define NEW_MASGN(l,r)   NEW_NODE(NODE_MASGN,l,0,r)
#define NEW_GASGN(v,val) NEW_NODE(NODE_GASGN,v,val,rb_global_entry(v))
#define NEW_LASGN(v,val) NEW_NODE(NODE_LASGN,v,val,local_cnt(v))
#define NEW_DASGN(v,val) NEW_NODE(NODE_DASGN,v,val,0)
#define NEW_DASGN_CURR(v,val) NEW_NODE(NODE_DASGN_CURR,v,val,0)
#define NEW_IASGN(v,val) NEW_NODE(NODE_IASGN,v,val,0)
#define NEW_CDECL(v,val,path) NEW_NODE(NODE_CDECL,v,val,path)
#define NEW_CVASGN(v,val) NEW_NODE(NODE_CVASGN,v,val,0)
#define NEW_CVDECL(v,val) NEW_NODE(NODE_CVDECL,v,val,0)
#define NEW_OP_ASGN1(p,id,a) NEW_NODE(NODE_OP_ASGN1,p,id,a)
#define NEW_OP_ASGN2(r,i,o,val) NEW_NODE(NODE_OP_ASGN2,r,val,NEW_OP_ASGN22(i,o))
#define NEW_OP_ASGN22(i,o) NEW_NODE(NODE_OP_ASGN2,i,o,rb_id_attrset(i))
#define NEW_OP_ASGN_OR(i,val) NEW_NODE(NODE_OP_ASGN_OR,i,val,0)
#define NEW_OP_ASGN_AND(i,val) NEW_NODE(NODE_OP_ASGN_AND,i,val,0)
#define NEW_GVAR(v) NEW_NODE(NODE_GVAR,v,0,rb_global_entry(v))
#define NEW_LVAR(v) NEW_NODE(NODE_LVAR,v,0,local_cnt(v))
#define NEW_DVAR(v) NEW_NODE(NODE_DVAR,v,0,0)
#define NEW_IVAR(v) NEW_NODE(NODE_IVAR,v,0,0)
#define NEW_CONST(v) NEW_NODE(NODE_CONST,v,0,0)
#define NEW_CVAR(v) NEW_NODE(NODE_CVAR,v,0,0)
#define NEW_NTH_REF(n)  NEW_NODE(NODE_NTH_REF,0,n,local_cnt('~'))
#define NEW_BACK_REF(n) NEW_NODE(NODE_BACK_REF,0,n,local_cnt('~'))
#define NEW_MATCH(c) NEW_NODE(NODE_MATCH,c,0,0)
#define NEW_MATCH2(n1,n2) NEW_NODE(NODE_MATCH2,n1,n2,0)
#define NEW_MATCH3(r,n2) NEW_NODE(NODE_MATCH3,r,n2,0)
#define NEW_LIT(l) NEW_NODE(NODE_LIT,l,0,0)
#define NEW_STR(s) NEW_NODE(NODE_STR,s,0,0)
#define NEW_DSTR(s) NEW_NODE(NODE_DSTR,s,1,0)
#define NEW_XSTR(s) NEW_NODE(NODE_XSTR,s,0,0)
#define NEW_DXSTR(s) NEW_NODE(NODE_DXSTR,s,0,0)
#define NEW_DSYM(s) NEW_NODE(NODE_DSYM,s,0,0)
#define NEW_EVSTR(n) NEW_NODE(NODE_EVSTR,0,(n),0)
#define NEW_CALL(r,m,a) NEW_NODE(NODE_CALL,r,m,a)
#define NEW_FCALL(m,a) NEW_NODE(NODE_FCALL,0,m,a)
#define NEW_VCALL(m) NEW_NODE(NODE_VCALL,0,m,0)
#define NEW_SUPER(a) NEW_NODE(NODE_SUPER,0,0,a)
#define NEW_ZSUPER() NEW_NODE(NODE_ZSUPER,0,0,0)
#define NEW_ARGS(f,o,r) NEW_NODE(NODE_ARGS,o,r,f)
#define NEW_ARGSCAT(a,b) NEW_NODE(NODE_ARGSCAT,a,b,0)
#define NEW_ARGSPUSH(a,b) NEW_NODE(NODE_ARGSPUSH,a,b,0)
#define NEW_SPLAT(a) NEW_NODE(NODE_SPLAT,a,0,0)
#define NEW_TO_ARY(a) NEW_NODE(NODE_TO_ARY,a,0,0)
#define NEW_SVALUE(a) NEW_NODE(NODE_SVALUE,a,0,0)
#define NEW_BLOCK_ARG(v) NEW_NODE(NODE_BLOCK_ARG,v,0,local_cnt(v))
#define NEW_BLOCK_PASS(b) NEW_NODE(NODE_BLOCK_PASS,0,b,0)
#define NEW_ALIAS(n,o) NEW_NODE(NODE_ALIAS,n,o,0)
#define NEW_VALIAS(n,o) NEW_NODE(NODE_VALIAS,n,o,0)
#define NEW_UNDEF(i) NEW_NODE(NODE_UNDEF,0,i,0)
#define NEW_CLASS(n,b,s) NEW_NODE(NODE_CLASS,n,NEW_SCOPE(b),(s))
#define NEW_SCLASS(r,b) NEW_NODE(NODE_SCLASS,r,NEW_SCOPE(b),0)
#define NEW_MODULE(n,b) NEW_NODE(NODE_MODULE,n,NEW_SCOPE(b),0)
#define NEW_COLON2(c,i) NEW_NODE(NODE_COLON2,c,i,0)
#define NEW_COLON3(i) NEW_NODE(NODE_COLON3,0,i,0)
#define NEW_CREF(c,n) NEW_NODE(NODE_CREF,c,0,n)
#define NEW_DOT2(b,e) NEW_NODE(NODE_DOT2,b,e,0)
#define NEW_DOT3(b,e) NEW_NODE(NODE_DOT3,b,e,0)
#define NEW_ATTRSET(a) NEW_NODE(NODE_ATTRSET,a,0,0)
#define NEW_SELF() NEW_NODE(NODE_SELF,0,0,0)
#define NEW_NIL() NEW_NODE(NODE_NIL,0,0,0)
#define NEW_TRUE() NEW_NODE(NODE_TRUE,0,0,0)
#define NEW_FALSE() NEW_NODE(NODE_FALSE,0,0,0)
#define NEW_DEFINED(e) NEW_NODE(NODE_DEFINED,e,0,0)
#define NEW_NEWLINE(n) NEW_NODE(NODE_NEWLINE,0,0,n)
#define NEW_PREEXE(b) NEW_SCOPE(b)
#define NEW_POSTEXE() NEW_NODE(NODE_POSTEXE,0,0,0)
#define NEW_DMETHOD(b) NEW_NODE(NODE_DMETHOD,0,0,b)
#define NEW_BMETHOD(b) NEW_NODE(NODE_BMETHOD,0,0,b)
#define NEW_ATTRASGN(r,m,a) NEW_NODE(NODE_ATTRASGN,r,m,a)

#define NOEX_PUBLIC    0
#define NOEX_NOSUPER   1
#define NOEX_PRIVATE   2
#define NOEX_PROTECTED 4
#define NOEX_MASK      6

#define NOEX_UNDEF     NOEX_NOSUPER

NODE *rb_compile_cstr _((const char*, const char*, int, int));
NODE *rb_compile_string _((const char*, VALUE, int));
NODE *rb_compile_file _((const char*, VALUE, int));

void rb_add_method _((VALUE, ID, NODE *, int));
NODE *rb_node_newnode _((enum node_type,VALUE,VALUE,VALUE));

NODE* rb_method_node _((VALUE klass, ID id));

struct global_entry *rb_global_entry _((ID));
VALUE rb_gvar_get _((struct global_entry *));
VALUE rb_gvar_set _((struct global_entry *, VALUE));
VALUE rb_gvar_defined _((struct global_entry *));

typedef unsigned int rb_event_t;

#define RUBY_EVENT_NONE     0x00
#define RUBY_EVENT_LINE     0x01
#define RUBY_EVENT_CLASS    0x02
#define RUBY_EVENT_END      0x04
#define RUBY_EVENT_CALL     0x08
#define RUBY_EVENT_RETURN   0x10
#define RUBY_EVENT_C_CALL   0x20
#define RUBY_EVENT_C_RETURN 0x40
#define RUBY_EVENT_RAISE    0x80
#define RUBY_EVENT_ALL      0xff

typedef void (*rb_event_hook_func_t) _((rb_event_t,NODE*,VALUE,ID,VALUE));
NODE *rb_copy_node_scope _((NODE *, NODE *));
void rb_add_event_hook _((rb_event_hook_func_t,rb_event_t));
int rb_remove_event_hook _((rb_event_hook_func_t));

#if defined(HAVE_GETCONTEXT) && defined(HAVE_SETCONTEXT)
#include <ucontext.h>
#define USE_CONTEXT
#endif
#include <setjmp.h>
#include "st.h"

#ifdef USE_CONTEXT
typedef struct {
    ucontext_t context;
    volatile int status;
} rb_jmpbuf_t[1];
#else
typedef RUBY_JMP_BUF rb_jmpbuf_t;
#endif

enum rb_thread_status {
    THREAD_TO_KILL,
    THREAD_RUNNABLE,
    THREAD_STOPPED,
    THREAD_KILLED,
};

typedef struct rb_thread *rb_thread_t;

struct rb_thread {
    rb_thread_t next, prev;
    rb_jmpbuf_t context;
#if (defined _WIN32 && !defined _WIN32_WCE) || defined __CYGWIN__
    unsigned long win32_exception_list;
#endif

    VALUE result;

    size_t stk_len;
    size_t stk_max;
    VALUE *stk_ptr;
    VALUE *stk_pos;
#ifdef __ia64
    size_t bstr_len;
    size_t bstr_max;
    VALUE *bstr_ptr;
    VALUE *bstr_pos;
#endif

    struct FRAME *frame;
    struct SCOPE *scope;
    struct RVarmap *dyna_vars;
    struct BLOCK *block;
    struct iter *iter;
    struct tag *tag;
    VALUE klass;
    VALUE wrapper;
    NODE *cref;

    int flags;		/* misc. states (vmode/rb_trap_immediate/raised) */

    NODE *node;

    int tracing;
    VALUE errinfo;
    VALUE last_status;
    VALUE last_line;
    VALUE last_match;

    int safe;

    enum rb_thread_status status;
    int wait_for;
    int fd;
    fd_set readfds;
    fd_set writefds;
    fd_set exceptfds;
    int select_value;
    double delay;
    rb_thread_t join;

    int abort;
    int priority;
    VALUE thgroup;

    struct st_table *locals;

    VALUE thread;

    VALUE sandbox;
};

extern VALUE (*ruby_sandbox_save)_((rb_thread_t));
extern VALUE (*ruby_sandbox_restore)_((rb_thread_t));
extern rb_thread_t rb_curr_thread;
extern rb_thread_t rb_main_thread;

enum {
    RAISED_EXCEPTION     = 0x1000,
    RAISED_STACKOVERFLOW = 0x2000,
    RAISED_NOMEMORY      = 0x4000,
    RAISED_MASK          = 0xf000
};
int rb_thread_set_raised(rb_thread_t th);
int rb_thread_reset_raised(rb_thread_t th);
#define rb_thread_raised_set(th, f)   ((th)->flags |= (f))
#define rb_thread_raised_reset(th, f) ((th)->flags &= ~(f))
#define rb_thread_raised_p(th, f)     (((th)->flags & (f)) != 0)
#define rb_thread_raised_clear(th)    (rb_thread_raised_reset(th, RAISED_MASK))

#if defined(__cplusplus)
}  /* extern "C" { */
#endif

#endif
PK     Y\ߖ P   P    x86_64-linux/racc/cparse.sonu ȯ        ELF          >          @       H          @ 8 	 @                                  4       4                    X=      X=      X=            P                    p=      p=      p=      0      0                   8      8      8      $       $                     4       4       4                             Std    4       4       4                             Ptd   @0      @0      @0                           Qtd                                                  Rtd   X=      X=      X=                                  GNU {6Lt4u;˶       0         A   @0   2   3   BE|qX7/                                                  m                                                                                                                                                                             f                     y                                                                  I                                                                                                                                                                                                 0                     U                                           @                                          *                                                                                                                                                      {                                          5                     ,                       Y                                           F   "                   e                     U                     s                     `                                            N                         8A                  A                  8A                  +             __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_gc_mark rb_ary_store rb_int2inum rb_funcall rb_check_type rb_catch rb_ivar_get rb_fix2int rb_num2int rb_num2long rb_ary_new4 rb_ary_pop rb_ary_new rb_eTypeError rb_raise rb_class2name rb_id2name rb_cFalseClass rb_cFixnum rb_str_new rb_cTrueClass rb_cSymbol rb_eArgError rb_hash_aref rb_ivar_set __stack_chk_fail rb_iter_break rb_ary_new2 rb_iv_set ruby_xmalloc rb_data_object_alloc rb_iterate Init_cparse rb_intern rb_cObject rb_const_defined rb_const_get rb_const_get_at rb_define_private_method rb_str_new2 rb_define_const rb_define_class_under rb_eRuntimeError rb_define_module libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 GLIBC_2.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                  ui	        ii         X=                   `=             P      h=             h=      ?                    ?                    ?                    ?                    ?                    ?                    ?                    ?         #           ?         &           ?         '           ?         )           ?         /           @                     @                    (@                    0@                    8@                    @@         	           H@         
           P@                    X@                    `@                    h@                    p@                    x@                    @                    @                    @                    @                    @                    @                    @                    @                    @                    @                    @                    @                     @         !           @         "           @         $           @         %            A         (           A         )           A         *           A         +            A         ,           (A         -           0A         .           HH/  HtH             5/  %/   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   %m-  D  %e-  D  %]-  D  %U-  D  %M-  D  %E-  D  %=-  D  %5-  D  %--  D  %%-  D  %-  D  %-  D  %-  D  %-  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %,  D  %},  D  %u,  D  %m,  D  %e,  D  %],  D  %U,  D  H=Q,  HJ,  H9tH*  Ht	        H=!,  H5,  H)HHH?HHtH*  HtfD      =+   u+UH=*   HtH='  	d+  ]     w    SHH? H{H{H{(H{0H{8H{@H{HH{PH{XH{`H{pH{xH   H   H   H   H   [w    ATIHUHSHH   Hw@   u&H   HH   [H]A\HwH   LHwH{L1L   L      H5*  % S"   HHC 1Hp Hx1   [fUH    SH)HHH   HH5   H=t  H{H5*  Ht8HHH   tQH[]f.     KH[]@ HXfD  Hx+HWHHO H9HNH)HH4Zf.        f.     AWAVAUATUSH"   HH(Hk HEpH   H@ H    HLtL|$  HA7  IH)  H  L   I9  LH0L   HD$H@ H HD$H  I@ LpIu   <  HD$   L   @ L@HuL   L9=(  Mt9D   H}E3  LL$HL$L1   L   HD$IpHT$L}D   E  H   HBH9  S  HR H\F  HAN  IL+uh   HE`L9p~]H@ J<HtO@  HHx=HEHH9x~3H@ HHt%HEPH9x~H@ L$ItLI9tHEXL9p   H@ JH   HHwt|HH   H(   []A\A]A^A_@ I9O  D   HD$Ef  HD$   HD$   \fD  H         HwHNHwfD     H3HALIfD  H   LHwHH}ML         1HL$(H52&  ^_fD  HL$   L1L   HD$ HH     IEIU HD$   H)HHD$fD     uHD$   L   HD$   bHD$   RL   HD$   HD$     H   HIL   HD$fLIuL   fD  Hq    uHD$   H   H9L   HD$eH#  H54  H81H=$  H5  ff.     fATUSHH   HH   HtVHtP  ?	uULbI  Hr HHHz   ~HFI H[]A\f     Ht[H      HzItFH} LD$HLD$He  HH"  H5^  H81H)"  H8@ H  H   H"  H8@ H       H=  LD$sLD$I H[]A\fH!  H8MH!  H8=? t-H>H  HH!  MH5A  H81_H}  H  ff.     @ AVAUATUSHHHt$H$   H   A   H  HC@H9P  H@ H,H
  @  HH   EtmHtgDKEn  H      H   H[]A\A]A^@ H   H{xHt$H   HB     Y  t  HH  HC(H9hr  H@ L,I`  A  IHC0H9hE  H@ H<H3  @Y  HH   E1H9t3    H   HC8H9P   H@ L,A}   IM   L9      H   HI9  L9   y       H   H@ H Hǃ      H   H[]A\A]A^ A   LIM{H   HMI9vLHo  o^ H0 H   H~#HH   H{H5q   HH$LHA   H   =   H   eHH   YH{   H5  HI1H   -HHSD      Hǃ      E   H{L$H   LD$H5  1HH   }@ H   E1H{H5]  117    H H   Hu8H{L$   1H   H   L   H5(  H   HuH   n  A   Hǃ         H{H5  H
H   *HR HD   H   H   '  H   HS@H9B   HR H<Htz@   HHoHxdHC(H9h~ZH@ L4    L,ItDA   IHC0H9h~-H@ J<0Ht@   HH9     D  H   H~ZH   H   HBH   HH ;HhAfL(IaHǃ      Hǃ      D  H   H   H{1L   L      H5  i LI=H	 H{H5  11Hs H{IHL$H4M~2H   L9_I9H=  LH5
  1D  tH   HL9H   Hǃ       Hǃ      H$   LHK	H  H5  H81~ff.      UHSH"   HH(dH%(   HD$1CH[ H    uWHL$Hs HH{LD$+HT$Ht$H߹   H   w9HT$dH3%(      uH([]H  H5G  H81ff.     AWIAVIAUMATI"   UHSHI^ L3LcL{ItA8  ILk H5;  L	   HH   4HUHBH  HE 	   L(LHE Lk(	   LhLHE Lk0	   LhLHE Lk8	   LhLHE Lk@	   Lh LHE LkH	   Lh(LHE LkP	   Lh0LxHE LkX	   Lh8L_HE Lk`Hx@@  HH{hLhH	   L1HE Lkp   LhPLHE LkxHxX@  HH   Hx`@j  HH}H                  '  H   @   6@   H   %   Hǃ       H   HpH1Hǃ      Hǃ       Hǃ       :H5  LH8C    H   LHǃ      H5  Hǃ       5   u+   H5  LHL[]A\A]A^A_D  H   H5|  L     HE H@hf     @   H HHE `    HHE H=0  H5  12H  H5>  H81f.     AUIATIUH   SHHHxHHH     HHHǀ       1H)   HHH=  QLH   HD$1H|$IA      H1ɺ   C       HD$H   H[]A\A]ff.     fAWMAVIAUIATIUH   SHHHxHHH     HHHǀ       1H)   HHH=  gMLLHD$1H|$HI   1ɺ   HC      HD$*H3HH=H1H    tH   H[]A\A]A^A_H{ 8H5I  HHO  H81ff.     fATH=  USH-  HHH} v  H} H"H=  ILHhHH߹   HH5]     HNHH5S  H=W  H5Q  HHAH=  HH5L  H#HU H5P  L H=N  H  H3  H H  H=#  H  H=   H  H=  H  H=  H}  H=  Hb  mH=  HG  ZH=  H,  GH=  H  4H=  H  !H=  H  []H  A\fH=   HU H5   HIHa  HH       racc_jump not symbol returned next_token yielded $ %s() %s %s (must be Array[2]) token given after EOF extra token after EndOfToken [Racc Bug] wrong arg.size %ld @vstack @tstack Racc Parser _racc_do_parse_c _racc_yyparse_c 1.4.5 Racc_Runtime_Core_Version_C Racc_Runtime_Core_Id_C CparseParams @yydebug on_error _reduce_none @racc_error_status racc_shift racc_reduce racc_accept racc_read_token racc_next_state racc_e_pop    state stack unexpectedly empty  %s() %s wrong size of array (%ld for 2) [Racc Bug] unknown act value %ld        %s() is finished before EndOfToken      $originalId: cparse.c,v 1.8 2006/07/06 11:39:46 aamine Exp $    ;         `   `       (  D  p|      00       `  @<  p             zR x  $      hP   FJw ?:*3$"       D   @             \   x    E  (   x       BGD t
DBI      .    Eh   4          AIJ O
AAKI
AAE       6       X        FBB B(A0A8O`/
8F0A(B BBBEhTpYhA`   @   h     BAA D0j
 AABJ
 AABC X        BBB A(A0G@
0A(A BBBEL
0A(A BBBD  (     l    EDO@w
AAA H   4      BEE E(I0D8D@
8D0A(B BBBF4     T    FED I(D@(A ABBH     #   FEE E(D0I8DP
8A0A(B BBBA ,        FHA 
AIC                   GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           P      h=                                                                                                        "             (             -             X=                           `=                    o    `             x                   
       O                            @             `                                        `             h      	              o    0      o           o    
      o                                                                                                                                                                                           p=                      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                           GA$3a1 (      -               GA$3p1067        -                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY           Y               GA+GLIBCXX_ASSERTIONS   cparse.so-1.8.7-16.el8.x86_64.debug 7zXZ  ִF !   t/] ?Eh=ڊ2Nع&MV~Xo//*PX5`W.CcE܌4ȳ.~FRMMVg>I&H|Ah,32x!W_%xr-?>Z&#F=`f}+7nE	x,Z;?zwW&d=rD!U	ަ$I|qߨP6ڪk:m,h{%@"IҌdK"5V
U'n{  P\pÆ\̙]X	m*تZAY*~drRҜ+O*8SdE
(dZwE Ҙjį[n~q<SN#t(
݀<E%#Hw0hP`3
Ɇ<EPdo}fn(XdvqVj=VWFʲ`viԭH	LjB+Hh>Ȉ5금K8A-dAX'>gW$W"I-oO^6P[\Ƴ"m{-mzw~")Ȇ:%lS^
#wI8wkoS_6q抎i)Ul-oPFUǱ|NWl=|
HHk5TX{KtIq{%ǋ(cr=5/XS>Лbmg JS9d FiegS]:Gbo\T1d+ݍ4CCsiJ?:!"ZăXQ_9){0yFZLML,6C,!da|$-j:w    /C,\Jn   >Cg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                   8      8      $                                 o       `      `      4                             (                                                   0             x      x      O                             8   o       
      
      h                            E   o       0      0      0                            T             `      `      h                           ^      B                   `                          h             (      (                                    c             P      P      P                            n                         @                            w                                                      }             -      -                                          2       -      -                                               @0      @0                                                 0      0      4                                           4       4                                                  X=      X=                                                `=      `=                                                h=      h=                                                 p=      p=      0                                        ?      ?      `                                           @       @      8                                         8A      8A      p                                            A`     8A      H                                                  C      (                                                   C                                                         G      +                             PK     Y\.v>J  J    x86_64-linux/rubysig.hnu [        /**********************************************************************

  rubysig.h -

  $Author: shyouhei $
  $Date: 2009-01-05 11:16:18 +0900 (Mon, 05 Jan 2009) $
  created at: Wed Aug 16 01:15:38 JST 1995

  Copyright (C) 1993-2003 Yukihiro Matsumoto

**********************************************************************/

#ifndef SIG_H
#define SIG_H
#include <errno.h>

#ifdef _WIN32
typedef LONG rb_atomic_t;

# define ATOMIC_TEST(var) InterlockedExchange(&(var), 0)
# define ATOMIC_SET(var, val) InterlockedExchange(&(var), (val))
# define ATOMIC_INC(var) InterlockedIncrement(&(var))
# define ATOMIC_DEC(var) InterlockedDecrement(&(var))

/* Windows doesn't allow interrupt while system calls */
# define TRAP_BEG do {\
    int saved_errno = 0;\
    rb_atomic_t trap_immediate = ATOMIC_SET(rb_trap_immediate, 1)
# define TRAP_END\
    ATOMIC_SET(rb_trap_immediate, trap_immediate);\
    saved_errno = errno;\
    CHECK_INTS;\
    errno = saved_errno;\
} while (0)
# define RUBY_CRITICAL(statements) do {\
    rb_w32_enter_critical();\
    statements;\
    rb_w32_leave_critical();\
} while (0)
#else
typedef int rb_atomic_t;

# define ATOMIC_TEST(var) ((var) ? ((var) = 0, 1) : 0)
# define ATOMIC_SET(var, val) ((var) = (val))
# define ATOMIC_INC(var) (++(var))
# define ATOMIC_DEC(var) (--(var))

# define TRAP_BEG do {\
    int saved_errno = 0;\
    int trap_immediate = rb_trap_immediate;\
    rb_trap_immediate = 1
# define TRAP_END rb_trap_immediate = trap_immediate;\
    saved_errno = errno;\
    CHECK_INTS;\
    errno = saved_errno;\
} while (0)

# define RUBY_CRITICAL(statements) do {\
    int trap_immediate = rb_trap_immediate;\
    rb_trap_immediate = 0;\
    statements;\
    rb_trap_immediate = trap_immediate;\
} while (0)
#endif
RUBY_EXTERN rb_atomic_t rb_trap_immediate;

RUBY_EXTERN int rb_prohibit_interrupt;
#define DEFER_INTS (rb_prohibit_interrupt++)
#define ALLOW_INTS do {\
    rb_prohibit_interrupt--;\
    CHECK_INTS;\
} while (0)
#define ENABLE_INTS (rb_prohibit_interrupt--)

VALUE rb_with_disable_interrupt _((VALUE(*)(ANYARGS),VALUE));

RUBY_EXTERN rb_atomic_t rb_trap_pending;
void rb_trap_restore_mask _((void));

RUBY_EXTERN int rb_thread_critical;
RUBY_EXTERN int rb_thread_pending;
void rb_thread_schedule _((void));
#if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE)
# define CHECK_INTS do {\
    if (!(rb_prohibit_interrupt || rb_thread_critical)) {\
	if (rb_thread_pending) rb_thread_schedule();\
	if (rb_trap_pending) rb_trap_exec();\
    }\
} while (0)
#else
/* pseudo preemptive thread switching */
RUBY_EXTERN int rb_thread_tick;
#define THREAD_TICK 500
#define CHECK_INTS do {\
    if (!(rb_prohibit_interrupt || rb_thread_critical)) {\
	if (rb_thread_pending || rb_thread_tick-- <= 0) {\
	    rb_thread_tick = THREAD_TICK;\
	    rb_thread_schedule();\
	}\
    }\
    if (rb_trap_pending) rb_trap_exec();\
} while (0)
#endif

#endif
PK     Y\)oŝ      x86_64-linux/dlconfig.hnu [        #ifndef DLCONFIG_H
#define DLCONFIG_H
#define MAX_ARG           0
#define MAX_CALLBACK 10
#define CALLBACK_TYPES 8
#define USE_DLSTACK
#define WITH_TYPE_CHAR
#define WITH_TYPE_SHORT
#define WITH_TYPE_LONG
#define WITH_TYPE_DOUBLE
#define WITH_TYPE_FLOAT
#define WITH_TYPE_INT
#if !defined(HAVE_DLFCN_H)
# define HAVE_DLFCN_H
#endif
#if !defined(HAVE_DLERROR)
# define HAVE_DLERROR
#endif

#endif /* DLCONFIG_H */
PK     Y\|q  q    x86_64-linux/stringio.sonu ȯ        ELF          >    0      @       j          @ 8 	 @                                 0M      0M                    ]      ]      ]                                (]      (]      (]      0      0                   8      8      8      $       $                    M      M      M                             Std   M      M      M                             Ptd   PB      PB      PB                         Qtd                                                  Rtd   ]      ]      ]                                  GNU ClD@[Pᶛ'&	       H         @ A   H   K       1BE|qX                                                                                                                 `                                                                                                            D                                                                                                         {                      M                                          4                                                                `                      	                                          f                                           +                                          f                                                                                                           p                     6                     t                                                                                                           '                                                                 ]                                          U                                                                                                                                                    l                     A                     X                                                               l                     ~                                           L                     ,                                            (                     ]                     v                     F   "                                                                                                          M                     6    09            G    a              Z    a              N    a               __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_gc_mark rb_rs rb_str_substr memchr rb_scan_args rb_string_value memcmp __stack_chk_fail rb_str_new rb_string_value_cstr rb_io_mode_flags __errno_location rb_sys_fail rb_fix2int rb_io_modenum_flags rb_str_resize ruby_xfree rb_class_new_instance rb_block_given_p rb_yield rb_ensure rb_data_object_alloc rb_eIOError rb_raise rb_str_modify memset rb_check_type rb_class2name rb_eTypeError rb_cFixnum rb_cFalseClass rb_cNilClass rb_cSymbol rb_cTrueClass rb_call_super ruby_xmalloc rb_eof_error rb_num2long rb_num2int memmove rb_int2inum rb_secure rb_eArgError memcpy rb_ary_new rb_ary_push rb_lastline_set rb_notimplement rb_convert_type rb_uint2inum re_mbctab rb_frame_this_func rb_enumeratorize rb_str_cat rb_obj_as_string rb_str_update Init_stringio rb_cData rb_define_class rb_mEnumerable rb_include_module rb_define_alloc_func rb_define_singleton_method rb_define_method rb_io_addstr rb_io_print rb_io_printf rb_io_puts libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.14 GLIBC_2.2.5 GLIBC_2.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                                   =     @      _     ui	   j     ii   v                 ui	   j      ]                   ]                    ]              ]      X_                    `_                    h_         	           p_         
           x_                    _                    _                    _                    _         $           _         '           _         )           _         +           _         .           _         2           _         7           _         =           _         >           _         @           _         A           _         B           _         F           `                     `                    (`                    0`                    8`                    @`                    H`                    P`                    X`                    ``                    h`                    p`                    x`                    `                    `                    `                    `                    `                    `                    `                    `                    `                    `                    `                     `         !           `         "           `         #           `         %           `         &            a         (           a         *           a         +           a         ,            a         -           (a         /           0a         0           8a         1           @a         3           Ha         4           Pa         5           Xa         6           `a         8           ha         9           pa         :           xa         ;           a         <           a         ?           a         B           a         C           a         D           a         E           a         G           HHI  HtH     5bI  %cI   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   h2   h3   %F  D  %F  D  %F  D  %F  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %E  D  %}E  D  %uE  D  %mE  D  %eE  D  %]E  D  %UE  D  %ME  D  %EE  D  %=E  D  %5E  D  %-E  D  %%E  D  %E  D  %E  D  %E  D  %E  D  %D  D  %D  D  %D  D  %D  D  %D  D  %D  D  %D  D  %D  D  %D  D  %D  D  %D  D  %D  D  %D  D  %D  D  %D  D  %D  D  H=D  HzD  H9tHB  Ht	        H=QD  H5JD  H)HHH?HHtHEB  HtfD      =D   u+UH=:B   HtH=^?  dC  ]     w    HtH?        AWIAVAUATUSHH  dH%(   H$8  1!  HJA  H HD$(M/IOMML9   MuHD$(K,IH  L`MtkI)I  M9$  LHL6IH+jIGIoH$8  dH3%(   |  HH  []A\A]A^A_D  HH9tW;
tHD  H9t#x
Hxm  H
   H)mHuHHLH)L)i    AO   cf     H\$(1HR   H
H|$(u2M/IOMML9}ImLLHLH):D  Hx I     N4#L9H@Lt$IHD$ IHD$K&H9Ht$LLLL$H$H$LL$uHl$II)_ H@LHHL$L$05L$HL$H/HhII) @ HhLXH$0  HD$0fD  L HH9uMIt'LLD  HrHD0HuM9MMxbLLF4LL)L)LG84t4@ HD08u#HBH9uHuN"J,h@ NT0M9|UIR^ff.      AUATUSHH  H(dH%(   HD$1Ll$Ld$MLŃtH   tsHD$HHC    HC    HD$dH3%(     H([]A\A]@ L@HD$   H   H       D    1H=  C   xfD  H|$@uuLHHC} w@@LHD$Ct`u\HtTH    tK1    If        k KH   CfD  1H@ GG~fD   SVHu
H[D  H=i<  HH[Hk  fD  HH~1    @uHtHuPH8<  H5  H81ff.     @ AUIATUHSHHH?H} It LgL9~M9|)H[]A\A]fD  H[]A\A]9f     HE L1L)HxH[]LA\A]ff.      PXH5   HHt;  H81fS"   HRHkH9CuHC [u:HtLHt;HtYtHH{kH5  HH:  H81`H:  H8H:  H8H:  H8H:  H8H:  H8@ AUIATAHUHSHAHHt)11HLDHH[]A\A]@     VHH    H@    H@    H       HCH]      PXH5  HH$:  H81rfHHt1HfHHtSp@tEHHPH;Q}(HIHrHpHHH%  HfD  p   HVfD  HHtH3 HHt
   Hff.     @ SHHtH[@ HHt
   Hff.     @ HsHtH@    H@    `   H{ff.     H3Ht
   HOff.     @ HHt@tHHJH9HHH
D  HHt@HH    HHt@HH    HcHt@HHw    SH3HtH[T@ ATUHSHt%IIHHtL`H[]A\fD  HIfD  HHtH HSHHtH    `H[f     AVAUATIUHSiH   H@   H   btqH;HKLoH   HqIL9HGH@8(t!1   HPHCHpHLpLHs@(HHtHL	tQc[   ]A\A]A^fD  SlfD  IuHLHpH~HH@ ItI$   H	Cff.      HCHtHxH\ff.     HHtHxH,ff.     UHSHHt$HtH@u	Hub   cH|$jHD$   uHtH   H҃SHC    HC    HH[]fHE uAUATIUHSHdH%(   HD$1%H   H@  H$   tDt%  Hf4  H5M  H81 ID$HH$H<$I$H<$H   d  HH  SH<$tHHIH9K^  E  HHsIE1H   HiH)H9HOHH$HsHHxHHpH$H   HhHkL9   E   HL$dH3%(      H[]A\A]fD     HHsHAH9}kH)A   IHSHHH$Hy1Cu11H$cf.     Kb    K1HtLH$AfD  H( Hu   SHt1m 1A'-HH[2  H5  H81fHsHtHx tHff.     ATAHUSHHdH%(   HD$1vH  HHI1H  D1aH   HE   H<$Ht@tPHHtUHuYHE HXH   e   H]HL$dH3%(      H[]A\D  HHuH]@ HtH=      $@ HHNH0  H5  H818C1    ff.     AUIATAHUSH4HtOHHCu7@ HHCt"HLDHuHH[]A\A]ff.     UHSHHHt(@t'HHAHH&HH[]bfHHtH PXHHNHtoff.     @ ATH  H  USHH"   H9tYHIHHtxHHtH{ GG~4Hk HtLH	بuIu,@ EH[]A\@ +Hk Ht@ I$%   H	D  ATIUSHӃu	HuZ   (u#I4$HtN@uH@tB?u8HHt9HLH[]A\fD  H   uD  H1[]A\D  UHSHHt3H@t HHHx$HCHcH[] HxL1    ff.     @ HSHtPtP   HaH-  H5  H81f     HHtPtP   HHB-  H5  H81f     HHtPtP   HH,  H5  H819f     SGt6HHuHu   -H[     H tH[H,  H5  H81ff.     AUATUHSHHtxH}L @t4HHMl$Hx\HL)L9$HH[]A\A]fD  HH I|$H1L)L+HH[]A\A]CH=      HSHtH HtHxHcH+  H5  H81ff.     AWAVAUIATUSHF   LIH   @   HH@LsHkI9vSL%*  D  HcI$DT5 )HcI9BHHcHIGHIGI9wHL[]A\A]A^A_    ;HL1H[1]HA\A]HA^A_fLff.     USHHH|   H@tn7u&AHRHHHMH<H  H-HU HEH;B|HH[]D  HH1H[1]HHY@ AUIATIUHSHRHtyHu?    HCtQHLHuHL[]A\A]f     HLH[L]HA\A]Hff.     @ AUIATUHSHH  H&H@   H   HAH;yC@   Hs   1HHHPHCHHHKD$HHt!HL	uItIU    H	HH[]A\A] @rE ?cH} XHEH;D C@[HHpHsOf.     H8Aff.     AUIATUSHHgH  HHH         ?~   LcM   H}  H} HGE@~   HEHsLnHE Ht!HL	uItIU    H	LeHL[]A\A][ HHLcMwH   []A\A]HuH9yLH1HuH} HL`yf     H5&  SH=  H0HH&  HH00HH51H߹HH5  H߹HwH5  H߹   HH5s  pH߹H1H5h  U1HHH5  =H߹   H~H5<  "1HH6H5,  
H߹   HH5  1HHH5  1HHKH5  1HHH5  1HH{H5  1HHSH5  w1HHH5  _1HHH5  G1HHkH5  /1HHSH5  H߹HH5~  1HHH5l  1HHH5Z  1HHH5H  H߹   HH51  1HHMH5  H߹HH5
  f1HHH5  NH߹   HH5  31HHH5  1HHOH5  H߹HH5  H߹HH5  H߹HH5  1HHH5b  1HHH5T  1HHH5B  j1HHH54  R1HHH5,  :1HHH5
  "H߹   HH5  H1HH5  H1HH5  H߹H8H5  H߹HmH5  H߹HH5  H߹HgH5  kH߹HH5q  PH߹   HH5  5Hv!  H߹   H5C  H{!  H߹H5+  HP!  H߹H5  H߹   HUH5  H   H߹H5  H߹   H_H5  H1HH5  {H1HH5  cH1HH5  KH1HH5  3H1HH5~  H1HH5k  H[   H#H5V     HH       02 not modifiable string not opened for reading uninitialized stream negative length %ld given 11 closed stream invalid whence to_strio StringIO not opened for writing negative legnth not opened initialize initialize_copy reopen string= lineno lineno= binmode close close_read close_write closed? closed_read? closed_write? eof eof? fcntl flush fsync pos pos= rewind seek sync= tell path each each_line each_byte bytes each_char chars getbyte ungetc readchar readbyte gets readline readlines sysread << print printf putc puts syswrite isatty tty? pid fileno size length truncate      wrong argument type %s (expected StringIO)      wrong number of arguments (%d for 0)    closing non-duplex IO for writing       closing non-duplex IO for reading       ;  8   P    (  <          0  p    |       P  p  (   H   d  P  p        P  (  D  `   |  P  p        <  0X    P      PL  x        P  H  d  `      	  (	  	  	  `
  P
  
             zR x  $      `P   FJw ?:*3$"       D   @             \   p       H   p   |B   BEB B(A0A8G
8A0A(B BBBF8         BBA A(NPi
(A ABBE                   :    EU
FN    ,            @  1    YX   T  H    BEA D(G0h
(A ABBGD
(A ABBNT(A AEB      |    AAK           A_
A8         FEG D(D0h
(D ABBE     $  X    AAK     @  \    HP
A     \  `j    Hu
SO
A   |      HO
A       !    HS
A           EQ
A     !    HS
A       5    Hg
A       !    HS
A     $  ;    Hb
G     @  <)    HU
G     \  P)    HU
G     x  d)    HU
G       x    EQ
A(     |J    FAD c
ABG         HQ
A       '    E\
A<     "   FBB D(D0
(F BBBG      T  $    HR
E     p  $    HR
E  (         EDD0~
AAC 8     D~   FBD F(D@M
(A ABBG     $    HV
A  0     D   FGA G0
 AABF 8   D  u    FEG A(D0J
(D ABBA (     N    EDI l
DAA            HO
A       $!    EAD  ,     8    FOA r
ABE   8         FDC a
ABGV
ABE   (   P  ,a    EDD m
AAD     |  pG    Ha
A       G    Ha
A       G    Ha
A        U    Af
IL
A  H     H    FBA D(D0
(D ABBGi
(D ABBA   @  E    H[
E  `   \      FBB E(A0A8D@
8D0A(B BBBHI
8J0C(E BFBE 4     |    EAG X
DAFI
JCL L         FED F(D0D
(D ABBJI
(J DEBI   8   H  D5   FEA D(D0
(D ABBD L     H7   FEA A(G0
(D ABBH\
(F ABBA        8   L              GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ]                                                                 %             3             =                                       L?             ]                           ]                    o    `             	                   
                                   `                                                     `             @      	              o           o           o    f      o                                                                                                                                                                                                                                                                   (]                                                                        0      @      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                                                         GA$3a1       Y?               GA$3p1067        I?                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY           	               GA+GLIBCXX_ASSERTIONS   stringio.so-1.8.7-16.el8.x86_64.debug   )"7zXZ  ִF !   t/] ?Eh=ڊ2NnL$Hѵ?tIכ4/7Mr=4JbC&Un	[VVfa˱Ln'3G8w.=okҍ

秙CRB։9Yu&~E;}^[RY8?S
hZ	V~>J*åtRݞL+AnLLz;yfZƽkVUQ+>yi5\.±'KMV@Sd02"
yN^קI-MUH$̮jpT/
!;1'u;4sK'JC+(+Ig!ՋwjezC}<LhN5i
/=m*b;Α"z(1XYآ!b~]Ņ.H+H jwG2W* BLt?&Ze*tTYR\&[џkݹJD$
{m<R*äQYO;=Etۡ\Zd2Zv^~1gbU	S;?U~5xXAmm+28I`F%pbǑ*Iu+1hC|
	_/K?}uǻ}xTfxDj{zptпN#1j1WFfN擴e5IG{$niƷl%pB	$m{MƝLb(A7z^R٣jrJ츛{i@~*i()mgI絴b-\]NKe#WSA."	˻wjӀkI|9%[ImLrM[:E݋͉g&$ٵ*"n+ʲDhjѕ1O]"I8Q\
_/FDm2A"ffUu-aƝYf?v] Ee65ӬzU{])ݬ`Wu:])HYH8[H*ܭ%}_ 4.M g}gy <s2%%Ed7NOFƊ3efrHPɞM;?#-<Np?#*f ꏿ:e6Ci_ NB](hhݪcLx!{?X9,ʌƖ    J4z6 
+  !zʱg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                   8      8      $                                 o       `      `      4                             (                                                    0             	      	                                   8   o       f      f                                  E   o                     `                            T             `      `      @                           ^      B                                             h                                                       c                         P                            n                         @                            w             0      0      "                             }             L?      L?                                          2       `?      `?                                               PB      PB                                                 D       D                                                M      M                                                  ]      ]                                                ]      ]                                                 ]       ]                                                 (]      (]      0                                        X_      X_                                                 `       `                                               a      a                                                  a`     a      H                                                   d      ,                                                   ,d      D                                                   pi      +                             PK     Y\MVpP  P    x86_64-linux/st.hnu [        /* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */

/* @(#) st.h 5.1 89/12/14 */

#ifndef ST_INCLUDED

#define ST_INCLUDED

#if SIZEOF_LONG == SIZEOF_VOIDP
typedef unsigned long st_data_t;
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
typedef unsigned LONG_LONG st_data_t;
#else
# error ---->> st.c requires sizeof(void*) == sizeof(long) to be compiled. <<---
-
#endif
#define ST_DATA_T_DEFINED

typedef struct st_table st_table;

struct st_hash_type {
    int (*compare)();
    int (*hash)();
};

struct st_table {
    struct st_hash_type *type;
    int num_bins;
    int num_entries;
    struct st_table_entry **bins;
};

#define st_is_member(table,key) st_lookup(table,key,(st_data_t *)0)

enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK};

#ifndef _
# define _(args) args
#endif
#ifndef ANYARGS
# ifdef __cplusplus
#   define ANYARGS ...
# else
#   define ANYARGS
# endif
#endif

st_table *st_init_table _((struct st_hash_type *));
st_table *st_init_table_with_size _((struct st_hash_type *, int));
st_table *st_init_numtable _((void));
st_table *st_init_numtable_with_size _((int));
st_table *st_init_strtable _((void));
st_table *st_init_strtable_with_size _((int));
int st_delete _((st_table *, st_data_t *, st_data_t *));
int st_delete_safe _((st_table *, st_data_t *, st_data_t *, st_data_t));
int st_insert _((st_table *, st_data_t, st_data_t));
int st_lookup _((st_table *, st_data_t, st_data_t *));
int st_foreach _((st_table *, int (*)(ANYARGS), st_data_t));
void st_add_direct _((st_table *, st_data_t, st_data_t));
void st_free_table _((st_table *));
void st_cleanup_safe _((st_table *, st_data_t));
st_table *st_copy _((st_table *));

#define ST_NUMCMP	((int (*)()) 0)
#define ST_NUMHASH	((int (*)()) -2)

#define st_numcmp	ST_NUMCMP
#define st_numhash	ST_NUMHASH

int st_strhash();

#endif /* ST_INCLUDED */
PK     Y\M3e@  @    x86_64-linux/digest.sonu ȯ        ELF          >          @       X9          @ 8 	 @                                 )      )                    p-      p-      p-            0                    -      -      -      0      0                   8      8      8      $       $                    )      )      )                             Std   )      )      )                             Ptd   $      $      $                           Qtd                                                  Rtd   p-      p-      p-                                  GNU Bdo<Uf:Ɋ       .         B    .   0   1   BE|qXYR	                            |                                                                                        F                     p                                                                                                          U                                                                 X                                                                                      o                                                                                       h                     '                     W                                           z                      F                                                                                                         m                                                                                                                                 /                     ,                                            F   "                   {                     `                                           6                     *    @1              =    1              1    @1                                __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_funcall rb_obj_clone rb_obj_class rb_obj_classname rb_eRuntimeError rb_raise rb_ivar_defined rb_ivar_get rb_check_type rb_int2inum rb_str_new rb_string_value rb_funcall2 rb_scan_args __stack_chk_fail strlen rb_str_buf_new rb_str_buf_cat2 rb_str_buf_append rb_check_frozen memcpy ruby_xmalloc free rb_data_object_alloc rb_eNotImpError rb_obj_alloc rb_obj_call_init rb_eArgError rb_obj_is_kind_of rb_str_cmp Init_digest rb_intern rb_define_module rb_define_module_function rb_define_module_under rb_define_method rb_define_private_method rb_cObject rb_define_class_under rb_include_module rb_define_singleton_method rb_define_alloc_func libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.14 GLIBC_2.4 GLIBC_2.2.5 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                       B     ii   M     ui	   W      p-                   x-             `      -             -      /                    /                    /                    /                    /                    /         "           /         '           /         (           /         )           0                     0                    (0                    00                    80                    @0         	           H0         
           P0                    X0                    `0                    h0                    p0                    x0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                     0         !           0         #            1         $           1         %           1         &           1         )            1         *           (1         +           01         ,           81         -           HH  HtH             5  %   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %}  D  %u  D  %m  D  %e  D  %]  D  %U  D  %M  D  H=I  HB  H9tH  Ht	        H=  H5  H)HHH?HHtH  HtfD      =   u+UH=   HtH=  d  ]     w    H5  11Lff.     H5}  11,ff.     U11SHHH5`  H5d  H1H1HH[] SH57  1HH1H[ff.     UHSHHHgHH5  HHS  H81f     PXH5  Hf.     PXH5  Hf.     PXH5q  Hjf.     PXH5X  HJf.     SHtZHD  H[ HtGH5  HHtH5  H"   HH$HC 8u#[f     HY  H5  H81HA  H5z  H81 HH[HxHff.      HSH+HxHff.      USHHHH߾"   HVH{ U HH[]D  ATUHSHH"   HHs1Le LHHpS0LS H[]A\ff.      ATUSHHHt$wHO"   HHH|$Lc 1HD$LHPHpU(HH[]A\fUSHH|$H|$HD$HXHhH?H9wR1H44HxHt71LB  fL ΃@AA40LW@4WHH9uH[]HF  H5	  H81D  HT@ HHH5  H׉HH&fD  U11SHHH5`  H5d  H1H1HH[]ff.     @ USHH3	  HdH%(   HD$1Hd~xH5  1H1H$   1H5  HsH5  1H1`H5  1HH1JHBHL$dH3%(   uH[] HHfD  ATUHSHIHxEH5[  HHLHHH5>  H11HHYHH5  jH[]A\fATUSHH9tJHHHxH"   IHm "   HH{ IT$HH[]A\ff.      H9=  ATUSt7HHxIkHHAT$ HH1H  []A\H  H52  H81`ATUSH dH%(   HD$1~nHIԉH|$HHD$L^HUsHD$H|$(HL$H|$1H5     KHL$dH3%(   u!H []A\H  H5  H81D  USHHs  HdH%(   HD$1H~pH5A  1H1H$   1H5  HH5  1H1H5  1HH1HHL$dH3%(   uH[]HHNff.      HH11dH%(   HD$1HH$0H$HxHL$dH3%(   uHf     UHSHHH(H5V  dH%(   HD$1Ht{H5  1H1H\$HD$H|$H|$Ht$H|$HFH9Gt1HL$dH3%(   uKH([]D  suٸ        H11$H11HD$HD${@ HH=I  LH=J  HV  9H=0  H;  &H=^  H   H=H  H   H=?  H  H=:  H     HH5"  HH  xH=  H5     H9H5  HH  H=     HH5  H=  1HH5K  H=q  1HH5)  H=U  1H|H5[  H=9  1H@H5  H=     HH5K  eH=  1HeH52  IH=  1HyH5  -H=  H*H5  H=  1HH5  H=  H/H5  H=l  1HH5  H=P  1HH5  H=4  1HKH5  H=  1H/H5h  cH4  H=  H5S  HH5  HH  H=  H}H5  !H=  HH5  H=  VHw  H=  H5  H"  H5HHD  H=8     H,H5  H=  1HH5   tH=     H!H5   UH=     HH5  6H=  1HH5   H=  1HH5   H=  1HH5B   H  HH               %s does not implement %s() block_length reset finish update digest string too long 01 #< :  > no data given hexdigest digest_length Digest hexencode Instance << == inspect new hexdigest! to_s size Class metadata Base initialize_copy        Incompatible digest API version Digest::Base cannot be directly inherited in Ruby       Digest::Base is an abstract class       0123456789abcdef;        @   X   l  @           0  P8  pT   t  0  `       `(   T  h  @    P     @,  X  P    p  P              zR x  $      p`   FJw ?:*3$"       D   P             \             p          $      =    EEG fDA       %    E_         7    ADG             EAK           EAK            EAK     <      EAK     X      AU
J      x  "    HU      "    HU $     ;    EAG hDA (     R    FAD CAB  ,      ^    FAA G0G DAB(   ,  0    AAD0z
AAA    X            l  *    HZ $     A    EEG fDA (         EAN0
AAD (     t~    FAD oAB  (     b    FAA VAB  (   0  `    MAA q
ABE0   \  @    FAA D@}
 AABA (         EAN0
AAA      PW    H I
A (         EDJ@}
AAF      H   H                GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   `      -                                                                                                         c                          #             p-                           x-                    o    `             H                   
                                   0             x                                                            	              o    @      o           o    
      o                                                                                                                                                                   -                      P      `      p                                                                          0      @      P      `      p                                                                          0      @      P      `      p                           GA$3a1       !#               GA$3p1067        #                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY                          GA+GLIBCXX_ASSERTIONS   digest.so-1.8.7-16.el8.x86_64.debug 7'27zXZ  ִF !   t/W9] ?Eh=ڊ2N	:'dPW؀^Mme3r7NT?\5>\yv@=]ڽ!]8uv˘ ٭JЩ7%ZOu!Dѽ([,(ۻ"7tFF5xIA=D"{>+
'gZAcg^'IoSc}82
݂SqQ;)[֋/cۍZ{[PJtd/WSfуC{ruR)ޅ+2},9q-wޤrK5 nb%bAmxat/40v_B_~ȏd y8<Yާ#5x$&J[Ld!-ު~;0+<޴9E߂0WO`VɼN2iRP~Zlg iPW5Tf	H-r]Ds
H qѥ%gakٰ "PJa~NF_=&pPV9]CEOw@`G.F=U}$oJb,Bw[/R
HeKK_6R3O,)8Ry3,z4J(*d~mJ5Ċ֖02þQcaeV_UiXrU8!N(` P'gA>_-+ŷܦ͍gI
zFAFpt<Pt?hC8Gg
y7pj-os=WLO]l) <Aa)@GwcT>|\e1ҏE{tfI9W"iiA*3C>`ƟEUy̷(eFڟltX-ZO*j|\:2 ;,fnM?	c,:LeM;)"In~#28߬R_ i.^V;6ez);Bޘq?iV`)CNMOT7dm"Ȓ猷CTiZ+u     VYq
 &  ng    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                               8      8      $                                 o       `      `      4                             (                                                   0             H      H                                   8   o       
      
      d                            E   o       @      @      @                            T                                                     ^      B                   x                          h                                                       c             @      @      `                            n                         P                            w                         "                             }             #      #                                                 0#      0#                                                $      $                                                 %      %                                                 )      )                                                  p-      p-                                                x-      x-                                                -      -                                                 -      -      0                                        /      /      H                                           0       0      @                                         @1      @1      `                                            1`     @1      H                                                  3      (                                                   3      |                                                   ,8      +                             PK     Y\      x86_64-linux/config.hnu [        /* confdefs.h */
#define PACKAGE_NAME ""
#define PACKAGE_TARNAME ""
#define PACKAGE_VERSION ""
#define PACKAGE_STRING ""
#define PACKAGE_BUGREPORT ""
#define PACKAGE_URL ""
#define OLD_YACC 1
#define STDC_HEADERS 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STRINGS_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_UNISTD_H 1
#define __EXTENSIONS__ 1
#define _ALL_SOURCE 1
#define _GNU_SOURCE 1
#define _POSIX_PTHREAD_SEMANTICS 1
#define _TANDEM_SOURCE 1
#define HAVE_LONG_LONG 1
#define HAVE_OFF_T 1
#define SIZEOF_INT 4
#define SIZEOF_SHORT 2
#define SIZEOF_LONG 8
#define SIZEOF_LONG_LONG 8
#define SIZEOF___INT64 0
#define SIZEOF_OFF_T 8
#define SIZEOF_VOIDP 8
#define SIZEOF_FLOAT 4
#define SIZEOF_DOUBLE 8
#define SIZEOF_TIME_T 8
#define rb_pid_t pid_t
#define rb_gid_t gid_t
#define rb_uid_t uid_t
#define HAVE_PROTOTYPES 1
#define TOKEN_PASTE(x,y) x##y
#define HAVE_STDARG_PROTOTYPES 1
#define NORETURN(x) __attribute__ ((noreturn)) x
#define NOINLINE(x) __attribute__ ((noinline)) x
#define HAVE_DECL_SYS_NERR 1
#define HAVE_LIBCRYPT 1
#define HAVE_LIBDL 1
#define HAVE_LIBRT 1
#define HAVE_DIRENT_H 1
#define STDC_HEADERS 1
#define HAVE_SYS_WAIT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_UNISTD_H 1
#define HAVE_LIMITS_H 1
#define HAVE_SYS_FILE_H 1
#define HAVE_SYS_IOCTL_H 1
#define HAVE_SYS_SYSCALL_H 1
#define HAVE_FCNTL_H 1
#define HAVE_SYS_FCNTL_H 1
#define HAVE_SYS_SELECT_H 1
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TIMES_H 1
#define HAVE_SYS_PARAM_H 1
#define HAVE_SYSCALL_H 1
#define HAVE_PWD_H 1
#define HAVE_GRP_H 1
#define HAVE_A_OUT_H 1
#define HAVE_UTIME_H 1
#define HAVE_MEMORY_H 1
#define HAVE_SYS_RESOURCE_H 1
#define HAVE_NETINET_IN_SYSTM_H 1
#define HAVE_FLOAT_H 1
#define HAVE_PTHREAD_H 1
#define HAVE_UCONTEXT_H 1
#define HAVE_TIME_H 1
#define SIZEOF_RLIM_T 8
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
#define HAVE_ST_BLKSIZE 1
#define HAVE_STRUCT_STAT_ST_BLOCKS 1
#define HAVE_ST_BLOCKS 1
#define HAVE_STRUCT_STAT_ST_RDEV 1
#define HAVE_ST_RDEV 1
#define HAVE_INT8_T 1
#define SIZEOF_INT8_T 1
#define HAVE_UINT8_T 1
#define SIZEOF_UINT8_T 1
#define HAVE_INT16_T 1
#define SIZEOF_INT16_T 2
#define HAVE_UINT16_T 1
#define SIZEOF_UINT16_T 2
#define HAVE_INT32_T 1
#define SIZEOF_INT32_T 4
#define HAVE_UINT32_T 1
#define SIZEOF_UINT32_T 4
#define HAVE_INT64_T 1
#define SIZEOF_INT64_T 8
#define HAVE_UINT64_T 1
#define SIZEOF_UINT64_T 8
#define HAVE_STRUCT_TIMEZONE 1
#define GETGROUPS_T gid_t
#define RETSIGTYPE void
#define HAVE_ALLOCA_H 1
#define HAVE_ALLOCA 1
#define HAVE_FSEEKO 1
#define HAVE_FTELLO 1
#define HAVE_DUP2 1
#define HAVE_MEMMOVE 1
#define HAVE_STRCASECMP 1
#define HAVE_STRNCASECMP 1
#define HAVE_STRERROR 1
#define HAVE_STRFTIME 1
#define HAVE_STRCHR 1
#define HAVE_STRSTR 1
#define HAVE_STRTOUL 1
#define HAVE_CRYPT 1
#define HAVE_FLOCK 1
#define HAVE_VSNPRINTF 1
#define HAVE_ISNAN 1
#define HAVE_FINITE 1
#define HAVE_ISINF 1
#define HAVE_HYPOT 1
#define HAVE_ACOSH 1
#define HAVE_ERF 1
#define HAVE_FMOD 1
#define HAVE_KILLPG 1
#define HAVE_WAIT4 1
#define HAVE_WAITPID 1
#define HAVE_SYSCALL 1
#define HAVE_CHROOT 1
#define HAVE_FSYNC 1
#define HAVE_GETCWD 1
#define HAVE_EACCESS 1
#define HAVE_TRUNCATE 1
#define HAVE_FTRUNCATE 1
#define HAVE_TIMES 1
#define HAVE_UTIMES 1
#define HAVE_FCNTL 1
#define HAVE_LOCKF 1
#define HAVE_LSTAT 1
#define HAVE_SYMLINK 1
#define HAVE_LINK 1
#define HAVE_READLINK 1
#define HAVE_SETITIMER 1
#define HAVE_SETEUID 1
#define HAVE_SETREUID 1
#define HAVE_SETRESUID 1
#define HAVE_SETEGID 1
#define HAVE_SETREGID 1
#define HAVE_SETRESGID 1
#define HAVE_PAUSE 1
#define HAVE_LCHOWN 1
#define HAVE_GETPGRP 1
#define HAVE_SETPGRP 1
#define HAVE_GETPGID 1
#define HAVE_SETPGID 1
#define HAVE_INITGROUPS 1
#define HAVE_GETGROUPS 1
#define HAVE_SETGROUPS 1
#define HAVE_GETPRIORITY 1
#define HAVE_GETRLIMIT 1
#define HAVE_SETRLIMIT 1
#define HAVE_SYSCONF 1
#define HAVE_GROUP_MEMBER 1
#define HAVE_DLOPEN 1
#define HAVE_SIGPROCMASK 1
#define HAVE_SIGACTION 1
#define HAVE__SETJMP 1
#define HAVE__LONGJMP 1
#define HAVE_SETSID 1
#define HAVE_TELLDIR 1
#define HAVE_SEEKDIR 1
#define HAVE_FCHMOD 1
#define HAVE_MKTIME 1
#define HAVE_TIMEGM 1
#define HAVE_GETTIMEOFDAY 1
#define HAVE_COSH 1
#define HAVE_SINH 1
#define HAVE_TANH 1
#define HAVE_ROUND 1
#define HAVE_SETUID 1
#define HAVE_SETGID 1
#define HAVE_SETENV 1
#define HAVE_UNSETENV 1
#define RUBY_SETJMP(env) _setjmp(env)
#define RUBY_LONGJMP(env,val) _longjmp(env,val)
#define RUBY_JMP_BUF jmp_buf
#define HAVE_STRUCT_TM_TM_ZONE 1
#define HAVE_TM_ZONE 1
#define HAVE_STRUCT_TM_TM_GMTOFF 1
#define HAVE_DAYLIGHT 1
#define HAVE_VAR_TIMEZONE 1
#define TYPEOF_VAR_TIMEZONE long
#define NEGATIVE_TIME_T 1
#define POSIX_SIGNAL 1
#define GETPGRP_VOID 1
#define SETPGRP_VOID 1
#define RSHIFT(x,y) ((x)>>(int)y)
#define FILE_READPTR _IO_read_ptr
#define FILE_READEND _IO_read_end
#define HAVE__SC_CLK_TCK 1
#define STACK_GROW_DIRECTION -1
#define _REENTRANT 1
#define _THREAD_SAFE 1
#define HAVE_LIBPTHREAD 1
#define HAVE_NANOSLEEP 1
#define HAVE_GETCONTEXT 1
#define HAVE_SETCONTEXT 1
#define DEFAULT_KCODE KCODE_NONE
#define USE_ELF 1
#define DLEXT_MAXLEN 3
#define DLEXT ".so"
#define RUBY_LIB "/opt/alt/ruby18/lib64/ruby/1.8"
#define RUBY_SITE_LIB "/opt/alt/ruby18/lib64/ruby/site_ruby"
#define RUBY_SITE_LIB2 "/opt/alt/ruby18/lib64/ruby/site_ruby/1.8"
#define RUBY_VENDOR_LIB "/opt/alt/ruby18/lib64/ruby/vendor_ruby"
#define RUBY_VENDOR_LIB2 "/opt/alt/ruby18/lib64/ruby/vendor_ruby/1.8"
#define RUBY_PLATFORM "x86_64-linux"
#define RUBY_ARCHLIB "/opt/alt/ruby18/lib64/ruby/1.8/x86_64-linux"
#define RUBY_SITE_ARCHLIB "/opt/alt/ruby18/lib64/ruby/site_ruby/1.8/x86_64-linux"
#define RUBY_VENDOR_ARCHLIB "/opt/alt/ruby18/lib64/ruby/vendor_ruby/1.8/x86_64-linux"
PK     Y\ʈx  x    x86_64-linux/env.hnu [        /**********************************************************************

  env.h -

  $Author: knu $
  $Date: 2007-03-03 16:28:54 +0900 (Sat, 03 Mar 2007) $
  created at: Mon Jul 11 11:53:03 JST 1994

  Copyright (C) 1993-2003 Yukihiro Matsumoto

**********************************************************************/

#ifndef ENV_H
#define ENV_H

extern struct FRAME {
    VALUE self;
    int argc;
    ID last_func;
    ID orig_func;
    VALUE last_class;
    struct FRAME *prev;
    struct FRAME *tmp;
    struct RNode *node;
    int iter;
    int flags;
    unsigned long uniq;
} *ruby_frame;

void rb_gc_mark_frame _((struct FRAME *));

#define FRAME_DMETH  1
#define FRAME_FUNC   2

extern struct SCOPE {
    struct RBasic super;
    ID *local_tbl;
    VALUE *local_vars;
    int flags;
} *ruby_scope;

#define SCOPE_ALLOCA  0
#define SCOPE_MALLOC  1
#define SCOPE_NOSTACK 2
#define SCOPE_DONT_RECYCLE 4
#define SCOPE_CLONE   8

extern int ruby_in_eval;

extern VALUE ruby_class;

struct RVarmap {
    struct RBasic super;
    ID id;
    VALUE val;
    struct RVarmap *next;
};
extern struct RVarmap *ruby_dyna_vars;

#endif /* ENV_H */
PK     Y\L@  @    x86_64-linux/syslog.sonu ȯ        ELF          >    `      @       9          @ 8 	 @                                 )      )                    X-      X-      X-                                p-      p-      p-      0      0                   8      8      8      $       $                    )      )      )                             Std   )      )      )                             Ptd   X%      X%      X%                           Qtd                                                  Rtd   X-      X-      X-                                  GNU ۹gP߮z"ݟ       )         @   @)   +       BE|.*qX                            q                                                                I                                          _                     @                                                                                                                                                                                                                                                 U                                                                                                            c                      U                     %                     l                                                                                                          /                                                                                    ,                       y                     F   "                   7                                                                    1                  81                        m          1               __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_check_type rb_class2name __snprintf_chk rb_str_new2 __stack_chk_fail rb_fix2int rb_scan_args rb_string_value rb_check_safe_obj ruby_strdup rb_num2int openlog setlogmask rb_block_given_p rb_yield rb_ensure rb_gv_get rb_eRuntimeError rb_raise rb_int2inum rb_secure rb_f_sprintf __syslog_chk rb_eArgError rb_eTypeError rb_cNilClass rb_cFalseClass rb_cSymbol rb_cTrueClass closelog free Init_syslog rb_define_module rb_define_module_under rb_include_module rb_define_module_function rb_define_const libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.4 GLIBC_2.2.5 GLIBC_2.3.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                           ii        ui	        ti	         X-                   `-                   h-             h-      /                    /                    /                    /                    /                    /                    /                    /                    /         #           /         $           /         %           /         (           0                     0                    (0                    00                    80                    @0                    H0         	           P0         
           X0                    `0                    h0                    p0                    x0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                    0                     0         !           0         "           0         %           0         &           0         '           HH!  HtH     5R!  %S!   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !%}  D  %u  D  %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  H=  H  H9tH.  Ht	        H=y  H5r  H)HHH?HHtH%  HtfD      =5   u+UH=
   HtH=v  9d  ]     w      1Hff.     H     AV   AUATUSHH  dH%(   H$  1     D5h  D-e  HHD%\  H-m  AV   HAUILb  1AT      UH HbH$  dH3%(   uGH  []A\A]A^    HHmL     HI      1J HH   HHBHHD     HH   HHcHD f.     USH(dH%(   HD$1H    H1LL$HLD$HH  H<$<  H4H<$H$HxNH|$H  H   @   H|$  H   @     5  H=  k1     ǉb  xudHL$dH3%(   H   H([]fD  {mfD       H|$Hc        f H=  HH  HD  1@ H=  dH$Hw  H5|  H81nff.        u
   @ Hc=a  ff.     ^  u
   @ Hc=5  ff.     .  u
   @ Hc=	  ff.     ATIU   S{~1  t?L[H  HH]   1A\fH  H5  H81nH_  H5  H81VfD  SHH   iH[@ SHH   IH[@ SHH   )H[@ SHH   	H[@ SHH   H[@ SHH   H[@ SHH   H[@ SHH1H[    ~  u
   @ H=q  ff.     ATUS~,_H>Lf@t6HkLމH[]A\H  H5o	  H81Ht5Ht<HtN@t<H]H5	  HH\  H81H[  H8Ho  H8H  H8HO  H8fS   H  t;Hugǉ=O  H[D  ǉ=3  H[H  H5  H81H     tNH=     H                  HHw  H5  H81nff.      ATIUHSHXHL[]A\    HH=  <H5  HH[  6H=O  HH=  H=9  HH5  H=  H^H5I  H=  H?H51  H=  1HH5  gH=  1HH5  KH=  1HKH5  /H=  1HH5  H=l  HH5  H=M  1HH5  H=1  1HxH5  H=     HYH5{  H=     H:H5b  ~H=     HH5L  _H=  1HH59  CH=  1HH5%  'H=x     HH5  H=Y     HuH5     H=0  H5  H9   H=  H5  H   H=  H5  H   _H=  H5  H   ?H=  H5z  H    H=  H5e  H    H=p  H5P  HyP   H=P  H59  HYH   H=0  H5&  H9   H=  H5  HX   H=  H5  H1bH=  H5  H0   BH=  H5  H   "H=  H5  H8   H=s  H5  H|(   H=S  H5  H\   H=3  H5s  H<@   H=  H5\  H   H=  H5E  H   bH=  H50  H   BH=  H5  H   "H=  H5  H   H=s  H5  H|   H=S  H5  H\   H=3  H5  H<   H=  H5  H1H=  H5  HH=  HH5  p   FH=  H5q  HH=  HH5Y  1   H=x  H5B  HH=j  H^H5)     H=9  H5  HBH=+  HH5     H=  H5  HH=  HH5  t   JH=  H5  HH=  HAH5  5   H=|  H5  HH=n  HH5m     H==  H5U  HFH=/  HHH59     HH   <#%s: opened=true, ident="%s", options=%d, facility=%d, mask=%d>        wrong number of arguments (%d for 2+)   must open syslog before setting log mask        <#%s: opened=false> syslog already open 03 $0 no log message supplied must open syslog before write %s type mismatch: %s given syslog not opened Syslog Constants reopen open! opened? ident options facility close mask mask= LOG_MASK LOG_UPTO inspect instance LOG_PID LOG_CONS LOG_ODELAY LOG_NDELAY LOG_NOWAIT LOG_PERROR LOG_AUTH LOG_AUTHPRIV LOG_CRON LOG_DAEMON LOG_FTP LOG_KERN LOG_LPR LOG_MAIL LOG_NEWS LOG_SYSLOG LOG_USER LOG_UUCP LOG_LOCAL0 LOG_LOCAL1 LOG_LOCAL2 LOG_LOCAL3 LOG_LOCAL4 LOG_LOCAL5 LOG_LOCAL6 LOG_LOCAL7 LOG_EMERG emerg LOG_ALERT alert LOG_CRIT crit LOG_ERR err LOG_WARNING warning LOG_NOTICE notice LOG_INFO info LOG_DEBUG debug  ;      X   8   8  L  `    (  X  (  X(  <  P  8|  X  x        $  @  8\  hp  (    (  X             zR x  $      X   FJw ?:*3$"       D                \             p          T          FGB A(A0JOJNKIb
0A(A BBBH      8)    HQ       P&    HQ (     h   EAD@
AAG   8  $          L  ($          `  D$       (   t  `z    BDH `
NIE         EV            EV            EV            EV            EV      ,      EV      H      EV      d      ES        $       (         FAA m
ABA      o    Eu
FV
A           Ha
A (      D)    FDF OCB      ,  Hm   HM                GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 h-             G             V             f             q             |                                                                  "             X-                           `-                    o    `                                
                                   0                                                     p
             h      	              o    0
      o           o    	      o                                                                                                                                                                                           p-                                                                  0      @      P      `      p                                                                          0      @      P      `      p                     GA$3a1       -"               GA$3p1067         "                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY            5               GA+GLIBCXX_ASSERTIONS   syslog.so-1.8.7-16.el8.x86_64.debug '7zXZ  ִF !   t/] ?Eh=ڊ2N2ZT\|]ܹEOp2<_#O9220Z`evqWX
Ayskߨ,8V[Ġ,]\UMF}A/٤F^P.du~*BMv!7=:t/+6Y=WgEq=j3yOSQgVZq`jAts@+2Z%b[hl+FH+Rl` 1iEG=R<Rs䁩f_a*z:(ӐMZinnG 5vu'Z)T/?!22bPaKCl~b)>O&!}I>$vuiG-
siTNZJPdГ9I@Ӥ(@1Gќ>f*;F61Q53	FF;i^doL?ΦD~%Bf Qu~=R	mY&yv
b_ݑ}-N(0fy3Ys(Xi%|^`)Xb
AKy|2'F7>,5%q- յtǅxKrLᯩ@?_`>?,-I3T}:\vE5^16*Vɋ
F˂&Zm0$
#u F+̉~kk2t].(6wceeގJ?OxÊ.LSTs=C &/9Tܦ7Y/BԷnyXA~"S~y| 6eV񧹣prPhϑmƝY-4:q{]hHʏ9_fib!V
Q=^~v2u422euwgU^dVd;,3=mZoi(_}dS6(ôV4ua|;	_  t۾6. $   drɱg    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                     8      8      $                                 o       `      `      4                             (                         8                          0                                                      8   o       	      	      Z                            E   o       0
      0
      @                            T             p
      p
      h                           ^      B                                             h                                                       c                                                     n                                                     w             `      `                                   }              "       "                                          2       0"      0"      '                                         X%      X%                                                 8&      8&      H                                          )      )                                                  X-      X-                                                `-      `-                                                h-      h-                                                 p-      p-      0                                        /      /      `                                           0       0                                                 1       1                                                 1      1      (                                            81`     1      H                                                  T3      (                              "                     |3      T                                                   7      1                             PK     Y\f"  "    x86_64-linux/rbconfig.rbnu [        
# This file was created by mkconfig.rb when ruby was built.  Any
# changes made to this file will be lost the next time ruby is built.

module Config
  RUBY_VERSION == "1.8.7" or
    raise "ruby lib version (1.8.7) doesn't match executable version (#{RUBY_VERSION})"

  TOPDIR = File.dirname(__FILE__).chomp!("/lib/ruby/1.8/x86_64-linux")
  DESTDIR = '' unless defined? DESTDIR
  CONFIG = {}
  CONFIG["DESTDIR"] = DESTDIR
  CONFIG["PATCHLEVEL"] = "374"
  CONFIG["INSTALL"] = '/usr/bin/install -c'
  CONFIG["EXEEXT"] = ""
  CONFIG["prefix"] = (TOPDIR || DESTDIR + "/opt/alt/ruby18")
  CONFIG["ruby_install_name"] = "ruby"
  CONFIG["RUBY_INSTALL_NAME"] = "ruby"
  CONFIG["RUBY_SO_NAME"] = "ruby"
  CONFIG["MANTYPE"] = "doc"
  CONFIG["NROFF"] = "/usr/bin/nroff"
  CONFIG["configure_args"] = " '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--program-prefix=' '--disable-dependency-tracking' '--prefix=/opt/alt/ruby18' '--exec-prefix=/opt/alt/ruby18' '--bindir=/opt/alt/ruby18/bin' '--sbindir=/opt/alt/ruby18/sbin' '--sysconfdir=/etc' '--datadir=/opt/alt/ruby18/share' '--includedir=/opt/alt/ruby18/include' '--libdir=/opt/alt/ruby18/lib64' '--libexecdir=/opt/alt/ruby18/libexec' '--localstatedir=/var' '--sharedstatedir=/var/lib' '--mandir=/opt/alt/ruby18/share/man' '--infodir=/opt/alt/ruby18/share/info' '--enable-shared' '--enable-rpath' '--enable-pthread' 'build_alias=x86_64-redhat-linux-gnu' 'host_alias=x86_64-redhat-linux-gnu' 'CFLAGS=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/opt/alt/openssl/include' 'LDFLAGS=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -L/opt/alt/openssl/lib64 -L/opt/alt/ruby18/lib64 -Wl,-rpath=/opt/alt/openssl/lib64,-rpath=/opt/alt/ruby18/lib64'"
  CONFIG["vendordir"] = "$(libdir)/ruby/vendor_ruby"
  CONFIG["sitedir"] = "$(libdir)/ruby/site_ruby"
  CONFIG["sitearch"] = "x86_64-linux"
  CONFIG["arch"] = "x86_64-linux"
  CONFIG["MAKEFILES"] = "Makefile"
  CONFIG["EXPORT_PREFIX"] = ""
  CONFIG["COMMON_HEADERS"] = ""
  CONFIG["COMMON_MACROS"] = ""
  CONFIG["COMMON_LIBS"] = ""
  CONFIG["MAINLIBS"] = ""
  CONFIG["ENABLE_SHARED"] = "yes"
  CONFIG["DLDLIBS"] = " -lc"
  CONFIG["SOLIBS"] = "$(LIBS)"
  CONFIG["LIBRUBYARG_SHARED"] = "-Wl,-R -Wl,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)"
  CONFIG["LIBRUBYARG_STATIC"] = "-l$(RUBY_SO_NAME)-static"
  CONFIG["LIBRUBYARG"] = "$(LIBRUBYARG_SHARED)"
  CONFIG["LIBRUBY"] = "$(LIBRUBY_SO)"
  CONFIG["LIBRUBY_ALIASES"] = "lib$(RUBY_SO_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_SO_NAME).so"
  CONFIG["LIBRUBY_SO"] = "lib$(RUBY_SO_NAME).so.$(MAJOR).$(MINOR).$(TEENY)"
  CONFIG["LIBRUBY_A"] = "lib$(RUBY_SO_NAME)-static.a"
  CONFIG["RUBYW_INSTALL_NAME"] = ""
  CONFIG["rubyw_install_name"] = ""
  CONFIG["LIBRUBY_DLDFLAGS"] = "-Wl,-soname,lib$(RUBY_SO_NAME).so.$(MAJOR).$(MINOR)"
  CONFIG["LIBRUBY_LDSHARED"] = "$(CC) -shared"
  CONFIG["debugflags"] = ""
  CONFIG["optflags"] = ""
  CONFIG["cflags"] = "$(optflags) $(debugflags)"
  CONFIG["cppflags"] = ""
  CONFIG["RDOCTARGET"] = ""
  CONFIG["ARCHFILE"] = ""
  CONFIG["EXTOUT"] = ".ext"
  CONFIG["PREP"] = "miniruby$(EXEEXT)"
  CONFIG["setup"] = "Setup"
  CONFIG["EXTSTATIC"] = ""
  CONFIG["STRIP"] = "strip -S -x"
  CONFIG["TRY_LINK"] = ""
  CONFIG["LIBPATHENV"] = "LD_LIBRARY_PATH"
  CONFIG["RPATHFLAG"] = " -Wl,-R%1$-s"
  CONFIG["LIBPATHFLAG"] = " -L%1$-s"
  CONFIG["LINK_SO"] = ""
  CONFIG["LIBEXT"] = "a"
  CONFIG["DLEXT2"] = ""
  CONFIG["DLEXT"] = "so"
  CONFIG["LDSHARED"] = "$(CC) -shared"
  CONFIG["CCDLFLAGS"] = " -fPIC"
  CONFIG["STATIC"] = ""
  CONFIG["ARCH_FLAG"] = ""
  CONFIG["DLDFLAGS"] = ""
  CONFIG["ALLOCA"] = ""
  CONFIG["MAKEDIRS"] = "mkdir -p"
  CONFIG["CP"] = "cp"
  CONFIG["RM"] = "rm -f"
  CONFIG["INSTALL_DATA"] = "$(INSTALL) -m 644"
  CONFIG["INSTALL_SCRIPT"] = "$(INSTALL)"
  CONFIG["INSTALL_PROGRAM"] = "$(INSTALL)"
  CONFIG["SET_MAKE"] = ""
  CONFIG["LN_S"] = "ln -s"
  CONFIG["OBJDUMP"] = ""
  CONFIG["DLLWRAP"] = ""
  CONFIG["WINDRES"] = ""
  CONFIG["NM"] = ""
  CONFIG["ASFLAGS"] = ""
  CONFIG["AS"] = "as"
  CONFIG["AR"] = "ar"
  CONFIG["RANLIB"] = "ranlib"
  CONFIG["YFLAGS"] = ""
  CONFIG["YACC"] = "yacc"
  CONFIG["OUTFLAG"] = "-o "
  CONFIG["CPPOUTFILE"] = "-o conftest.i"
  CONFIG["GNU_LD"] = "yes"
  CONFIG["EGREP"] = "/usr/bin/grep -E"
  CONFIG["GREP"] = "/usr/bin/grep"
  CONFIG["CPP"] = "gcc -E"
  CONFIG["OBJEXT"] = "o"
  CONFIG["CPPFLAGS"] = " $(DEFS) $(cppflags)"
  CONFIG["LDFLAGS"] = "-L. -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -L/opt/alt/openssl/lib64 -L/opt/alt/ruby18/lib64 -Wl,-rpath=/opt/alt/openssl/lib64,-rpath=/opt/alt/ruby18/lib64 -rdynamic -Wl,-export-dynamic"
  CONFIG["CFLAGS"] = "-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/opt/alt/openssl/include  -fPIC $(cflags)"
  CONFIG["CC"] = "gcc"
  CONFIG["target_os"] = "linux"
  CONFIG["target_vendor"] = "redhat"
  CONFIG["target_cpu"] = "x86_64"
  CONFIG["target"] = "x86_64-redhat-linux-gnu"
  CONFIG["host_os"] = "linux-gnu"
  CONFIG["host_vendor"] = "redhat"
  CONFIG["host_cpu"] = "x86_64"
  CONFIG["host"] = "x86_64-redhat-linux-gnu"
  CONFIG["build_os"] = "linux-gnu"
  CONFIG["build_vendor"] = "redhat"
  CONFIG["build_cpu"] = "x86_64"
  CONFIG["build"] = "x86_64-redhat-linux-gnu"
  CONFIG["TEENY"] = "7"
  CONFIG["MINOR"] = "8"
  CONFIG["MAJOR"] = "1"
  CONFIG["target_alias"] = ""
  CONFIG["host_alias"] = "x86_64-redhat-linux-gnu"
  CONFIG["build_alias"] = "x86_64-redhat-linux-gnu"
  CONFIG["LIBS"] = "-lpthread -lrt -ldl -lcrypt -lm "
  CONFIG["ECHO_T"] = ""
  CONFIG["ECHO_N"] = "-n"
  CONFIG["ECHO_C"] = ""
  CONFIG["DEFS"] = ""
  CONFIG["mandir"] = "$(DESTDIR)/opt/alt/ruby18/share/man"
  CONFIG["localedir"] = "$(datarootdir)/locale"
  CONFIG["libdir"] = "$(DESTDIR)/opt/alt/ruby18/lib64"
  CONFIG["psdir"] = "$(docdir)"
  CONFIG["pdfdir"] = "$(docdir)"
  CONFIG["dvidir"] = "$(docdir)"
  CONFIG["htmldir"] = "$(docdir)"
  CONFIG["infodir"] = "$(DESTDIR)/opt/alt/ruby18/share/info"
  CONFIG["docdir"] = "$(datarootdir)/doc/$(PACKAGE)"
  CONFIG["oldincludedir"] = "/usr/include"
  CONFIG["includedir"] = "$(DESTDIR)/opt/alt/ruby18/include"
  CONFIG["localstatedir"] = "$(DESTDIR)/var"
  CONFIG["sharedstatedir"] = "$(DESTDIR)/var/lib"
  CONFIG["sysconfdir"] = "$(DESTDIR)/etc"
  CONFIG["datadir"] = "$(DESTDIR)/opt/alt/ruby18/share"
  CONFIG["datarootdir"] = "$(prefix)/share"
  CONFIG["libexecdir"] = "$(DESTDIR)/opt/alt/ruby18/libexec"
  CONFIG["sbindir"] = "$(DESTDIR)/opt/alt/ruby18/sbin"
  CONFIG["bindir"] = "$(DESTDIR)/opt/alt/ruby18/bin"
  CONFIG["exec_prefix"] = "$(DESTDIR)/opt/alt/ruby18"
  CONFIG["PACKAGE_URL"] = ""
  CONFIG["PACKAGE_BUGREPORT"] = ""
  CONFIG["PACKAGE_STRING"] = ""
  CONFIG["PACKAGE_VERSION"] = ""
  CONFIG["PACKAGE_TARNAME"] = ""
  CONFIG["PACKAGE_NAME"] = ""
  CONFIG["PATH_SEPARATOR"] = ":"
  CONFIG["SHELL"] = "/bin/sh"
  CONFIG["ruby_version"] = "$(MAJOR).$(MINOR)"
  CONFIG["rubylibdir"] = "$(libdir)/ruby/$(ruby_version)"
  CONFIG["archdir"] = "$(rubylibdir)/$(arch)"
  CONFIG["sitelibdir"] = "$(sitedir)/$(ruby_version)"
  CONFIG["sitearchdir"] = "$(sitelibdir)/$(sitearch)"
  CONFIG["vendorlibdir"] = "$(vendordir)/$(ruby_version)"
  CONFIG["vendorarchdir"] = "$(vendorlibdir)/$(sitearch)"
  CONFIG["topdir"] = File.dirname(__FILE__)
  MAKEFILE_CONFIG = {}
  CONFIG.each{|k,v| MAKEFILE_CONFIG[k] = v.dup}
  def Config::expand(val, config = CONFIG)
    val.gsub!(/\$\$|\$\(([^()]+)\)|\$\{([^{}]+)\}/) do |var|
      if !(v = $1 || $2)
	'$'
      elsif key = config[v = v[/\A[^:]+(?=(?::(.*?)=(.*))?\z)/]]
	pat, sub = $1, $2
	config[v] = false
	Config::expand(key, config)
	config[v] = key
	key = key.gsub(/#{Regexp.quote(pat)}(?=\s|\z)/n) {sub} if pat
	key
      else
	var
      end
    end
    val
  end
  CONFIG.each_value do |val|
    Config::expand(val)
  end
end
RbConfig = Config # compatibility for ruby-1.9
CROSS_COMPILING = nil unless defined? CROSS_COMPILING
PK     Y\X      x86_64-linux/socket.sonu ȯ        ELF          >    0      @                 @ 8 	 @                                 @      @                    ؼ      ؼ      ؼ      X                                            0      0                   8      8      8      $       $                                                                Std                                               Ptd   H      H      H                         Qtd                                                  Rtd   ؼ      ؼ      ؼ      (      (                      GNU ynݏZT[k-N       t             X-p t   x   }   BEvjdu|ޛm<nY7uqX0L*F,%o-q)                                                                                           )                                                                                                           n                      S                     !                                                                                      K                                          )                                          g                     g                     	                                                                                                         s                                           F                                                                                                                                                    a                                                                                     [                                          t                                                                                                         w                      U                                                                #                     ]                     Q                     J                     Q                                          X                                          D                                                                 T                     y                     ;                                           j                     (                                                                                    |                     (                     ;                                                                                      B                     <                     ,                                                               l                     I                                                                                                                              d                                          s                                                                                                                                                                                                                                                             ,                                                                 8                     ]                                           F   "                                                             ;                     .                     F                                                                   0              }    p                 x                                    P2      O            @2             a    h                 0              =                 o    X                 `                                                          g       __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize getnameinfo gai_strerror rb_raise rb_str_new2 __stack_chk_fail tcp_sockaddr sock_sockaddr rb_str_new rb_string_value_ptr strlen rb_eArgError rb_eTypeError rb_assoc_new rb_int2inum rb_check_string_type rb_num2int rb_check_safe_obj rb_fix2int __sprintf_chk strtol rb_ary_new3 rb_scan_args rb_string_value rb_string_value_cstr getservbyname strtoul gethostbyaddr rb_ary_new rb_ary_push rb_secure rb_ensure gethostname rb_sys_fail rb_io_close free ruby_xmalloc rb_fdopen rb_io_synchronized socketpair rb_obj_alloc __errno_location rb_gc rb_io_taint_check rb_io_check_closed rb_read_pending fileno rb_tainted_str_new rb_io_set_nonblock recvfrom rb_obj_taint rb_bug rb_eIOError rb_trap_immediate rb_trap_pending rb_str_unlocktmp rb_io_wait_readable rb_str_locktmp rb_thread_wait_fd rb_prohibit_interrupt rb_thread_critical rb_thread_pending rb_thread_schedule rb_trap_exec accept rb_cSocket rb_cUNIXSocket rb_cTCPSocket fcntl bind rb_str_new4 connect __fdelt_chk rb_thread_select getsockopt freeaddrinfo listen rb_cIO recvmsg rb_funcall2 rb_intern getpeername getsockname ruby_strdup setsockopt rb_thread_fd_writable sendto rb_io_wait_writable send ruby_safe_level shutdown rb_eSecurityError rb_define_const rb_obj_is_kind_of sendmsg strncpy __snprintf_chk getaddrinfo __memcpy_chk strcmp rb_check_array_type __strcpy_chk rb_protect rb_jump_tag rb_cInteger rb_num2ulong gethostbyname rb_ary_new2 Init_socket rb_eStandardError rb_define_class rb_cBasicSocket rb_undef_method rb_define_singleton_method rb_define_method rb_cIPSocket rb_define_global_const rb_cTCPServer rb_cUDPSocket rb_cUNIXServer rb_define_module_under libruby.so.1.8 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.2.5 GLIBC_2.15 GLIBC_2.4 GLIBC_2.3.4 /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                                                                                               ui	                            ii   )     ui	        ti	   3      ؼ             P1                   1                                              (                    0         }           8         x           @                    H                    P                     X         y           `         ~           h         0           p         7           x         z                    <                    u                    v                    L                                        T                    V                                        |           ȿ         f           п         g           ؿ         h                    j                    k                    l                    p                                                    (                    0                    8                    @                    H                    P         	           X         
           `                    h                    p                    x                                                                                                                                                                                                                                                                                                                     !                    "                     #                    $                    %                    &                     '           (         (           0         )           8         *           @         +           H         ,           P         -           X         .           `         /           h         1           p         2           x         3                    4                    5                    6                    8                    9                    :                    ;                    =                    >                    ?                    @                    A                    B                    C                    D                    E                     F                    G                    H                    I                     J           (         K           0         M           8         N           @         O           H         P           P         Q           X         R           `         S           h         U           p         W           x         X                    Y                    Z                    [                    \                    ]                    ^                    _                    `                    a                    b                    c                    d                    e                    i                    l                    m                     n                    o                    p                    q                     r           (         s           HHi  HtH             5қ  %ӛ   h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   h2   h3   h4   h5   h6   h7   qh8   ah9   Qh:   Ah;   1h<   !h=   h>   h?   h@   hA   hB   hC   hD   hE   hF   hG   qhH   ahI   QhJ   AhK   1hL   !hM   hN   hO   hP   hQ   hR   hS   hT   hU   hV   hW   qhX   ahY   QhZ   Ah[   1h\   !h]   h^   h_   h`   ha   hb   %  D  %  D  %  D  %  D  %}  D  %u  D  %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %ݔ  D  %Ք  D  %͔  D  %Ŕ  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %}  D  %u  D  %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %ݓ  D  %Փ  D  %͓  D  %œ  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %}  D  %u  D  %m  D  %e  D  %]  D  %U  D  %M  D  %E  D  %=  D  %5  D  %-  D  %%  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  %ݒ  D  %Ւ  D  %͒  D  %Œ  D  %  D  %  D  %  D  %  D  %  D  %  D  %  D  H=  H  H9tHn  Ht	        H=Y  H5R  H)HHH?HHtH͎  HtfD      =   u+UH=ʎ   HtH=  d  ]     w      1Hff.     HIf?
   j   LDE1E1VZYuHÉH=  H5`  H1ff.     S   H  dH%(   H$  1HHuHH$  dH3%(   u	H  [ff.     1     ftf
u#H   O    H   :RH=  H5_  1AUSHH|$Ht$'f8   Hl$HUHn   HXHH9r^Ha  H9u
Hn   Hma  Hu'HtHT$uHtH   H	H[]    HnuHHUHHnH9uH  H5i  H81jH  n   H5i  H81MHN  H5 _  H815H떉HGH`  SHH9HCH H=^  HH[HD  USHH|$Ht$H fuXH1HŨu%HtHD$uHtH %   H	E {frHHH[]Hq  H5h  H81X     AVIAUIATUHSHH   HuUAHHHtLHtHU   H=^  H   AE    []A\A]A^Ð;f     H߃   []AE A\A]A^fIHIT$   H=e]  H       H=?]  H       H=1]  H tJ   H=]  H       H=	]  H    A   fA   @ 'fD     H=\  H t>	   H=\  H u<AE        A   _@ []AE    A\A]A^       H=\  H t.	   H=\  H uLAE    E    AE    1    H=[  H u5A   f   H=-\  H u"AE 
   H=  H5[  1H=  H5[  1ff.     @ AVAUATUSHH  DdH%(   H$  1fA  fE  fAG  fA
  L$   H[     1   LLDj  IE      If
   LM      A   HEHjZY  LH
   LHD1HWIL   HcH1HT
H$  dH3%(   6  H  []A\A]A^ f
   IH߸      LDHE1E1j 0^_      f     H=Y  L$   DE  IE@ H=5Z  L$   D  IEQH=Z  L$   D  IE{!H=Y  L$   \D  IEKL8H:(qH=r  H5X  H1f     UHY  SH(dH%(   HD$1Hl$HIH\H|$tdHlHdH|HHqHHHtI@fHL$dH3%(   HHD uiH([]     H=X  THD$D  H$1Ht$HXHHT$: tHD$H=s  HH5X  HH1AUHX  ATUSH(dH%(   HD$1H\$LD$HYHH|$H
  @   SHD$HpHxOHH   NH} IrLH2LHIH]Ht'H;Ht ;HLH\H;HuHc}LH@H]H;Ht$@ HcuHLHH;HuHL$dH3%(   LuXH([]A\A]fHD$Hp HD$1HpH   H=ۆ  H5,W  1epS   H>1H  H[    SHHV  H`dH%(   HD$X1HLD$H\$tvHD$   H$Ht$HD$ H8  H   HH=4>  HD$(    HD$0   HD$8   HD$@    HD$HFH\$XdH3%(   uH`[H$HD$HD${ff.     SHH V  HpdH%(   HD$h1HHHD$ P1LL$ LD$HD$Ht$0H\$0HD$H    HH=m=  HD$8HD$HD$`    HD$@HD$ HD$PHD$(HD$XH    HD$hXZH  dH\$hdH3%(   uHp[f     S   H  dH%(   H$  1HT  Hx,HƄ$   SH$  dH3%(   uH  [H=T  k&fD  ATAUHSH tH}HE    0   DH5S  HEHH     H@    H@    @    H@     H@(    KDH5oT  H9C   HHCH[]A\ff.      ATUHHSHH dH%(   HD$1HL$Ht$H߃   Ld$t$|$Lxn\$HHǉ1Dd$HHDH1HH^HT$dH3%(   u_H []A\D  [{@  vH=ZS  D  t$|$LISZf.     UHHS  SH(dH%(   HD$1HL$LD$u'HD$      HD$      f     HT$~HL$H1   bH|$dH3<%(   uH([]fD  UHHSHt;HH{HH1^HHsHxHH[]HfD  AWAVAUA@   ATAUSHHHQ  H8  dH%(   H$(  1HL$LD$D$   H|$Ht@P  CAA@H|$@P  (IHHhHH} xJ  H} L1AHHHHl$ 2HsIDLL$LDH   H9CiHqAtuEt$A   t$HHHHH$(  dH3%(   H   H8  []A\A]A^A_fD  HSHCH Au   D$tHHH4H    CH|$AA@@(IH=Z  1H=UP  H/|  H5)P  H81.9f        HH        HH     1HHff.     AWAVAUATUSHHHJO  Hh  L$,LD$HHL$@dH%(   H$X  1D$<   H|$HD$    Ht@  D$H|$@@  HD$H;HXHH;N  H;7Ht$1AH H-yz  IHD$PHD$HD$<HD$ <Hz         AH=M   D  HLDL$HsDHT$LL$ LD$D} E    HSz  D} IAHy  uHy  
[D$(Hy  D$(UD$(tD$(HAMH@ L9kbHD$,      t_H$X  dH34%(   H   Hh  []A\A]A^A_ KHD$NHCLkB( 돐+D$fD$<toH|$HHHzf     t$<H|$HHHP    t$<H|$HHH(H߾   zHH=L  Hx  H5L  H81f        HH1fD     HH1fD     HH1fD  1HH1if     AWAVAUE1ATUSH(H|$   H$HL$ Hyw  L=w  I    !HT$H4$D3   Hw  AD3A$uH"w  
   HQw  uSA$yk   |(w E   A   w    a   E1YD$t$D$t$A$x H|$ tBH|$4$4$H([H]1A\A]A^A_D$t$sD$t$6H(Hc[]A\A]A^A_1f     USH(  dH%(   H$  1D$   HXHH;H\$HHL$11't$HHHHH$  dH3%(   u
H(  []ff.     USH(  dH%(   H$  1D$   HXH'H;H\$HHL$H)u  H81t$HHpHH%H$  dH3%(   u
H(  []s SH   dH%(   H$   1LHXHH;D$n   P1HL$HT$1H$   dH34%(   u	HĐ   [f.     SH   dH%(   H$   1HXHH;D$n   HL$HT$Het  H81cH$   dH34%(   u	HĐ   [rfSH   dH%(   H$   1LHXHH;D$   P1HL$HT$1H$   dH34%(   u	HĠ   [f.     SH   dH%(   H$   1HXHH;D$   HL$HT$H=s  H81cH$   dH34%(   u	HĠ   [rfAUIATIUH   SHH0HH;`LLxRÉǾ   1t6   ߉1wtHHH[1]A\A]1H=F  USH(  dH%(   H$  1D$   H\$HhHHHL$HHq  H8t$HH9HHH$  dH3%(   u
H(  []<ff.     SH   dH%(   H$   1HXHPHq  HHL$HT$D$n   H8lH$   dH34%(   u	HĐ   [ff.     SH   dH%(   H$   1HXHHq  HHL$HT$D$   H8H$   dH34%(   u	HĠ   [;ff.     ATUSHHH|$Ht$H
HXHNHD$H;L`Hh	DHxH   []A\H=D  ff.      ATUSHHH|$Ht$BH|$HHD${HXHH'HD$H;L`HhrDH5xHH[HD ]A\H=WD  eD  AWAVAULcATE1U   S   HH  Dl$L|$0L$   dH%(   H$8  1DAL ?)AED$HD$,HHD$HD$(HD$fD  LHİ   u~HLDHHLHLLH	\0|$E11LLH	İ   L~H\0t1H$8  dH3%(   udHH  []A\A]A^A_LD$HL$      |$D$,   u"T$(MT$T$됸f     SHHHt
HC    H{0HtHC0    {<x`   [f     UH   SHH&H߃t>H/HhHsH} :މxH   []ÐH=(B  +ff.     ATUHHA  SH  dH%(   H$  1HLD$5u!HBm  H H$HD$        ~HH$   kL`LI<$v   H1HHc~E1H{?)Ѻ   H1H	Ā   1I<$Hl$0H$  HD$`HD$`HD$ H      HD$    D$    HD$h   HD$(   HD$8   D$@    HǄ$      H$   Ǆ$   1Ht$|H=  HT$8H  H$   H   $      $      Hc$   H<$H\Ht6H5[o  HtNHD$   HL$PH\$PHHD$XEWHH$  dH34%(   Hu*H  []A\fH=@  H<$HHn  H=n     1H5(J  sH=n     H5I  1YH=n     H5vI  1?H=n     H5I  1%H=p?  if     USH   dH%(   H$   1D$n   Hl$HXH2H;HT$HKx)t$H{H$   dH3%(   uHĘ   []H=>  ff.     fUSH   dH%(   H$   1D$   Hl$NHXHH;ZHT$Hx%HH$   dH3%(   uHĨ   []H=O>  6USH(  dH%(   H$  1D$   Hl$HXHH;HT$Hx)t$H[H$  dH3%(   uH(  []H==  ]ff.     fUSH   dH%(   H$   1D$n   Hl$HXHbH;*HT$H[x)t$HH$   dH3%(   uHĘ   []H=*=  ff.     fUSH   dH%(   H$   1HXHH{ Ht&qH$   dH3%(   u]HĘ   []@ H;D$n   Hl$[HT$Hx,D$H}HH<  H9HCJHHC 15D  USH   dH%(   H$   1D$   Hl$HXHH;HT$Hx%HH$   dH3%(   uHĨ   []H=;  aUSH(  dH%(   H$  1D$   Hl$.HXHrH;:HT$Hkx)t$HH$  dH3%(   uH(  []H=:;  ff.     fAVAUATI   UHSHH HL$dH%(   HD$1hH߃  H  H|$@  H   H   HtH   @   ? utD$   A   Ll$LL`LEI<$ELމ   HT$dH3%(         H []A\A]A^D  !t#
tgH|$DHD$LhDpyfD$    A   Ll$_     HH|$@A   Ll$D$I|$ Tff.     @ AWAVIAUA   ATIUSH8dH%(   HD$(1H\$Hl$ILD$ HH!9  LD12HJH|$tH:LHXHH{H  AH-c  L=<d  L5c     L@HXLD$H   LD$HD$ADHPHpDm AAD(u"Hac  
   Hc     D(   D   H|$ HD$Dm E    HHNHtAHD$DHPHpb     LD$1        HD$HD$D([fD  HL$(dH3%(   HcHD u<H8[]A\A]A^A_ÐHD$vHD$@ H;gH=>7  ff.     @ UHAVAUIHATISHdH%(   HE1   LA   AHE   H9tH   H$   H9uH  H$   LLt$IHxbL
LhLNI} LELDމxOuLHMdH3%(   u>He[A\A]A^]    [LA4GA/I} UHSHdH%(   HD$1H`  8~#   H   H      HH5  1H<$Htq@u[Ã   HHhH?H} މtOHT$dH3%(      uAH[]@        H_  H5s?  H81y1}Hn`  H5o?  H81UD  UHSHcHH\HHH_  H8H=c  HHH[]rfUHSHHH   dH%(   H$   1H_  H0H     H.HHhHfH$   Ƅ$    HD$@HD$@HD$HD$PD$dD$t    H} HD$ H      H$    D$    HD$H   HD$   HD$(   D$0    HD$P   HD$X\$`F1H:HtLH$   dH3%(      u/HĘ   []fHHXH,H;H=A3  H]  H5=  H81@ ATUSH   Ht$H\$HkH{HdH%(   H$   1H)HD$    lHCf    H   H|$fD$HIHkwsLHk   'n   Hu.Ht&HT$uHtH   H	    H$   dH3%(   uHĐ   []A\H]  k   H5<  H81    AUH2  ATU1SH  dH%(   H$x  1Ld$Ll$HD$0   HD$(   MMH\$HD$    HHHD$    HD$   HD$   HD$8PHD$8PHD$8P1H H|$t%HHl$p   HHƄ$o   LL$1It5A   I      1H$p  L 1     H5H|$f)D$@)D$P)D$`Ht_@  LEHtH   H=/  H   Hƹ	   H=/   uD$D
       H|$ Ht@#  D$HH|$(Ht@   D$LH|$0Ht@   bD$@HL$8HT$@HH  H\$8H4  NI H{HcsHHHt6HcsHHt6zHcsHHt6iHL^H[(HuH|$8LH$x  dH3%(      HĈ  []A\A] K4fD  ;fD  +fD  D$DfLH$p     HHƄ$o    D$D   kH=]  H5.  H1DOH=]  H5-  1*f.     AWAVAUATUSH   H$ H  H-  E1dH%(   H$  1HL$LD$0HD$   HD$    HD$(   HD$8    HD$0   HD$   =H|$0Ht@  AH|$&HH  HPHD$H     LD$pHp   Lf|$p
IHCG  HU  LǾ   L$  A      L$   HMAUL^_v  H|$8H   H_(H   L$  H$      H{   HM      A   f?
DHAUZY	  HL  LL  H[(HuH|$8LDLH9HHH$  dH3%(     H  []A\A]A^A_D  AcH  LǾ   H|$RH  fHD$)D$@)D$P)D$`HPH  s  H@ HHT$HPHT$(HPHT$ H  D$@   H|$ H$   J   HHZƄ$   LL$(IW  A   I      1H$  L+     H1AH|$D$HH   @   0D$DHL$8HT$@HH  HD$8   Hx   f?
EhH@ HHT$HPHT$(H@HD$ 1H$H|$(H$  ?   HHOƄ$   4D$D    YH|$HF   H=(  H uPD$D   H@HD$ jA0   1fD$  H|$8,H=Y  H5v5  1Hƹ	   H=)   D$D
   H|$8HtD$D$H=X  H5'  H16HoT  H5)  H81)HU  H54  H81H|$8HtD$nD$CH=DX  H5w)  H1˿HT  H5=4  H81賿HS  H5o)  H81蛿ff.     AUAATAUSHÅxH[]A\A]fD  k wHDD[]A\A]D  AUIATI   UHSHHdH%(   HD$1H1HL$HLH߃tGJt$<$H19x9L1HT$dH3%(   uH[]A\A]fD  S蜿H=i(  ATIU   SHHdH%(   HD$1BHLH'  1ܾ   t:11   xIH1H\$dH3%(   u9H[]A\ H<$@tYD  蛾H='  ־fD  AWAVAUATAUHSH   Ht$Lt$LdH%(   H$   1DH|$11      O  HD$2    Ll$01M}I}IEf    LH)lH   fL$0HD$Hxk  Ll   LHEuHT$Ht$ Ll$ H=  \$(踿T$      H1HHxH$   dH3%(   H   Hĸ   []A\A]A^A_ n   LxE߾   ٿH1=HUHXH虿HD$Hx{HC {fI}`H=%  TH Q  k   H5<0  H81۽|$bf   1 11 UHSHHP  8~@u_HtVH   tMH臾HXH˾Ct%H{茾    cH   []HH[]HO  H5"%  H81f.     AW1AVI   AUA1ATUSHl   ߉A1VDLɿŅy%κIǋ jtd:u1Ņt=D߾   1H[]A\A]A^A_@ rw҉1WŅuA         A    1D  USHHoHu9f     H[(Ht'SHs1xH   []    H1[]    HHn   H01HHff.     SHHH|$Ht$UH|$˺HHD$莼HXHҼH;蚼HL$1HQHqDxH   [H={"  艾f     H(1ҹ   dH%(   HD$1Hf$HD$    fP  @
    |$H1臿HD$dH3%(   uH(ݹff.     fUSHH|$H3  HM  HH0蹼H   H|$FH|$HD$HhHtVE tN<<   HFH=   3  HH߃   1Ҩ   uduPHH[]fD  H11HH[]fH|$Hމ1HH[]fD  D fD  L fHtD  U    r@ H1HHPfD  H1[]       H=w!  H 2   H=_!  H H޿HHHL  H53!  H81ff.     AVAUATUSH  HoHdH%(   H$  1Lo蚸H} IH   赸LHںH} HtQ,HHtD_H[IHt=H;Ht5 sHLH蔺H;Huf.     1ɺILLHhHc}LHT@ E9CusH{ALH3H[(HuH$  dH3%(   Lu)H  []A\A]A^@ HH1H趶fD  AWAVAAUAATUHSHx  dH%(   H$h  1Ht$`HD$    Hl$IH  @  Hl$HH|$蝵HD$LxLH  H\$@LHP    H詷DHD	   fHL$HLD$HE$    E,    EDl$Dt$Åt>H-M  MtL芵A|
   H5"  HH1s H$h  dH3%(   HD$   Hx  []A\A]A^A_fH\$@I    1I       HL  Hl$гDHD	|$@ uE1H    
   HHHD$    OHD$Htˀ8 uHA   fH5(  H1蟳    DD	uE11Hl$茴HHzH  H5  H81aAU11IATI1ULSHHxpHHH褸@uAHt8AuItIE %   H	E AuItI$%   H	E HH[]A\A]ff.     @ UH1ɺ   S   H  dH%(   H$  1H   HPHpH"HH$   1   HHHXH$  dH3%(   u
HĘ  []6fD  S   HH dH%(   HD$1   H1      AH2F  HH$HH=HD$HT$HF  cHL$dH3%(   uH [訲     S   HH dH%(   HD$1Z   H1      HE  HH$HH=IHD$HT$H@F  ӲHL$dH3%(   uH [     ATIUHSH   H dH%(   HD$11ɺ   LH1HH$HXHH;ͳH$HHE  H=HD$/HtHL$dH3%(      uH []A\H=  蠵[ff.     AVAUATIUHSH   1LH   1mHHL`LVHtJHI<$DsLkDL xHD[   ]A\A]A^fD  H[(HuHH=   AW1I   AVAUATUSH8_8HwdH%(   HD$(1HD$$    IIGt*I Iw(HuHt1ɺ   1xMwIG0AG<M  H--  L%+  LDHD$$L-  HD$Ld$AVAv1A~1AĉD$$   AG<   IG0HtTPHpD轲D$$y=Hl$DArMv(AG<MuD$$y.H|$螳fD  AVIvD1&D$$   AG<   I?1DHL$(dH3%(      H8[]A\A]A^A_f     Mv(Ll$Mif     HL$A      Ǿ   D$$   ܭAVIvD輱D$$Q    DUfD  AhHD$HD$f     AWAVAUIATIUSHHdH%(   HD$81Gj     Hl$HHLHD$8H  P1LL$8LD$0qXHZ臮Ht$011H|$(   LHD$貯HXHLcM   HD$H   HUfD  ۱HD$LHPLhH$耯H$EML*Åy4L\UtYH|$ D}Lu@uɬD  H|$vHcHD HL$8dH3%(   uVHH[]A\A]A^A_    Hm(HuH|$5H=  f     1    L#蓬 UHSHH?  8~@u_HtVH   tMHWHXH蛮H;c1CtCH   []ÐHH[]鲮H[?  H5  H81f.     H?  ATH=5  USH0rH=0  HC  He?  H0UH^?  H5  HH|H;1H H5  TH;   HH5   9H;   HH5  H;1HH5  H;1HjH5  ޭH;HH5  íH;   H4H5  設H;   H)H5  荭H;1HaH5  uH;1HH5  ]H;HH5~  BH;H#H5h  'H;HhH5R  H3H=Q  ݮH->  H=G  HHE 胫H} 1H&H5  ʬH} 1H}H5  豬H} HqH5  蕬H}    HH5  艬Hu H=  IL%B=  H=  HI$I<$   HH5  CI<$HH5  I4$H=  L%<  H=  HI$荪I<$1H0H5  ԫI<$1HWH5t  軫I<$1H~H5k  被I<$HH5<  膫I<$   HVH5=  jHu H=4  :H-;  H=+  HHE H} HH5  $H}    HDH5  H}    HH5  H} HH5  ЪH} HH5  贪H3H=  腬H-;  H=  HHE +H}    HH5%  oH} 1HH5y  VH} 1H9H5F  =H} 1HPH5  $H} HH5w  H}    HH5  H} H<H5   ЩH} HH5  ĩH} HH5  訩Hu H=  hH-Y:  H=  HHE H}    HH5  RH} 1HH5  9H} 1H<H5   H} 1HH5  H}    HH5  H3H=b  輪H9     HHH5p  H跨H;   H(H5  蜨H;   HH5  聨H;   HH5\  fH;   H7H5  KH;1HoH5  3H;1HH5  H;1HH5  H;HH5W  H;HH5  ͧH;   HH5  §H;   HsH5  觧H;1H+H5  菧H;   HH5  tH;HH5  YH;HzH5  >H;HH5  #H;HH5  H;   HH5  H;   HH5b  ҦH;   HH5E  跦H;   H8H5D  蜦H;   HH5$  聦H;   HRH5  fH;H5  臧   H=
  H:  11   H=|
  1   H=t
  1   H=y
  1   H=W
  1
   H=\
  1   H=	  1   H=	  1   H=	  u1   H=	  b1   H==  O   H=	  1<1   H=  )1   H=l	  1   H=   1   H=  11H=	  11H=  1
   H=	  1
   H=  1   H={	  1   H=  1   H=  q1   H=  ^1   H=  K1   H=  8"   H=z  1%1"   H=m  1-   H=b  1-   H=V  1   H=J  1   H=>  1   H=3  1   H=)  1   H=$  1    H=  z1   H=  g1   H=  T1@   H=  A1   H=  .11H=  1   H=     H=  111H=  1   H=  1   H=  1   H=  1   H=  1   H=  1   H=  v1   H=  c1   H=  P1   H=  =1   H=  *1  H=  11H=  1H=    H=  11   H=  1  H=  1  H=  1H=  1   H=  1   H=~  o1   H=v  \1   H=j  I1   H=^  61   H=W  #1   H=S  1    H=K  1!   H=H  1"   H=F  1#   H=E  $   H=F  11   H=D  1   H=J  1   H=Q  x1   H=Q  e1   H=G  R1   H=A  ?1   H=;  ,1   H=0  1   H=&  1   H=   1   H=  1   H=  1	   H=  1
   H=  1   H=     H=  11   H=  n1   H=  [1   H=  H1   H=  51   H=  "1   H=  1   H=  1   H=  1   H=  1   H=8  1   H=M  1   H=  1   H=  1   H=  w1   H=  d   H=  1Q1   H=  >1   H=}  +1H=u  1H=q  1H=h  1H=b  1H=X  1H=P  1H=H  1H=@  1H=8  1H=1  m1H=+  Z1   H=#  G1   H=  4   H=  1!   H=  1    H=  1   H=  1  H=
  1    H=
  1   H=
  1   H=
  1   H=
  1   H=
  1v   H=
  1c1H=
  1S   H=
  1@[   ]H=
  1A\) HH   getnameinfo: %s unknown socket family:%d not an AF_UNIX sockaddr AF_UNIX AF_INET PF_INET PF_UNIX PF_AX25 PF_IPX unknown socket domain %s SOCK_STREAM SOCK_DGRAM SOCK_RAW SOCK_SEQPACKET SOCK_RDM SOCK_PACKET unknown socket type %s AF_UNSPEC AF_INET6 AF_LOCAL unknown:%d 11 tcp no such service %s/%s host not found 22 gethostname w socketpair(2) 02 recvfrom for buffered IO recvfrom(2) recv for buffered IO accept(2) bind(2) connect(2) listen(2) recvmsg(2) for_fd getpeername(2) getsockname(2) 21 send(2) 01 sendmsg(2) 24 %ld getaddrinfo: %s sockaddr length too big expecting String or Array socket(2) socket(2) - udp Insecure: can't close socket <any> <broadcast> hostname too long (%d) service name too long (%d) sendto(2) SocketError BasicSocket initialize do_not_reverse_lookup do_not_reverse_lookup= close_read close_write shutdown setsockopt getsockopt getsockname getpeername send recv recv_nonblock IPSocket IPsocket peeraddr recvfrom getaddress TCPSocket TCPsocket gethostbyname TCPServer TCPserver accept_nonblock sysaccept listen UDPSocket UDPsocket connect bind recvfrom_nonblock UNIXSocket UNIXsocket path send_io recv_io socketpair UNIXServer UNIXserver connect_nonblock gethostbyaddr getservbyname getaddrinfo getnameinfo unpack_sockaddr_in unpack_sockaddr_un Constants AF_AX25 AF_IPX AF_APPLETALK PF_APPLETALK PF_UNSPEC PF_INET6 PF_LOCAL AF_SNA PF_SNA AF_ROUTE PF_ROUTE AF_ISDN PF_ISDN AF_MAX PF_MAX PF_KEY MSG_OOB MSG_PEEK MSG_DONTROUTE MSG_EOR MSG_TRUNC MSG_CTRUNC MSG_WAITALL MSG_DONTWAIT SOL_SOCKET SOL_IP SOL_TCP SOL_UDP IPPROTO_IP IPPROTO_ICMP IPPROTO_IGMP IPPROTO_TCP IPPROTO_EGP IPPROTO_PUP IPPROTO_UDP IPPROTO_IDP IPPROTO_TP IPPROTO_RAW IPPORT_RESERVED IPPORT_USERRESERVED INADDR_ANY INADDR_BROADCAST INADDR_LOOPBACK INADDR_UNSPEC_GROUP INADDR_ALLHOSTS_GROUP INADDR_MAX_LOCAL_GROUP INADDR_NONE IP_OPTIONS IP_HDRINCL IP_TOS IP_TTL IP_RECVOPTS IP_RECVRETOPTS IP_RETOPTS IP_MULTICAST_IF IP_MULTICAST_TTL IP_MULTICAST_LOOP IP_ADD_MEMBERSHIP IP_DROP_MEMBERSHIP IP_DEFAULT_MULTICAST_TTL IP_DEFAULT_MULTICAST_LOOP IP_MAX_MEMBERSHIPS SO_DEBUG SO_REUSEADDR SO_REUSEPORT SO_TYPE SO_ERROR SO_DONTROUTE SO_BROADCAST SO_SNDBUF SO_RCVBUF SO_KEEPALIVE SO_OOBINLINE SO_NO_CHECK SO_PRIORITY SO_LINGER SO_PASSCRED SO_PEERCRED SO_RCVLOWAT SO_SNDLOWAT SO_RCVTIMEO SO_SNDTIMEO SO_ACCEPTCONN SO_SECURITY_AUTHENTICATION SO_BINDTODEVICE SO_ATTACH_FILTER SO_DETACH_FILTER SO_PEERNAME SO_TIMESTAMP TCP_NODELAY TCP_MAXSEG EAI_ADDRFAMILY EAI_AGAIN EAI_BADFLAGS EAI_FAIL EAI_FAMILY EAI_MEMORY EAI_NODATA EAI_NONAME EAI_SERVICE EAI_SOCKTYPE EAI_SYSTEM AI_PASSIVE AI_CANONNAME AI_NUMERICHOST AI_ALL AI_ADDRCONFIG AI_V4MAPPED NI_MAXHOST NI_MAXSERV NI_NOFQDN NI_NUMERICHOST NI_NAMEREQD NI_NUMERICSERV NI_DGRAM SHUT_RD SHUT_WR SHUT_RDWR     too long sockaddr_un - %ld longer than %d       sockaddr_un.sun_path not NUL terminated not an AF_INET/AF_INET6 sockaddr        s_recvfrom_nonblock called with bad value       file descriptor was not passed (msg_controllen=%d, %d expected) file descriptor was not passed (cmsg_len=%d, %d expected)       file descriptor was not passed (cmsg_level=%d, %d expected)     file descriptor was not passed (cmsg_type=%d, %d expected)      Insecure: can't shutdown socket `how' should be either 0, 1, 2  neither IO nor file descriptor  too long unix socket path (max: %dbytes)        sockaddr size differs - should not happen       array size should be 3 or 4, %ld given  sockaddr resolved to multiple nodename  newline at the end of hostname  SO_SECURITY_ENCRYPTION_TRANSPORT        SO_SECURITY_ENCRYPTION_NETWORK  ;  Y     (  0  8D  h      X  h    H(         8\  hx  8      8   XT    X  x    $  أ8      8  X  x  <  h  8    8   	  8$	  ج`	  x	  	  x	  
  <
  
  H
  ȱ
    (4  `  X      H  <      (  H$  L  |    x  x  h     4          X0  d  |  h      T  8    x  ,  P  X    X  l               zR x  $      @   FJw ?:*3$"       D   0             \              p   T    DN YAH
A        (T    AL@
AA      d             `O    w(         EAD0
AAH      ;    Ne   (   (      EAD0s
AAA `   T     BEE A(D0f
(A BBBBb
(A FBBC)
(A JBBH d        BBB A(A0JBFAe
0A(A BBBDcHFA   (          EHD@
AAI 8   L     FIA A(DP"
(A ABBC     Ԗ)    Ec             ENp
AA 0         ENWFoA`
AA      0z    ELV
AA(          BDD AB  0   L     FAG G@
 AABF (         EKF@|
AAA (     pZ    EGD z
DAA  L        BBB H(D0A8V6
8A0A(B BBBG      (  t          <            P         L   d     BBB B(A0A8V	
8A0A(B BBBD        h            t                               `     w   BBB E(A0C8D`
8A0D(D BBBE^
8D0A(B BBBE(   h      EAG
AAA(     (    EAG
AAA      v    EGc
AA      ~    EGk
AA      Tv    EGc
AA    ,  ~    EGk
AA8   P      BED I(G0_
(F CBBE (     p    EAG
AAA      u    EGb
AA      @u    EGb
AA0      r    FAA G0M
 FABA 0   4      FAA G0d
 CFBA H   h  Dg   BBB E(D0F8L
8A0A(B BBBA     hG    EA  (     u    EIG B
FAB 4        FAK I
 AABC   (   4  x    EAGr
AAA(   `      EAGn
AAA(     P    EAGr
AAA(     Ī    EAGr
AAA(     8    EAGL
AAE(   	  ̫    EAGn
AAA(   <	  0    EAGr
AAA@   h	     FBB I(D0GP
0A(A BBBF H   	   A   FBE J(D0A8Dp
8A0A(B BBBB(   	  $/   ECDHH
H(   $
  (   EDD0
AAE $   P
  >    ADR ZGA ,   x
  4|   EDM
AAC   0   
  	   FAA G
 AABAP   
  `V   FIA C(GGdFFK
(A ABBD  p   0  l   FBB B(A0A8G L""E"I"A"d"B"F"A"}
8A0A(B BBBF H     [    BED C(D0O
(C ABBGX(G CBB   8         FEI D(G@l
(A ABBG 0   ,      FDH G0g
 AABD L   `     BBB B(D0D8G#
8A0A(B BBBD        <            8       4     4    EDD [
FAAD
DAE H         BDJ G(A0A8F@h
8C0A(B BBBE 0   \   Y    EAD w
FAHDCA      L$    KV       dw    EG X
FA      c    D0Y
A L        AAD0
AAGP
DAC\
DAGd
CAHD   8  J   FBB A(A0G
0A(A BBBE   L     ?   BBE E(A0D8G	9
8A0A(B BBBC   4         FIF D(D0j(D ABB(         EKL	v
AAA    4  h    EL0p
AA     X      EL0p
AA 0   |  @    FDD L@
 AABA <         FBB D(D0k
(F BBBG   H     <G   FLB B(A0A8Dp
8A0A(B BBBJX   <  @   FBB E(D0A8FoURD
8A0A(B BBBH4         EDD Z
FABD
DAE (     g   MHA ;FK                  GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     P1      1                                                                                                              ?             $             h             ؼ                                               o    `                                
       l                                         H	                                                           	              o    h      o           o    d      o                                                                                                                                                                                                                                                                                                                                                 @$      P$      `$      p$      $      $      $      $      $      $      $      $       %      %       %      0%      @%      P%      `%      p%      %      %      %      %      %      %      %      %       &      &       &      0&      @&      P&      `&      p&      &      &      &      &      &      &      &      &       '      '       '      0'      @'      P'      `'      p'      '      '      '      '      '      '      '      '       (      (       (      0(      @(      P(      `(      p(      (      (      (      (      (      (      (      (       )      )       )      0)      @)      P)      `)      p)      )      )      )      )      )      )      )      )       *      *       *      0*      @*      P*      `*               GA$3a1 $      u               GA$3p1067  `1      g                GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY     `1      u1               GA+GLIBCXX_ASSERTIONS   socket.so-1.8.7-16.el8.x86_64.debug cs7zXZ  ִF !   t/] ?Eh=ڊ2NHj ٦*xZ%"[,385bU&[L'w<0CC}ylF_'ٱa)̇)@7L;xAXe~լ56YKe2EVNZz)
ꖋB@CBk *9>޲L|`(4zEq	WsfďGG)z¶$ V7Jx$XSvoG,rhBW)ZSN9h/Vc)O`F2S{oF@OM0VI#Ǭ65~;b^_c	.h"ɵ39!+Zn`u7~	eykL\Oo!)H5ʌ|\83VC{WDK1oRiX*Q9vQC^wHl2ylBIx16]a>k2KJy)c,Ϊl?۬
	?]Vc窣SG2/O?b#%vR_7Ҕm_hVfO)^@rHM5.l%z5'm-P+5BNnmXjM9:DS`c@ad/b;3	։Ɠi><6k=vQ|4M{]ˊsŮDK"]Ѝ2CülI[0-<?L4$h+?fgLnpmkkJ0)6!~m<UɧTuFS"Y_nnY(K<}=޼+I`	q;'rR;u܄OM^d7N?ۥnֹofF$[Ev+u?>r!%,J|o'ŀ 68psдQ,[q')^!P$ʔ<qQpxciכ#C <#vջA)`xz
wSgmr	<,)\a#%vWҺg3u0%:}FFl)]V&E#u)pSlcs?ӯ@Z[ayîs|E$`TofOl<\9s%ά@YE[!	K pћM0#Wjry[k&&:l=Z$4ưsUiQ> ?AYI	*5 3UɆxݼ 1c3u =E: 5!=![RO]&i47@5BSumafIn20LB,ɺ
f'˵!;Y}^ٓAK[A\Nё9P'k/
&ٴiUT2}*>Tbm-j?`t*oT_SGc$)qQF ;6Gg+25#H1s/$
ɦ{8ƷKiɽ%L팙r	B q(1zIE(ӧ#QT(|W$HPN_3bw|aMe].o|9/R'GG.;G  *)} 7  ֪@g    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                   8      8      $                                 o       `      `      d                             (                         0                          0                         l                             8   o       d      d                                 E   o       h      h      p                            T                                                    ^      B                   H	                          h             $      $                                    c             0$      0$      @                            n             p*      p*      0                            w             0      0      a                             }             h      h                                          2       x      x                                               H      H                                                                                                                                                                  ؼ      ؼ                                                                                                                                                                         0                                                                                                              0                                         0      0      h                                            `     0      H                                                  x      (                                                                                                            h      +                             PK     Y\      x86_64-linux/openssl.sonu ȯ        ELF          >     y     @                @ 8 	 @                                 Ȅ     Ȅ                   0     0$     0$     &      *                    p     p$     p$     P      P                   8      8      8      $       $                                                          Std                                         Ptd                  l      l             Qtd                                                  Rtd   0     0$     0$                                 GNU 79(Z=(KO&
                B  " @D@ 	( Q	 4I   
 @B H		$ @ \a   	
  @ @ @ ! @  D @@ H!     $  `
QJ$	 @J)&@    X0 1B  @@ D ₋@  @@  
  b R  H   B@P  @                      	  
                                           "  #  $  '  (  *      +  ,  -  /  0  3  5      7          8  ;  <  ?  @          A  B  C  I  J  K  L  M      N          O      P  Q  S      U          V  W      X  Z          [      \  ^  _  `  a  c  e  f  h  i      j  l      m      n  p  r      s  u      v  w  {      |  }      ~                                                                                                                                                                                                                            
wP')
0t:li-2kE{1bolS6GX{+p=&4U8\x%!!0JSqO_/:<wش7Eǫ2oZ%mނטa}%mp텄e6ZjbI%9<nU">'9<	rJ _z/i(Bг;Yyqc
,TҀ? MPTEtdQk'm!1a,TνcIɌATmqβG'!m>[-Iq#I5AA|7)4y]|[ {+E'm3͍h!,,Y.\*y\X-Կ[6#BEq$B<P=u$.6{i6mјYtƑT7y	.ZJmʮ9ijS<@|NW6w"`v8?I7.2v<g:hُHo(4<G-rwxEcCE)& t9E>Q!I)*%P\8;ӨA+nD[H)t- I)04pߝ)4~-)+b^I-(7evH|wvDqXU`u$.z^H|T	sY`iƵk,oeRFRO\ժ}Nsbyl=v|0zИmXf9Q;e-&uX_SfEӕ2=v$.ѫ	
                            ]                                          ;                     \                     c0                     S*                     48                                           >                     I%                                          2                     ~&                     r                     m<                     
                                                               3                                          U3                     V                                          
3                                          $                                          7                     }"                     Y1                     i*                     
                     h-                                                               ;                                                               M                      +'                                          h                                          '                     E                     <                     G                                          4                     p.                                          z-                     =                     9                     '                     M;                     87                                          86                                          &                     ^
                     :5                                                                                    T0                                          z0                     v;                     g                     4                     -!                     )                     S                                          }                     B(                                                               d                     92                                          B1                     k                     =                     t5                     a,                                          	                                                                                                          |                                          >                     5                                                               /                     6                     d7                     9                                                               ^6                     -                     '                     r$                     Q                     l                     \                     l#                     W2                     Z%                     :                     	                     n                     *                     &                     %                     B,                     ?=                                          .                     }                                           R"                     [                                          q1                     >                     R                     7                     r"                     %                                                                                                         1"                     '                     Z                     ?                     1                     =                     h                     6                     7                     /                     P>                     1                     3                     &                     F   "                   K&                     T$                     3                     k                     -                                           E7                     1                     !                     	                                          -$                     5                     0                     '                     $                     !                     7                     4                     !                     5                     =                                          /                     :                     6'                                          S                                          E
                     0                     Q(                     p=                     2                     *                                          '                     d=                     q2                                           M6                                          1                                                                5/                                                               )                     1                     1                     6                     b'                     6                     S                     d                     o6                     2                     "8                     J8                                                               "                     *                                          #                     .                                          @!                                          \4                     P7                     8                                          g                     F+                     /                     ;                     %                     $                     (                     l                     u
                     8(                                          i                     	                                          Y!                     (                                          0                                                               )                                          '2                     E                                           
$                     :                                          n                     '                     2                     "                     .                     W:                     $                                                               j3                                           2                     *                                                                                                         #:                     F                     0                                                               U                     ,                     x                                                                                    
                                                               %                     *                     6                     U                                           8                                          -                                          }                                          <                     7                     7:                     =                     -                                          1+                                          )                     (                                          8                     
                     `                     d"                                          0                     1                                          L4                                          #                     V                                           ,                                           8                     #                     6                     6                                                                                      U                                          -                                          %                     7                     )8                     6                     >                                                               3                                                               G                                                                                    <                     0                                                                                     '                     W/                     "                     &                                          
                     g!                     (.                     49                     c                     6                     7                     k&                     D/                                           v                      V=                                          #                                          W-                     4                                                               ^                                          0                                                                                                                                                                         B%                     {:                     	1                     +                     G                     ]>                     (=                     u7                     9                                          
                     6                     7                     N
                     -                     .                                          ,                     8                                          2                     >                     (                                          ;                                          e:                     6                     !                     <>                     0                                                                                    X.                                          #                     W,                     +                                                               
                                          E                     :                      ,                     X)                     O'                     -                                          =0                     k4                     t                     C                     w8                     .                     )5                     "                                          
                                          +                     .                     z(                     M,                                                                                    E                     >                                           C                     w+                     5=                     <                                          4-                     x                                          3                     8                     (%                     a                      +                     H#                                                               $                                                               "                     )                     +                     5                     C                     ,                                                                "                     D9                     N                     =*                     4                                                               /                     e)                     (                     =                     $                     6                      <                     G2                     #                     =                     E                     !                     r                                          e2                     
/                                          /                     	                     ,                     a+                                          	                                          -                                          2                     K:                     5                     9                     .                     )                     q                                                               a9                                          8                     (                     :                     3                                                               &                     +                     %;                     /                     &                                          $/                                          ,,                     R                     )                     n:                                           2&                     g                     W                     #                                          '                     t'                     >                                          7                                          n9                      &                     6                                                               6                                                               <                     1                     1)                     0                                          :	                     :                     	+                                          *                     +                     )                                          )                     :                     @3                     +-                     E                     <                                          ]7                     	                     X                     ;                     <                     ,                     5                                                                                                                              #                     *                                          ;$                     &                     q                                          c                      7                     0                                                               %	                                          '                     N<                     (>                     P9                                          ,                                          @<                     :                                          s)                     *                                                               1                     u!                                          8                     4                     &                     1                     U                      	7                     -                     9                     4                                                               R8                                          ;                     (                                          R&                     .                     &+                     :                                          7                                          +                                                                                    n                     q                      /                                                               n                     v                     84                     [                     2                                          :                     )                     3                                          ,                     2                     03                                          L                     >                     d8                                            |                                          	                     #                     =                     =                     :                     d                     9                     (                                          
                     >                     /                     /                                          '<                     2                     X                                          .#                     E                                           ^                                          00                     4                     G                                          3,                     B'                                           3                     8                     p                     *                                                                                      7                     O-                                          !                     "                     (*                     6                     +                     :                                            2                     i                     \                     #                     *7                     {                     ,                       |                     Z;                                           k7                     G                     /                     ;                     H                                                               %                     7                     r                     7                     P                                          3                     !                     C%                     1                     B.                                                               :                     .%                      3                     (                                                               8                     \5                     q>                     M    H     A                           g     2          2     =       
)               4    $            @"    h$            *    $            0(    p$            [                                     C            }    0$            $    PS     j       |2    &     O      s    $            
    P     S       $    @            v4    0B     <           J     )           `$            a    8$            9;    $                @            ,    $            (                    $                $                     ~       :    $            H    p           <    $            -                '    `$            0    $            4    @     ;       r,    p           |    $            !    PG            n%                q    h$            0    H$            Z#    S                $            "    $            (    $                $            5    PL                8$            +    л$            C    $            	    1            	     $            51     $            }     @g     Z                       =    x$            "    $            Y    ;            $     $            2    $                $            i    $            "     C            N    T     1      )    P           ""    $            ,    $            _    $                p             V    ($                $            ?#    H$                G           .    $            -    $            $                /    $                X$                @$            8    $            (    x$                0C     Z       &    P$                     $          ȼ$                               ($            &    @$             .    $            -    $            <    D     +           $            8    t$            y=     $            $    `            O	         [          $            "    $            '
    0;            $                     3     f            D            *9    $            N    $            >         Q       &    X$            !    p$                 J            x/    ؽ$            ~                ?    $             {    `1     =           @                0$            5     |     v      e                !    @J     U       3    $                      a      &    @           #(    P     J      (    pD     i          $            j
    $                02            c%    @            \(    h$            
    W               Ƚ$            %)    $            e	    x$            !         Q       5    P$            +    E     i      3    p:            "    y     s          $                $            !    d     2       c    P$            >    @                $                               p<     *          ($                                 h$            5    M           4    @$            N    ػ$            *    $            
9    p$            0         )      *    $            !    $            t    H$            '0    $            	                c    $                @     Z       <    $            5    `     v      }%                                %    0               Ч     3      !    Ȼ$                            n         Z            e     =      "     j     '	          8$            !    :     Z           $                      Z            pd     2       5    X$                Y     f       	    D     Q       ?    $             6
                    X$            %               ;    $            0    @$            ?    $                 м$                $                p$            1    `     Z       .    н$            !    d            j/                d    3               $            j	                i(                "    0$            %    H$            ?)    C            "     $            J    `$            8    $                            P    x$                `$                $            >                 
    $            j    P$                ؼ$            i$    $            4    K                 $                     |      0    $            U    `     f        __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize rb_check_type EVP_PKEY_type rb_hash_new ossl_bn_new rb_str_new2 rb_hash_aset rb_eRuntimeError rb_raise ossl_raise GetBNPtr BN_copy BN_new eBNError BN_clear_free rb_scan_args rb_fix2int rb_string_value RSA_size rb_str_new RSA_private_decrypt rb_str_set_len rb_num2int rb_iv_get eRSAError __stack_chk_fail RSA_private_encrypt RSA_public_decrypt RSA_public_encrypt i2d_RSAPrivateKey i2d_RSAPublicKey __assert_fail BIO_s_mem BIO_new ossl_pem_passwd_cb PEM_write_bio_RSAPrivateKey BIO_free PEM_write_bio_RSAPublicKey ossl_membio2str GetCipherPtr rb_string_value_ptr RSA_print rb_block_given_p RSA_generate_key ossl_to_der_if_possible ossl_obj2bio PEM_read_bio_RSAPrivateKey EVP_PKEY_assign RSA_new ossl_generate_cb BIO_ctrl PEM_read_bio_RSAPublicKey PEM_read_bio_RSA_PUBKEY d2i_RSAPrivateKey_bio d2i_RSAPublicKey_bio d2i_RSA_PUBKEY_bio RSA_free EVP_PKEY_new EVP_PKEY_free rb_data_object_alloc rb_iv_set RSAPublicKey_dup rb_cFixnum rb_cFalseClass rb_cNilClass rb_cTrueClass rb_cSymbol ossl_rsa_new cRSA rb_eTypeError Init_ossl_rsa ePKeyError mPKey rb_define_class_under cPKey rb_define_singleton_method rb_define_method rb_define_alias rb_define_const ruby_xmalloc EVP_CIPHER_CTX_init rb_obj_class rb_class2name rb_warning rb_intern rb_funcall EVP_CIPHER_CTX_block_size rb_str_resize EVP_CipherUpdate rb_eArgError eCipherError GetDigestPtr EVP_CIPHER_CTX_cipher EVP_BytesToKey EVP_CipherInit_ex OPENSSL_cleanse EVP_md5 rb_ary_new OBJ_NAME_do_all_sorted rb_ary_push EVP_CIPHER_CTX_cleanup ruby_xfree EVP_CIPHER_CTX_set_padding EVP_CIPHER_block_size rb_int2inum EVP_CIPHER_iv_length EVP_CIPHER_CTX_iv_length EVP_CIPHER_key_length EVP_CIPHER_CTX_set_key_length EVP_CIPHER_CTX_key_length EVP_CIPHER_nid OBJ_nid2sn EVP_CipherFinal_ex rb_warn __memcpy_chk EVP_get_cipherbyname rb_check_frozen cCipher rb_obj_is_kind_of EVP_CIPHER_CTX_copy rb_obj_classname ossl_cipher_new Init_ossl_cipher rb_cObject mOSSL eOSSLError rb_define_alloc_func rb_define_module_function SSL_SESSION_print PEM_write_bio_SSL_SESSION cSSLSession memcmp cSSLSocket rb_obj_is_instance_of PEM_read_bio_SSL_SESSION SSL_get1_session SSL_SESSION_new d2i_SSL_SESSION ASN1_d2i_bio SSL_SESSION_free i2d_SSL_SESSION SSL_SESSION_get_id SSL_SESSION_get_timeout rb_cTime SSL_SESSION_set_timeout rb_num2long SSL_SESSION_get_time SSL_SESSION_set_time Init_ossl_ssl_session mSSL X509_STORE_set_ex_data CRYPTO_set_ex_data X509_STORE_get_ex_data CRYPTO_get_ex_data GetX509StorePtr ossl_x509_ary2sk OCSP_basic_verify X509_free sk_pop_free ERR_peek_error ERR_error_string GetX509CertPtr GetPrivPKeyPtr EVP_sha1 OCSP_basic_sign sk_new_null eOCSPError OCSP_resp_count OCSP_resp_get0 OCSP_single_get0_status OCSP_CERTID_dup OCSP_CERTID_free cOCSPCertId asn1time_to_time OCSP_SINGLERESP_get_ext_count OCSP_SINGLERESP_get_ext ossl_x509ext_new rb_Integer rb_protect X509_gmtime_adj OCSP_basic_add1_status X509_EXTENSION_free DupX509ExtPtr OCSP_SINGLERESP_add_ext ASN1_TIME_free cX509Ext rb_jump_tag OCSP_basic_add1_nonce i2d_OCSP_RESPONSE i2d_OCSP_REQUEST OCSP_request_verify OCSP_request_sign OCSP_request_onereq_count OCSP_request_onereq_get0 OCSP_onereq_get0_id OCSP_request_add1_nonce OCSP_cert_to_id OCSP_id_issuer_cmp OCSP_id_cmp OCSP_CERTID_new cOCSPReq OCSP_copy_nonce OCSP_BASICRESP_new OCSP_BASICRESP_free OCSP_response_get1_basic cOCSPBasicRes OCSP_response_status OCSP_response_status_str d2i_OCSP_RESPONSE OCSP_RESPONSE_new OCSP_RESPONSE_free OCSP_response_create OCSP_request_add0_id OCSP_check_nonce d2i_OCSP_REQUEST OCSP_REQUEST_new OCSP_REQUEST_free asn1integer_to_num Init_ossl_ocsp rb_define_module_under mOCSP cOCSPRes i2d_X509_ATTRIBUTE eX509AttrError i2d_ASN1_TYPE i2d_ASN1_SET mASN1 ossl_asn1_get_asn1type ASN1_TYPE_get ASN1_TYPE_free sk_free eASN1Error X509_ATTRIBUTE_get0_object OBJ_obj2nid i2a_ASN1_OBJECT d2i_X509_ATTRIBUTE X509_ATTRIBUTE_new X509_ATTRIBUTE_free OBJ_txt2obj X509_ATTRIBUTE_set1_object ossl_x509attr_new X509_ATTRIBUTE_dup cX509Attr DupX509AttrPtr Init_ossl_x509attr mX509 cEC_GROUP EC_GROUP_get_point_conversion_form cBN rb_obj_alloc ossl_bn_ctx EC_POINT_point2bn eEC_POINT eEC_GROUP EC_POINT_set_to_infinity cEC_POINT EC_POINT_invert EC_POINT_make_affine EC_POINT_is_on_curve EC_POINT_is_at_infinity EC_POINT_dup EC_POINT_bn2point EC_POINT_new EC_POINT_clear_free ECPKParameters_print PEM_write_bio_ECPKParameters i2d_ECPKParameters ASN1_i2d_bio eECError EC_GROUP_set_generator EC_GROUP_cmp EC_POINT_cmp EC_GROUP_new_curve_GFp EC_GFp_nist_method EC_GROUP_new EC_GROUP_dup PEM_read_bio_ECPKParameters EC_GFp_simple_method EC_GFp_mont_method d2i_ECPKParameters rb_str2cstr OBJ_sn2nid EC_GROUP_new_by_curve_name EC_GROUP_set_asn1_flag EC_GROUP_set_point_conversion_form EC_GROUP_clear_free EC_KEY_print EC_KEY_get0_public_key EC_KEY_check_key EC_KEY_get0_private_key PEM_write_bio_ECPrivateKey i2d_ECPrivateKey_bio PEM_write_bio_EC_PUBKEY i2d_EC_PUBKEY_bio ECDSA_verify ECDSA_size ECDSA_sign ECDH_compute_key EC_KEY_set_public_key EC_KEY_set_private_key EC_KEY_set_group EC_KEY_get0_group cEC EC_KEY_dup PEM_read_bio_ECPrivateKey EC_KEY_new PEM_read_bio_EC_PUBKEY d2i_ECPrivateKey_bio d2i_EC_PUBKEY_bio EC_KEY_new_by_curve_name EC_KEY_set_asn1_flag EC_KEY_set_conv_form EC_KEY_free EC_get_builtin_curves rb_ary_new2 rb_undef_method EC_GROUP_get_degree EC_GROUP_set_seed EC_GROUP_get_seed_len EC_GROUP_get0_seed EC_GROUP_get_asn1_flag EC_GROUP_get_curve_name EC_GROUP_get_cofactor EC_GROUP_get_order EC_GROUP_get0_generator EC_KEY_generate_key ossl_ec_new Init_ossl_ec rb_uint2inum rb_attr EVP_MD_CTX_md EVP_MD_size EVP_DigestFinal_ex EVP_DigestInit_ex eDigestError EVP_MD_CTX_create EVP_MD_CTX_destroy ossl_digest_update EVP_DigestUpdate EVP_MD_type EVP_MD_block_size cDigest EVP_MD_CTX_copy EVP_get_digestbyname ossl_digest_new Init_ossl_digest rb_require rb_path2class rb_define_private_method Init_ossl_x509 Init_ossl_x509cert Init_ossl_x509crl Init_ossl_x509ext Init_ossl_x509name Init_ossl_x509req Init_ossl_x509revoked Init_ossl_x509store X509_get_default_cert_area X509_get_default_cert_dir X509_get_default_cert_file X509_get_default_cert_dir_env X509_get_default_cert_file_env X509_get_default_private_dir X509_STORE_CTX_free X509_STORE_CTX_set_time cX509Store DupX509CertPtr X509_STORE_CTX_init eX509StoreError X509_STORE_CTX_set_trust X509_STORE_CTX_set_purpose X509_STORE_CTX_set_flags X509_STORE_CTX_cleanup ossl_x509crl_new X509_STORE_CTX_get_current_cert ossl_x509_new X509_STORE_CTX_get_error_depth X509_STORE_CTX_get_error X509_verify_cert_error_string X509_STORE_CTX_set_error X509_STORE_CTX_get_chain sk_num sk_value dOSSL stderr fwrite __fprintf_chk cX509StoreContext rb_block_proc ossl_verify_cb_idx X509_STORE_CTX_set_ex_data X509_verify_cert X509_STORE_CTX_new GetX509CRLPtr X509_STORE_add_crl X509_STORE_add_cert X509_STORE_set_default_paths rb_check_safe_str X509_LOOKUP_file X509_STORE_add_lookup X509_LOOKUP_ctrl X509_LOOKUP_hash_dir X509_STORE_set_trust X509_STORE_set_purpose X509_STORE_set_flags ossl_verify_cb X509_STORE_new X509_STORE_free ossl_x509store_new DupX509StorePtr CRYPTO_add_lock ossl_x509stctx_new ossl_x509stctx_clear_ptr X509_REQ_add1_attr eX509ReqError X509_REQ_print i2d_X509_REQ eX509CertError PEM_write_bio_X509_REQ PEM_read_bio_X509_REQ d2i_X509_REQ_bio X509_REQ_new X509_REQ_free X509_REQ_get_attr_count X509_REQ_get_attr GetPKeyPtr X509_REQ_verify X509_REQ_sign X509_REQ_set_pubkey X509_REQ_get_pubkey ossl_pkey_new GetX509NamePtr X509_REQ_set_subject_name ossl_x509name_new X509_REQ_set_version ASN1_INTEGER_get cX509Req X509_REQ_dup ossl_x509req_new GetX509ReqPtr DupX509ReqPtr rb_attr_get OBJ_txt2nid OBJ_nid2ln cASN1Set rb_funcall3 cASN1Sequence cASN1GeneralizedTime cASN1UTCTime cASN1ObjectId cASN1Null cASN1BMPString cASN1UniversalString cASN1GeneralString cASN1ISO64String cASN1GraphicString cASN1IA5String cASN1VideotexString cASN1T61String cASN1PrintableString cASN1NumericString cASN1UTF8String cASN1OctetString cASN1BitString cASN1Enumerated cASN1Integer cASN1Boolean rb_ary_each rb_block_call rb_str_append ASN1_get_object ossl_asn1_info_size rb_cArray d2i_ASN1_OBJECT ASN1_OBJECT_free cASN1Data rb_yield d2i_ASN1_TIME d2i_ASN1_BOOLEAN d2i_ASN1_INTEGER ASN1_INTEGER_free d2i_ASN1_BIT_STRING ASN1_BIT_STRING_free d2i_ASN1_NULL ASN1_NULL_free d2i_ASN1_ENUMERATED ASN1_ENUMERATED_free rb_str_new4 rb_ary_entry sscanf rb_funcall2 ASN1_INTEGER_to_BN BN_free ASN1_object_size ASN1_put_object memcpy OBJ_obj2txt OBJ_create time_to_time_t asn1str_to_str num_to_asn1integer BN_to_ASN1_INTEGER ASN1_GENERALIZEDTIME_set CRYPTO_malloc ASN1_TYPE_set ASN1_BIT_STRING_new ASN1_BIT_STRING_set ASN1_STRING_new ASN1_STRING_set ASN1_STRING_free ASN1_NULL_new ossl_to_der ASN1_UTCTIME_set ossl_buf2str Init_ossl_asn1 rb_ary_store cASN1Primitive rb_mEnumerable cASN1Constructive rb_include_module HMAC_CTX_copy HMAC_Final HMAC_CTX_cleanup eHMACError string2hex CRYPTO_free HMAC_CTX_init HMAC_Update HMAC_Init cHMAC Init_ossl_hmac X509_CRL_add_ext eX509CRLError X509_CRL_print PEM_write_bio_X509_CRL i2d_X509_CRL_bio cX509Rev X509_REVOKED_free DupX509RevokedPtr X509_CRL_add0_revoked X509_CRL_sort PEM_read_bio_X509_CRL d2i_X509_CRL_bio X509_CRL_new X509_CRL_free X509_CRL_get_ext_count X509_CRL_get_ext X509_CRL_verify X509_CRL_sign ossl_x509revoked_new X509_time_adj X509_CRL_set_issuer_name X509_CRL_set_version cX509CRL X509_CRL_dup DupX509CRLPtr EVP_DigestInit EVP_VerifyFinal id_private_q EVP_PKEY_size EVP_SignFinal rb_eNotImpError ossl_dh_new ossl_dsa_new ossl_pkey_new_from_file rb_check_safe_obj fopen PEM_read_PrivateKey fclose __errno_location strerror DupPKeyPtr DupPrivPKeyPtr Init_ossl_pkey Init_ossl_dsa Init_ossl_dh NETSCAPE_SPKI_print eSPKIError i2d_NETSCAPE_SPKI NETSCAPE_SPKI_verify NETSCAPE_SPKI_sign NETSCAPE_SPKI_set_pubkey NETSCAPE_SPKI_get_pubkey NETSCAPE_SPKI_b64_encode strlen NETSCAPE_SPKI_b64_decode NETSCAPE_SPKI_free ERR_clear_error d2i_NETSCAPE_SPKI NETSCAPE_SPKI_new Init_ossl_ns_spki mNetscape cSPKI i2d_X509_NAME eX509NameError X509_NAME_entry_count X509_NAME_get_entry i2t_ASN1_OBJECT OBJ_ln2nid rb_ary_new3 rb_num2ulong X509_NAME_print_ex X509_NAME_oneline X509_NAME_add_entry_by_txt cX509Name rb_const_get rb_check_array_type d2i_X509_NAME X509_NAME_new X509_NAME_free X509_NAME_hash X509_NAME_cmp X509_NAME_hash_old X509_NAME_dup GetConfigPtr cConfig NCONF_new NCONF_load_bio NCONF_free eConfigError Init_ossl_config CONF_get1_default_config_file i2d_PKCS12 ePKCS12Error d2i_PKCS12_bio PKCS12_parse ossl_x509_sk2ary PKCS12_create cPKCS12 PKCS12_free PKCS12_new Init_ossl_pkcs12 i2d_PKCS7 ePKCS7Error PKCS7_decrypt ossl_protect_x509_ary2sk PKCS7_verify ERR_get_error ERR_reason_error_string PKCS7_dataInit BIO_write BIO_read PKCS7_dataFinal PKCS7_content_new d2i_PKCS7_RECIP_INFO i2d_PKCS7_RECIP_INFO ASN1_dup cPKCS7Recipient PKCS7_RECIP_INFO_free PKCS7_RECIP_INFO_new PKCS7_get_signer_info d2i_PKCS7_SIGNER_INFO i2d_PKCS7_SIGNER_INFO cPKCS7Signer PKCS7_SIGNER_INFO_free PKCS7_SIGNER_INFO_new PEM_read_bio_PKCS7 d2i_PKCS7_bio PKCS7_encrypt cPKCS7 PKCS7_free EVP_rc2_40_cbc PKCS7_sign SMIME_write_PKCS7 PKCS7_ctrl PKCS7_RECIP_INFO_set PKCS7_get_signed_attribute PKCS7_SIGNER_INFO_set PEM_write_bio_PKCS7 ossl_x509crl_sk2ary sk_pop PKCS7_add_crl PKCS7_add_certificate PKCS7_add_recipient_info PKCS7_add_signer OBJ_nid2obj PKCS7_add_signed_attribute PKCS7_set_cipher strcmp PKCS7_set_type rb_id2name PKCS7_dup PKCS7_new SMIME_read_PKCS7 Init_ossl_pkcs7 eDSAError i2d_DSAPrivateKey i2d_DSA_PUBKEY PEM_write_bio_DSAPrivateKey i2d_DSAPublicKey PEM_ASN1_write_bio DSA_print RAND_bytes DSA_generate_parameters DSA_generate_key DSA_free PEM_read_bio_DSAPrivateKey DSA_new d2i_DSAPublicKey PEM_ASN1_read_bio PEM_read_bio_DSA_PUBKEY d2i_DSAPrivateKey_bio d2i_DSA_PUBKEY_bio cDSA PKCS5_PBKDF2_HMAC_SHA1 ePKCS5 PKCS5_PBKDF2_HMAC Init_ossl_pkcs5 mPKCS5 i2d_X509_EXTENSION eX509ExtError X509_EXTENSION_get_object ASN1_OCTET_STRING_new X509_EXTENSION_set_data ASN1_OCTET_STRING_free d2i_X509_EXTENSION X509V3_EXT_nconf_nid X509V3_EXT_print ASN1_STRING_print X509_EXTENSION_get_critical X509_EXTENSION_set_critical X509_EXTENSION_set_object X509V3_set_nconf X509V3_set_ctx X509_EXTENSION_new X509_EXTENSION_dup GetX509ExtPtr cX509ExtFactory RAND_status rb_num2dbl RAND_add RAND_seed eRandomError RAND_egd_bytes RAND_egd RAND_pseudo_bytes RAND_write_file RAND_load_file Init_ossl_rand mRandom DH_size eDHError i2d_DHparams PEM_write_bio_DHparams DHparams_print DH_generate_parameters DH_generate_key DH_free PEM_read_bio_DHparams DH_new d2i_DHparams DHparams_dup DH_check BN_bin2bn cDH OSSL_DEFAULT_DH_512 OSSL_DEFAULT_DH_1024 ENGINE_get_cmd_defns ENGINE_ctrl_cmd_string eEngineError ENGINE_load_public_key ENGINE_load_private_key ENGINE_get_first ENGINE_free ENGINE_get_next ENGINE_cleanup ENGINE_load_openssl ENGINE_load_builtin_engines ENGINE_by_id ENGINE_init ENGINE_ctrl ENGINE_set_default ENGINE_get_digest ENGINE_get_cipher ENGINE_finish ENGINE_get_name ENGINE_get_id rb_str_cat2 ENGINE_new Init_ossl_engine cEngine X509_add_ext i2d_X509 PEM_read_bio_X509 d2i_X509_bio X509_new X509_get_ext_count X509_get_ext X509_check_private_key X509_verify X509_sign X509_set_pubkey X509_get_pubkey X509_set_issuer_name X509_get_issuer_name X509_set_subject_name X509_get_subject_name X509_get_serialNumber rb_inspect X509_set_version X509_print PEM_write_bio_X509 cX509Cert X509_dup ossl_x509_new_from_file PEM_read_X509 ossl_call_verify_cb_proc ERR_peek_last_error __vsnprintf_chk __snprintf_chk rb_exc_new ossl_get_errors CRYPTO_mem_ctrl ossl_x509_ary2sk0 PEM_def_callback X509_STORE_CTX_get_ex_data rb_ensure ossl_s_to_der rb_respond_to rb_exc_raise sk_push ossl_exc_new Init_openssl SSL_library_init OPENSSL_add_all_algorithms_noconf ERR_load_crypto_strings SSL_load_error_strings rb_define_module rb_eStandardError X509_STORE_CTX_get_ex_new_index Init_ossl_bn Init_ossl_ssl X509_REVOKED_add_ext eX509RevError X509_REVOKED_new X509_REVOKED_get_ext_count X509_REVOKED_get_ext d2i_X509_REVOKED i2d_X509_REVOKED BN_is_prime_fasttest BN_bn2dec BN_bn2hex BN_bn2mpi BN_num_bits BN_bn2bin BN_is_prime BN_pseudo_rand BN_rand BN_hex2bn BN_mpi2bn BN_dec2bn rb_cstr_to_inum BN_rshift BN_lshift BN_mask_bits BN_is_bit_set BN_clear_bit BN_set_bit rb_assoc_new BN_sqr BN_dup rb_String BN_mod_inverse BN_generate_prime BN_pseudo_rand_range BN_rand_range BN_ucmp BN_cmp BN_gcd BN_mod_exp BN_exp BN_mod_sqr BN_mod_mul BN_mod_sub BN_mod_add BN_div BN_mul BN_sub BN_add BN_CTX_new SSL_get_verify_result SSL_new rb_io_taint_check rb_io_check_closed rb_io_check_readable rb_io_check_writable fileno SSL_set_fd ossl_ssl_ex_ptr_idx SSL_set_ex_data ossl_ssl_ex_vcb_idx ossl_ssl_ex_client_cert_cb_idx ossl_ssl_ex_tmp_dh_callback_idx eSSLError SSL_set_session SSL_pending SSL_state_string ruby_verbose SSL_state_string_long SSL_CIPHER_get_name SSL_CIPHER_get_version SSL_CIPHER_get_bits SSL_get_current_cipher SSL_get_peer_cert_chain SSL_get_peer_certificate SSL_write SSL_get_error rb_io_wait_writable rb_io_wait_readable rb_sys_fail rb_str_modify SSL_read rb_eof_error rb_thread_wait_fd ID_callback_state rb_ivar_set rb_ivar_get SSL_accept SSL_connect SSL_CTX_flush_sessions SSL_CTX_ctrl SSL_get_ex_data SSL_get_ex_data_X509_STORE_CTX_idx SSL_CTX_get_ex_data ossl_ssl_ex_store_p SSL_CTX_free SSL_CTX_set_tmp_dh_callback SSL_CTX_set_ex_data SSL_CTX_set_cert_store SSL_CTX_use_certificate SSL_CTX_use_PrivateKey SSL_CTX_check_private_key SSL_CTX_add_client_CA SSL_CTX_set_verify SSL_CTX_set_timeout SSL_CTX_set_verify_depth rb_obj_freeze SSL_CTX_set_session_id_context SSL_CTX_load_verify_locations SSL_CTX_sess_set_remove_cb SSL_CTX_sess_set_new_cb SSL_CTX_sess_set_get_cb SSL_CTX_set_client_cert_cb cSSLContext rb_call_super SSL_ctrl SSL_get_certificate SSL_shutdown SSL_clear SSL_CTX_remove_session SSLv23_method SSL_CTX_new SSL_free ossl_ssl_method_tab SSL_CTX_set_ssl_version SSL_CTX_add_session SSL_CTX_set_cipher_list SSL_get_ex_new_index TLSv1_method TLSv1_server_method TLSv1_client_method SSLv2_method SSLv2_server_method SSLv2_client_method SSLv3_method SSLv3_server_method SSLv3_client_method SSLv23_server_method SSLv23_client_method BIO_new_mem_buf fdopen BIO_new_fp ossl_membio2str0 ossl_protect_obj2bio ossl_protect_membio2str libruby.so.1.8 libssl.so.10 libcrypto.so.10 libpthread.so.0 librt.so.1 libdl.so.2 libcrypt.so.1 libm.so.6 libc.so.6 _edata __bss_start _end GLIBC_2.4 GLIBC_2.14 GLIBC_2.3.4 GLIBC_2.2.5 OPENSSL_1.0.1_EC /opt/alt/openssl/lib64:/opt/alt/ruby18/lib64                                                                                                                                                                                                                                                                                                                                                                                                                                                             	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           y?     P   ii  	 ?        ?     ti	   ?     ui	   ?        ;?         ui	   ?        ?         Лw
   ?        +?         3   ?      t
   +?      0$            y     8$            py     @$            @$     `$                 p$            {     $                 $                 $                 $            .     $                 $                 $                 $                  $                 $                 $                 $                  $                 ($                 0$            %     8$            1     @$                 H$                 P$            
     X$                 `$                 h$                 $            1     $                 $                 $                 $                 Е$                 $                 $                  $                 $            (      $            -     0$            8     @$            E     P$            P     `$            ]     p$            l     $            {     $                 $                 $                 $                 Ж$                 $                 $                  $                 $                  $                 0$                 @$            	     P$                 `$            *      $            $     $            o      $            |     0$                 @$                 P$                 `$                 p$                 $                 $                 $                 $                 $        N          $        N          $                  p$                  $        Y          $        Y          ȕ$                  $                  ؕ$                  @$                  $        /          $        /          ($        R          Л$        R          H$                  ($                  $                  $                  $        e          @$        e          $        A          $        A          $        S          h$        S          Ȗ$                  H$                  ؖ$                  $                  $                  8$                  $                  ȟ$                  $                  x$                  $                  $                  ($                  $                  8$                  0$                  H$                  П$                  h$        G          $        G          $        O          ș$                   Й$                  ؙ$                  $                   $                   $                    $                   $        "           $        &           $        `          $                   $                  ($        [          0$        \          8$        A           P$        P           X$        Q           `$        a          h$        #          p$                  x$                  $        k           $        u           $        x           $        b          $        n          $                   $                   $                   $                  Ț$                   К$                   ؚ$                  $        ?          $                   $        B          $                   $                   $        8          $        U          $                    $                   ($                  0$                  8$        '          @$                  H$        0          P$                  X$        Q          `$        	          p$                  x$                   $        <          $        	          $        
          $                  $                  $        K          $        J          ț$        #          ؛$                  $                  $                  $        A          $        v           $                  $                  $                   $        
          8$                  H$                  P$        q          X$        %          `$        s          h$        v          p$        y          x$                  $        {          $                  $                  $                  $                  $        =          $                  $                  Ȝ$                  М$        ^          ؜$                  $                  $                  $                  $                   $        ,          $        4          $                  $        f           $                  ($                  0$        M          8$                  @$        1          H$                  P$                  X$        9          `$                  h$                  x$        ~          $        ]          $                  $        @          $        !          $        2          $                  $                   $        5          ȝ$        F          Н$                  ؝$                  $                  $        l          $                  $                   $                  $                  $                   $        "          ($        )          0$                  @$                  H$        9          P$        T          X$                  `$                  h$                  p$        T          x$                  $        d          $        f          $        m          $                  $        w          $                  $        k          $                  Ȟ$                  О$        -          ؞$                  $        L          $                  $                   $                  $                  $                  $                   $                  ($        6          0$                  8$                  @$        z          H$                  P$                  X$        i          `$        q          h$        W          p$                  $                  $                  $                  $                  $                  $                  $                  $        ;          ؟$                  $        &          $        H          $        o          $                  $                   ($        a           8$                   H$        k          X$                  h$                   x$                  $                  $        u          $                  $        /          $                    $                   ($                   0$                  8$                   @$        p          H$                   P$                   X$                   `$        	           h$                  p$        $          x$        
           $                   $                   $                   $                   $                   $                   $                   $                   $        C          Ƞ$                   Р$                   ؠ$                   $                   $                   $                   $                    $                   $                   $                   $                    $                    ($        !           0$        "           8$        #           @$                  H$        $           P$        %           X$        &           `$        '           h$        (           p$                  x$        )           $        *           $        +           $        ,           $        -           $                  $        .           $        /           $        P          $        0           ȡ$        1           С$        2           ء$        3           $        4           $        5           $        6           $        7            $        8           $        9           $        :           $        ;            $        <           ($        =           0$        >           8$        ?           @$        @           H$        B           P$        C           X$        D           `$        E           h$        F           p$        G           x$        H           $        I           $        J           $        K           $        L           $        M           $        N           $        O           $                  $        R           Ȣ$        S           Т$        T           آ$        U           $        V           $        W           $        X           $        Y            $        Z           $        [           $        \           $        ]            $        ^           ($        _           0$        `           8$        b           @$        c           H$        d           P$        e           X$        f           `$        g           h$        h           p$        i           x$        j           $        l           $        m           $        n           $        o           $        p           $        q           $        r           $        s           $        t           ȣ$        v           У$        w           أ$        x           $        y           $        z           $        {           $        |            $        }           $        ~           $                   $                    $                   ($                   0$                   8$                   @$                   H$                   P$                   X$                   `$                   h$                   p$                   x$                   $                   $                   $                   $                   $                   $                   $                   $                   $                   Ȥ$                   Ф$                   ؤ$        |          $                   $                  $                   $                    $                   $                  $                   $                    $                   ($                   0$                   8$                   @$                   H$                   P$                   X$                   `$                   h$                   p$                   x$                   $                   $                   $                  $                   $                   $                   $        }          $                   $                   ȥ$                  Х$        _          إ$                   $                   $                  $                  $                    $                   $                   $                   $                    $                   ($                  0$                   8$                   @$                   H$                   P$                   X$                   `$                   h$                   p$                   x$                   $                   $                  $                   $                   $                   $                   $                   $                   $                   Ȧ$                   Ц$        (          ئ$                   $                   $                   $                   $                    $                   $                   $                   $                   $                   ($                   0$                   8$                   @$                   H$                   P$                   X$                   `$                   h$                   p$                   x$                   $                   $                   $                   $                   $                   $                   $                   $                   $                   ȧ$        X          Ч$        w          ا$                   $                   $                   $                   $                    $                   $                   $                   $                    $        7          ($                  0$                   8$                   @$                   H$                   P$                   X$                  `$                  h$                  p$                  x$                  $                  $                  $                  $                  $                  $                  $                  $                  $                  Ȩ$                  Ш$                  ب$                  $                  $                  $                  $                   $                  $                  $        Z          $                   $                  ($                  0$                  8$        I          @$                  H$                  P$                  X$                   `$        !          h$        "          p$        #          x$                  $        $          $        %          $        &          $        '          $        (          $                   $        )          $        *          $        +          ȩ$        ,          Щ$        -          ة$        .          $        /          $        0          $        1          $        2           $        3          $        4          $        5          $        6           $        7          ($        8          0$        9          8$        :          @$        ;          H$        <          P$        =          X$        >          `$        ?          h$        @          p$        A          x$        B          $        C          $        D          $        E          $        F          $        x          $        G          $        H          $        I          $        J          Ȫ$        K          Ъ$        L          ت$        M          $                  $        N          $        O          $        P           $        Q          $        R          $        S          $        T           $        U          ($        V          0$        W          8$        X          @$        Y          H$                  P$        Z          X$        [          `$        \          h$        ]          p$        ^          x$        _          $        `          $        a          $        b          $        c          $                  $        d          $        e          $        f          $        g          ȫ$        h          Ы$                  ث$        i          $        j          $        k          $        l          $        m           $        n          $        o          $        p          $        q           $        r          ($        s          0$        t          8$        u          @$        w          H$        x          P$                  X$        z          `$                  h$        |          p$        }          x$        ~          $                  $                  $                  $                  $                  $                  $                  $                  $                  Ȭ$                  Ь$                  ج$                  $                  $                  $                  $                   $                  $                  $                  $                   $                  ($                  0$                  8$                  @$                  H$                  P$                  X$                  `$                  h$                  p$                  x$        >          $                  $                  $                  $                  $                  $                  $                  $                  $                  ȭ$                  Э$                  ح$                  $                  $                  $                  $                   $                  $                  $                  $                   $                  ($                  0$                  8$        D          @$                  H$                  P$                  X$                  `$                  h$                  p$                  x$                  $                  $                  $                  $                  $                  $                  $                  $                  $                  Ȯ$                  Ю$                  خ$                  $                  $                  $                  $                   $                  $                  $                  $                   $                  ($                  0$                  8$        E          @$                  H$                  P$                  X$                  `$                  h$                  p$                  x$                  $                  $                  $                  $                  $                  $                  $                  $                  $                  ȯ$                  Я$                  د$                  $                  $        ~          $                  $                   $                  $                  $                  $                   $                  ($                  0$        {          8$                  @$                  H$                  P$        u          X$                  `$                  h$                  p$                  x$        c          $                  $        r          $                  $                  $                  $                  $                  $                  $                  Ȱ$        	          а$        
          ذ$                  $                  $                  $                  $                   $                  $                  $                  $                   $                  ($                  0$                  8$                  @$                  H$                  P$                  X$                  `$                   h$        !          p$        "          x$        #          $        $          $        :          $        %          $        &          $        '          $        (          $        )          $        *          $        y          ȱ$        +          б$        ,          ر$        -          $        .          $        0          $        1          $                   $        2          $                  $        3          $        4           $        5          ($        6          0$        7          8$        8          @$        :          H$        ;          P$        <          X$        =          `$        >          h$                  p$        ?          x$        @          $        A          $        B          $        C          $        D          $        E          $        F          $        G          $        H          $        I          Ȳ$        J          в$        K          ز$        "          $        L          $        M          $        N          $        O           $        P          $        Q          $                  $                   $        R          ($        S          0$        U          8$        V          @$        W          H$        X          P$        Y          X$        Z          `$        [          h$        \          p$        ]          x$        ^          $        _          $        `          $        a          $        b          $        c          $        e          $        g          $        h          $        i          ȳ$        j          г$        l          س$        m          $        n          $        o          $        p          $        q           $        r          $        s          $        t          $        u           $        v          ($        w          0$        x          8$        y          @$        z          H$        {          P$        |          X$        }          `$        ~          h$                  p$                  x$                  $                  $        g          $                  $                  $                  $                  $                  $                  $                  ȴ$                  д$                  ش$                  $                  $                  $                  $                   $                  $                  $                  $                   $                  ($                  0$                  8$                  @$                  H$                  P$                  X$                  `$                  h$                  p$                  x$                  $                  $                  $                  $                  $                  $                  $                  $                  $                  ȵ$                  е$                  ص$                  $                  $                  $                  $                   $                  $                  $                  $                   $                  ($                  0$                  8$                  @$                  H$                  P$                  X$                  `$                  h$        d          p$                  x$                  $                  $                  $                  $                  $                  $                  $                  $                  $                  ȶ$                  ж$                  ض$                  $                  $        *          $                  $                   $                  $                  $                  $                   $                  ($                  0$                  8$                  @$                  H$                  P$                  X$                  `$                  h$                  p$                  x$                  $                  $                  $                  $                  $                  $                  $                  $                  $                  ȷ$        ;          з$                  ط$                  $                  $                  $                  $                   $                  $                  $                  $                   $                  ($                  0$        .          8$                  @$                  H$                  P$                  X$                  `$                  h$                  p$                  x$                  $                  $                  $                  $                  $                  $                  $                   $                  $                  ȸ$                  HH# HtH     5# %#  h    h   h   h   h   h   h   h   qh   ah	   Qh
   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h    h!   h"   h#   h$   h%   h&   h'   qh(   ah)   Qh*   Ah+   1h,   !h-   h.   h/   h0   h1   h2   h3   h4   h5   h6   h7   qh8   ah9   Qh:   Ah;   1h<   !h=   h>   h?   h@   hA   hB   hC   hD   hE   hF   hG   qhH   ahI   QhJ   AhK   1hL   !hM   hN   hO   hP   hQ   hR   hS   hT   hU   hV   hW   qhX   ahY   QhZ   Ah[   1h\   !h]   h^   h_   h`   ha   hb   hc   hd   he   hf   hg   qhh   ahi   Qhj   Ahk   1hl   !hm   hn   ho   hp   hq   hr   hs   ht   hu   hv   hw   qhx   ahy   Qhz   Ah{   1h|   !h}   h~   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h   h   h   h   h   h   h   h   qh   ah   Qh   Ah   1h   !h   h   h   h   h  h  h  h  h  h  h  qh  ah	  Qh
  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h   h!  h"  h#  h$  h%  h&  h'  qh(  ah)  Qh*  Ah+  1h,  !h-  h.  h/  h0  h1  h2  h3  h4  h5  h6  h7  qh8  ah9  Qh:  Ah;  1h<  !h=  h>  h?  h@  hA  hB  hC  hD  hE  hF  hG  qhH  ahI  QhJ  AhK  1hL  !hM  hN  hO  hP  hQ  hR  hS  hT  hU  hV  hW  qhX  ahY  QhZ  Ah[  1h\  !h]  h^  h_  h`  ha  hb  hc  hd  he  hf  hg  qhh  ahi  Qhj  Ahk  1hl  !hm  hn  ho  hp  hq  hr  hs  ht  hu  hv  hw  qhx  ahy  Qhz  Ah{  1h|  !h}  h~  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h   h  h  h  h  h  h  h  qh  ah	  Qh
  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h   h!  h"  h#  h$  h%  h&  h'  qh(  ah)  Qh*  Ah+  1h,  !h-  h.  h/  h0  h1  h2  h3  h4  h5  h6  h7  qh8  ah9  Qh:  Ah;  1h<  !h=  h>  h?  h@  hA  hB  hC  hD  hE  hF  hG  qhH  ahI  QhJ  AhK  1hL  !hM  hN  hO  hP  hQ  hR  hS  hT  hU  hV  hW  qhX  ahY  QhZ  Ah[  1h\  !h]  h^  h_  h`  ha  hb  hc  hd  he  hf  hg  qhh  ahi  Qhj  Ahk  1hl  !hm  hn  ho  hp  hq  hr  hs  ht  hu  hv  hw  qhx  ahy  Qhz  Ah{  1h|  !h}  h~  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h  h  h  h  h  h  h  h  qh  ah  Qh  Ah  1h  !h  h  h  h   h  h  h  h  h  h  h  qh  ah	  Qh
  Ah  1h  !h  h  h  h  h  h  h  h  h  h  %}X# D  %uX# D  %mX# D  %eX# D  %]X# D  %UX# D  %MX# D  %EX# D  %=X# D  %5X# D  %-X# D  %%X# D  %X# D  %X# D  %X# D  %X# D  %W# D  %W# D  %W# D  %W# D  %W# D  %W# D  %W# D  %W# D  %W# D  %W# D  %W# D  %W# D  %W# D  %W# D  %W# D  %W# D  %}W# D  %uW# D  %mW# D  %eW# D  %]W# D  %UW# D  %MW# D  %EW# D  %=W# D  %5W# D  %-W# D  %%W# D  %W# D  %W# D  %W# D  %W# D  %V# D  %V# D  %V# D  %V# D  %V# D  %V# D  %V# D  %V# D  %V# D  %V# D  %V# D  %V# D  %V# D  %V# D  %V# D  %V# D  %}V# D  %uV# D  %mV# D  %eV# D  %]V# D  %UV# D  %MV# D  %EV# D  %=V# D  %5V# D  %-V# D  %%V# D  %V# D  %V# D  %V# D  %V# D  %U# D  %U# D  %U# D  %U# D  %U# D  %U# D  %U# D  %U# D  %U# D  %U# D  %U# D  %U# D  %U# D  %U# D  %U# D  %U# D  %}U# D  %uU# D  %mU# D  %eU# D  %]U# D  %UU# D  %MU# D  %EU# D  %=U# D  %5U# D  %-U# D  %%U# D  %U# D  %U# D  %U# D  %U# D  %T# D  %T# D  %T# D  %T# D  %T# D  %T# D  %T# D  %T# D  %T# D  %T# D  %T# D  %T# D  %T# D  %T# D  %T# D  %T# D  %}T# D  %uT# D  %mT# D  %eT# D  %]T# D  %UT# D  %MT# D  %ET# D  %=T# D  %5T# D  %-T# D  %%T# D  %T# D  %T# D  %T# D  %T# D  %S# D  %S# D  %S# D  %S# D  %S# D  %S# D  %S# D  %S# D  %S# D  %S# D  %S# D  %S# D  %S# D  %S# D  %S# D  %S# D  %}S# D  %uS# D  %mS# D  %eS# D  %]S# D  %US# D  %MS# D  %ES# D  %=S# D  %5S# D  %-S# D  %%S# D  %S# D  %S# D  %S# D  %S# D  %R# D  %R# D  %R# D  %R# D  %R# D  %R# D  %R# D  %R# D  %R# D  %R# D  %R# D  %R# D  %R# D  %R# D  %R# D  %R# D  %}R# D  %uR# D  %mR# D  %eR# D  %]R# D  %UR# D  %MR# D  %ER# D  %=R# D  %5R# D  %-R# D  %%R# D  %R# D  %R# D  %R# D  %R# D  %Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %}Q# D  %uQ# D  %mQ# D  %eQ# D  %]Q# D  %UQ# D  %MQ# D  %EQ# D  %=Q# D  %5Q# D  %-Q# D  %%Q# D  %Q# D  %Q# D  %Q# D  %Q# D  %P# D  %P# D  %P# D  %P# D  %P# D  %P# D  %P# D  %P# D  %P# D  %P# D  %P# D  %P# D  %P# D  %P# D  %P# D  %P# D  %}P# D  %uP# D  %mP# D  %eP# D  %]P# D  %UP# D  %MP# D  %EP# D  %=P# D  %5P# D  %-P# D  %%P# D  %P# D  %P# D  %P# D  %P# D  %O# D  %O# D  %O# D  %O# D  %O# D  %O# D  %O# D  %O# D  %O# D  %O# D  %O# D  %O# D  %O# D  %O# D  %O# D  %O# D  %}O# D  %uO# D  %mO# D  %eO# D  %]O# D  %UO# D  %MO# D  %EO# D  %=O# D  %5O# D  %-O# D  %%O# D  %O# D  %O# D  %O# D  %O# D  %N# D  %N# D  %N# D  %N# D  %N# D  %N# D  %N# D  %N# D  %N# D  %N# D  %N# D  %N# D  %N# D  %N# D  %N# D  %N# D  %}N# D  %uN# D  %mN# D  %eN# D  %]N# D  %UN# D  %MN# D  %EN# D  %=N# D  %5N# D  %-N# D  %%N# D  %N# D  %N# D  %N# D  %N# D  %M# D  %M# D  %M# D  %M# D  %M# D  %M# D  %M# D  %M# D  %M# D  %M# D  %M# D  %M# D  %M# D  %M# D  %M# D  %M# D  %}M# D  %uM# D  %mM# D  %eM# D  %]M# D  %UM# D  %MM# D  %EM# D  %=M# D  %5M# D  %-M# D  %%M# D  %M# D  %M# D  %M# D  %M# D  %L# D  %L# D  %L# D  %L# D  %L# D  %L# D  %L# D  %L# D  %L# D  %L# D  %L# D  %L# D  %L# D  %L# D  %L# D  %L# D  %}L# D  %uL# D  %mL# D  %eL# D  %]L# D  %UL# D  %ML# D  %EL# D  %=L# D  %5L# D  %-L# D  %%L# D  %L# D  %L# D  %L# D  %L# D  %K# D  %K# D  %K# D  %K# D  %K# D  %K# D  %K# D  %K# D  %K# D  %K# D  %K# D  %K# D  %K# D  %K# D  %K# D  %K# D  %}K# D  %uK# D  %mK# D  %eK# D  %]K# D  %UK# D  %MK# D  %EK# D  %=K# D  %5K# D  %-K# D  %%K# D  %K# D  %K# D  %K# D  %K# D  %J# D  %J# D  %J# D  %J# D  %J# D  %J# D  %J# D  %J# D  %J# D  %J# D  %J# D  %J# D  %J# D  %J# D  %J# D  %J# D  %}J# D  %uJ# D  %mJ# D  %eJ# D  %]J# D  %UJ# D  %MJ# D  %EJ# D  %=J# D  %5J# D  %-J# D  %%J# D  %J# D  %J# D  %J# D  %J# D  %I# D  %I# D  %I# D  %I# D  %I# D  %I# D  %I# D  %I# D  %I# D  %I# D  %I# D  %I# D  %I# D  %I# D  %I# D  %I# D  %}I# D  %uI# D  %mI# D  %eI# D  %]I# D  %UI# D  %MI# D  %EI# D  %=I# D  %5I# D  %-I# D  %%I# D  %I# D  %I# D  %I# D  %I# D  %H# D  %H# D  %H# D  %H# D  %H# D  %H# D  %H# D  %H# D  %H# D  %H# D  %H# D  %H# D  %H# D  %H# D  %H# D  %H# D  %}H# D  %uH# D  %mH# D  %eH# D  %]H# D  %UH# D  %MH# D  %EH# D  %=H# D  %5H# D  %-H# D  %%H# D  %H# D  %H# D  %H# D  %H# D  %G# D  %G# D  %G# D  %G# D  %G# D  %G# D  %G# D  %G# D  %G# D  %G# D  %G# D  %G# D  %G# D  %G# D  %G# D  %G# D  %}G# D  %uG# D  %mG# D  %eG# D  %]G# D  %UG# D  %MG# D  %EG# D  %=G# D  %5G# D  %-G# D  %%G# D  %G# D  %G# D  %G# D  %G# D  %F# D  %F# D  %F# D  %F# D  %F# D  %F# D  %F# D  %F# D  %F# D  %F# D  %F# D  %F# D  %F# D  %F# D  %F# D  %F# D  %}F# D  %uF# D  %mF# D  %eF# D  %]F# D  %UF# D  %MF# D  %EF# D  %=F# D  %5F# D  %-F# D  %%F# D  %F# D  %F# D  %F# D  %F# D  %E# D  %E# D  %E# D  %E# D  %E# D  %E# D  %E# D  %E# D  %E# D  %E# D  %E# D  %E# D  %E# D  %E# D  %E# D  %E# D  %}E# D  %uE# D  %mE# D  %eE# D  %]E# D  %UE# D  %ME# D  %EE# D  %=E# D  %5E# D  %-E# D  %%E# D  %E# D  %E# D  %E# D  %E# D  %D# D  %D# D  %D# D  %D# D  %D# D  %D# D  %D# D  %D# D  %D# D  %D# D  %D# D  %D# D  %D# D  %D# D  %D# D  %D# D  %}D# D  %uD# D  %mD# D  %eD# D  %]D# D  %UD# D  %MD# D  %ED# D  %=D# D  %5D# D  %-D# D  %%D# D  %D# D  %D# D  %D# D  %D# D  %C# D  %C# D  %C# D  %C# D  %C# D  %C# D  %C# D  %C# D  %C# D  %C# D  %C# D  %C# D  %C# D  %C# D  %C# D  %C# D  %}C# D  %uC# D  %mC# D  %eC# D  %]C# D  %UC# D  %MC# D  %EC# D  %=C# D  %5C# D  %-C# D  %%C# D  %C# D  %C# D  %C# D  %C# D  %B# D  %B# D  %B# D  %B# D  %B# D  %B# D  %B# D  %B# D  %B# D  %B# D  %B# D  %B# D  %B# D  %B# D  %B# D  %B# D  %}B# D  %uB# D  %mB# D  %eB# D  %]B# D  %UB# D  %MB# D  %EB# D  %=B# D  %5B# D  %-B# D  %%B# D  %B# D  %B# D  %B# D  %B# D  %A# D  %A# D  %A# D  %A# D  %A# D  %A# D  %A# D  %A# D  %A# D  %A# D  %A# D  %A# D  %A# D  %A# D  %A# D  %A# D  %}A# D  %uA# D  %mA# D  %eA# D  %]A# D  %UA# D  %MA# D  %EA# D  %=A# D  %5A# D  %-A# D  %%A# D  %A# D  %A# D  %A# D  %A# D  %@# D  %@# D  %@# D  %@# D  %@# D  %@# D  %@# D  %@# D  %@# D  %@# D  %@# D  %@# D  %@# D  %@# D  %@# D  %@# D  %}@# D  %u@# D  %m@# D  %e@# D  %]@# D  %U@# D  %M@# D  %E@# D  %=@# D  %5@# D  %-@# D  %%@# D  %@# D  %@# D  %@# D  %@# D  %?# D  %?# D  %?# D  %?# D  %?# D  %?# D  %?# D  H=A# HA# H9tH&# Ht	        H=A# H5A# H)HHH?HHtHU&# HtfD      =EA#  u+UH=B!#  HtH=# YdA# ]     w    AT"   USHKH[ Hp  ;x  HHC Hx iH=Y ILHHHC Hx(?H=wZ ILHHHC Hx0H=6a IvLHHHC Hx8H=J ILLHHnHC Hx@H=V= I"LHHDHC HxHH=.= ILHHHC HxPmH=	= ILHHHC HxXCH=< HHHHH[]A\H'$# H5< H81&H$# H5< H81^ff.      ATUHSH"   HtHm H   HtiH9Le HI|$XHt3Ht/HH[]A\fHD$Ht$ID$XHE HxXHuH  # 1H81@ HE HxX{HE H@X    HH[]A\H,## H5; H81+ff.     ATUHSH"   HHm H   HtiHYLe HI|$PHtSHt/HH[]A\fHD$Ht$ID$PHE HxPHuH@# 1H81@ HE HxPHE H@P    HH[]A\HL"# H5: H81Kff.     ATUHSH"   HHm H   HtiHyLe HI|$HHtsHt/HH[]A\fHD$&Ht$ID$HHE HxHHuH`# 1H81@ HE HxHHE H@H    HH[]A\Hl!# H59 H81kff.     ATUHSH"   HHm H   HtiHLe HI|$@HtHt/HH[]A\fHD$FHt$ID$@HE Hx@HuH# 1H81@ HE Hx@HE H@@    HH[]A\H # H58 H81ff.     ATUHSH"   HHm H   HtiHLe HI|$8HtHt/HH[]A\fHD$fHt$ID$8HE Hx8HuH# 1H81<@ HE Hx8HE H@8    HH[]A\H# H58 H81ff.     ATUHSH"   HHm H   HtiHLe HI|$0HtHt/HH[]A\fHD$Ht$ID$0HE Hx0HuH# 1H81\@ HE Hx0HE H@0    HH[]A\H# H5%7 H81ff.     ATUHSH"   H4Hm H   HtiHLe HI|$(HtHt/HH[]A\fHD$Ht$ID$(HE Hx(HuH# 1H81|@ HE Hx(;HE H@(    HH[]A\H# H5E6 H81ff.     ATUHSH"   HTHm H   HtiHLe HI|$ HtHt/HH[]A\fHD$Ht$ID$ HE Hx HuH # 1H81@ HE Hx [HE H@     HH[]A\H# H5e5 H81ff.     AUI"   ATIUHSH(dH%(   HD$1]I\$ H8  ;  HC Hx8    Hx@    Ld$1LD$LLH%5 tH|$@   LbH{ Y1pHcHK AIHD$IT$HpHx   HcLLHL$dH3%(      H([]A\A]fD  {z@ H5V4 LH"HP# H5>4 H81H# H53 H81Hp# H53 H81oH# 1H81    AUI"   ATIUHSH(dH%(   HD$1I\$ H8  ;  HC Hx8    Hx@    Ld$1LD$LLHu3 EtH|$@   \LH{ 1pHc<HK AIHD$IT$HpHx   HcLLHL$dH3%(      H([]A\A]fD  z@ H52 LQH"H# H52 H81?H# H5J2 H81'H# H52 H81HS# 1H81    AUI"   ATUHSHH(dH%(   HD$1Hm H   } X   Ld$1LD$LLH1 tH|$@twL H} 1pHcHM AIHD$IT$HpHxyxkHcLzLHL$dH3%(   uHH([]A\A]@ CH# H50 H81Hp# H50 H81oH# 1H81    AUI"   ATUHSHH(dH%(   HD$1Hm H   }    Ld$1LD$LLH0 _tH|$@twzLH} 1pHcZHM AIHD$IT$HpHxixkHcL*LHL$dH3%(   uHH([]A\A]@ H8# H5/ H81臿H # H5y/ H81:H# 1H81W    AT"   USHHdH%(   HD$1gHk H   }    H} H8 tH@ tL%# fD  L%9# 1AHcH~T1-HH} HH@H$Aԅx4H4$H+s9s|RHcHHHT$dH3%(   ukH[]A\H# 1H81mH# H5x. H81UH/ &  H5. H=. vH# H5(. H81f     AUI"   ATAHUSHH(dH%(   HD$1H[ H#  ;x   Hl$DHL$LIH. 1H|$H   E1E1H|HHt=Hs H~8 tIH~@ tBHL# 1LATE1HZYu+HH# 1H81$@ HtHHT$dH3%(   uKH([]A\A]ÐE1H|$IPHI@Hb# H5, H81豼|HE# H5, H81D@ U"   SHHH[ Htq;uMHWHHt%Hs H1AHtH[]Hs# 1H81H# H5", H81H# H5+ H81    AVI"   AUAHATUSHH dH%(   HD$1Lc Mh  Hl$1HL$LIH+ D  H|$HT$@td  HtH׃  H|$HcI1҅   H1DHHu^H]# 1H81E1H   HHD$H*# L1HIHH   LVH   L  HH\$dH3%(   w  H []A\A]A^f.     HfD  HY# +@ HH|$IH H|$HcfD  11Ҿ   L/111LHH711Ҿ   L111LHH11Ҿ   Lٻ1L/HH11Ҿ   L費1LHHH11Ҿ   L苻1LLHHH# H5) H815H# H5') H81Hff.     AUIATIU1SHHt?L   HHt=H
# 1HLI1H5( HH%HH[]A\A]    H踺HH[]A\A]f.     U"   SHHHk H   }    H} "Hu:HttHt_Hty   H{Ht&HHtH[] H# H8HuHH"# 1H81ƷfD  H# H8@ HY# H8@ HQ# H8@ H# H8uH# H5s' H81H# H5t' H81QU"   HSHyH] HtQ;u]HC Hx8 tHx@ tH   []fD  H56' HH1HtH[]Hx# H5& H81wH`# H5& H81诶ff.     @ PXH5& HH,# H812fS"   HHC HtH@ HxXHt[f   [@ S"   HnHC HtH@ HxPHt[f   [d@ S"   H.HC HtH@ HxHHt[bf   [$@ S"   HHC HtH@ Hx@Ht["f   [@ S"   HHC HtH@ Hx8Ht[f   [@ S"   HnHC HtH@ Hx0Ht[f   [d@ S"   H.HC HtH@ Hx(Ht[bf   [$@ S"   HHC HtH@ Hx Ht["f   [@ ATIH$ U  SH dH%(   HD$1HL$LD$vH|$Ht@tm萺HcH|$@tm}v1҅tH	# 1HHHtMHLHt=HL$dH3%(   uHH []A\@ H|$Hc@u @ H`H# 1H81荳X     S"   HHC Ht8u   [H
# H5D# H81H
# H5E# H81"fSHtNH?uzH# H!# H1H8|1H5 # HHXHt3H[fD  3HtHH# H8H    H# 1H81荲H~	# H5# H81uD  SH<# H5# H# HH;H# H;H5aM HH# HxH9# HHH5" H裵H;HH5" (H;1H\H5" H;1HtH5" H;1HH5}" H;HH5j" H;H[" H5[" H;HE" H5L" H;1HH59" H;1HH5)L iH;HzH5" NH;HH5" 3H;HDH5! H;HyH5! H;1HH5< H;   HfH5*$ H;1H~H5F= H;   HSH5jT H;1HH5C H;   H@H5i. dH;1HH5M- LH;   H-H5@! 1H;1H%H5
  H;   HH5  H;1HH5 H;   HH5  H;1H?H5 H;   HH5  H;1HH5} H;   HH5q  eH;1HH5_  MH;   H5R  yH;   H5L  eH;   H5G  QH;[	   H5=  <f.     fUH   SH1HxHHH     HHHǀ       1H)   HHH  HHHH[]ff.     @ UHSHH;HH= HH1H=> HHHH[   1]     AUATUHH SH(dH%(   HD$1H\$Ll$HMHKHD$HXL`   H"   Hm H   HH|$D$tvLHct$H|$߯HD$HpHT$ALH賱   H|$Hct$H;w}qVHD$HL$dH3%(   uRH([]A\A]fD  Hc1&HD$HX# H5s H81觬H" H5D H81?ZHS  b  H5R H=Y 諻H# 1H81X     AWAVAUE1ATUHH: SH   dH%(   H$   1H\$Ld$HHD$0MHP1LL$0%YH^諼H|$/  H|$ A   Ht@   AH|$(H   8HD$"   HL} M   HD$H\$0LL@LpL$ۺSELLHHl$HULD$Ht$X1ZA1IHLo   @   H)   H   H$   dH3%(   uyHĘ   []A\A]A^A_f+H|$(AH4HD$f.     LhHD$Hxu9LhH,# H5G H81{FH" 1H81cH|" H5% H81ff.     SfH5      HHH[f.     SHHHH1[PX1HH" H81ש    S"   HH{ HtE1111AuH[H0# H5K H81f.     HtSHH[%D  ff.     @ ATIHUSHt:腯L"   VI|$ Ht*uH[]A\     ;H{ # H5 H81ʨf.     PXH5y HHL # H81袨fS"   HH{ HtH[Hcf.     S"   HH{ Ht谷H蘬[Hc_jf.     USHHH|$Ht$ĸH߾"   7H[ HtFHD$HHh譭HH9|KHD$111AHL@u$HD$H[]HA" H5\ H81萧H" H5 H81s S"   HH{ HtHh[Hcozf.     ATIHUSHt:uL"   FI|$ Ht*uH[]A\     +Hk" H5 H81躦f.     USHHH|$Ht$TH߾"   H[ HtGHD$HHhHH9|LHD$E111AHHH舶u$HD$H[]H" H5 H81*H3" H5' H81fS"   H.H{ HtPHx[Hȱ U"   SHHdH%(   HD$1Hk HtWH1Hc޵HT$HHpH
tiHct$H;s?H賶HHL$dH3%(   uH[]H" H5 H81!H {  H5 H=2 =H" 1H81f.     AWAVAUAATUSHHC H   dH%(   HD$x1Ld$Hl$MH͹5  HHH=n HHH1nH&"   HLs M5  H|$   foH Hl$ )D$ HD$HHLxHL$臩LH${j EHA   HLd$8ATHL$Ht$4XIZL11EL   HH\$xdH3%(      HĈ   []A\A]A^A_ LPHD$HPH~AH@Hl$ o)L$ <f.     "   HLs Mt3E11dHl$ Hpf   H)D$ aH" H5 H81H" 1H81ff.     1D     fATUSHHH|$Ht$"   HIHk Ht6LHtFE111AHH褲u$HH[]A\H" H5 H81;FH" LH5} H81ff.     AUATUHSHH7H9tQ"   H%Lc MtIL-" HIu IHt\"   HHu HtL&u&HH[]A\A]H," H5G H81{H" 1H81hI} HH$HH5 HH8" H816fD  USHHH-" Hu Ht!H߾"   AH{ Ht=H[]]H} tHH該HH5O HH" H81軠HT" H5o H81裠 Hu" ATIUSH8"   HHHk Ht-H襲E111ALH荰u H[]A\H" H5 H81(HA" 1H81D  Hm" SH5I HH" H8;H" H" H5) HHHH" H;H5H߫H;   HH5 ԾH;1HHH5 LH;   HH5" 衾H;1HH5 艾H;HjH54 nH;H?H5( SH;HH5z 8H;HH5/ H;   HH5S H;1HH5> H;1HH5 ҽH;   HH56 跽H;   H8H5 蜽H;1HH5 脽H;   HH5 iH;1HH5 QH;1HeH5 9H;[   HH5 f.      U"   SHHdH%(   HD$1Hk HtoH蓷HH   HHtd1Hs   H膟H$HxH0趭HHHHT$dH3%(   uH[]H" H5C H81H謩H=# H5j 1H=# H5I 1fU"   SHHdH%(   HD$1Hk HtoH裶HH   HHtd1Hs   H薞H$HxH0ƬHHHHT$dH3%(   uH[]H" H5S H81)H輨H=# H5z 1H=# H5Y 1fATUH"   SHH[ Ht[L%" HI4$<Ht["   HHu Ht-19u SD;VDuHHH{HH[]A\H" H5 H81\I<$HHHH5 HH," H81*f.     ATUSH     H" HHHH0腣Hu8H111HIgHHtOLgHk H[]A\ H"   H} HtHHuH=v# H5 1耚11Ҿ   L菜H=" 1LH54" 7LHHuH" H5 H81/H=# H5a 1f.     HE" 11錷ff.     SH   H$ H   H$ H   "   dH%(   H$(  1HH{ HtHHD$Ht$HD$?~b='  FH|$HcשH$(  dH3%(   u!H (  [H" H5m H81CH=# H5 1)H=
# H5 1@ PXH5' HH" H81fS"   HHdH%(   HD$1D$    H{ Ht,Ht$课t$HHT$dH3%(   uH[xS S"   HH{ Htp[HBfATUH"   SHxLc MtnH" HH0譠Hu(HtgHLաH[]A\yf     H= t1HH1HƨuHHHZ" H5 H81詗H" H50 H81AS"   H辿H{ HtLPHt;HH=`! HHٺ   [HH	" H81W       [@ ATUH"   SHHLc MtnH" HH0}Hu(HtgHLEH[]A\9f     H= D1HH1ūHƨuHƥHH*" H5
 H81yH" H5  H81H" SH5 HH" H8苤H\" HE" H5
 HHHhH;H5H# 2H;   HH5 'H;   HH54 H;1H0H51 H;   HH5
 ٴH;1HH57 H;   H"H5W
 覴H;1HjH5.0 莴H;1HRH5. vH;1HJH5
 ^H;1[HAH5 ED  Hx飵 Hx H     AUATUHH	 S1H(dH%(   HD$1HLL$LD$ĩH|$JH|$IHt觾H<$ܦH"   I蜼H} HtoLHcLŹH56" LGb1HH=0 H11H\$dH3%(   u4H([]A\A]D     H}" H5 H81̓藯    AWAVAUATU1SHH H8dH%(   HD$(1HL$HHD$(P1LL$(LD$ 袨XZH|$H|$I	H|$ IHt@   蜙HH|$H   蕥IǾ"   HULc M   CILLMHL|H5" LtlHT$(dH3%(   HuTH8[]A\A]A^A_D  H|$HHotHIfH!" H5r H81p;H" 1H81X     AW"   AVAUATUSHHxdH%(   HD$h1aHC HD$H  :H|$HD$8ˠD$  HD$`1HD$HD$XHD$ HD$PHD$(HD$LHD$0 9l$  H|$臥HHtLD$HL$ HHD$`    HT$(Ht$0HD$X    HD$P    舣AąxH;詭IHZ  xHQ" 1LIH" H8躮LH迺IcGLH謺Hc|$L2LH藺H|$P   HtsHLxH|$X   HtTHLYH|$`   Ht5HL:ŧHIAŅ~*E1DHAaH9LHE9uLLH|$8L޹9l$HT$hdH3%(   HD$8u'Hx[]A\A]A^A_H" H5 H81ëH|" 1H81AWAVIAUMATIHUHSH8Ht$H\$xL$dH%(   HD$(1D$$       D$D$    HtLA  ǕD$H  I  H-" Lt$$LLHE|$$q  HǨ  yH1IH4$LHt$$  HǨ  AH1ǻHt$pLHH$ӲL$$  HǨ  H1荻"   LIͶM|$ M  H-0" H|$Hu H  Hl$"   H菶Hu HJ  HLMAVLL$L$T$,IHD$XZMtvHa  I H5" +H{ IG     >  1@ ۷HH9k#  HC H<谟H|$HI苎Lu蟷H<$LLH" 1H81s 転D$f諢D$H	   H耵H{ E1H-#" f     IL;{HC Hu N4    J<yHuH} {HHC J<0諞HHH" H5G H81轌D  H$    E1E1H<$LL|$$   HL$(dH3%(   L   H8[]A\A]A^A_    E1Lt$$H-	" 8@ E1H$     {HE kH k_fD  E1NH" H5 H81H} gH|$H蚝HH[" H5  H81誋upUSHH  HdH%(   HD$1HH衠H<$tRH"H߾"   蕳H{ HtpH$HPHptHHL$dH3%(   Hu0H[]D  H߾"   KH{ Ht&1֜迦Hx" 1H81܊Hu" H5 H81Ċ@ U"   SHHdH%(   HD$1ٲHk Htx1H6HcH~S1ךHHHH@H$~2H4$H+s9s|UHcH襛HHT$dH3%(   u2H[]H" 1H81H" H5 H81 ˥H   H5 H=M ff.     U"   SHHdH%(   HD$1Hk Htx1HHcH~S1HHHH@H$ѥ~2H4$H+s9s|UHcH赚HHT$dH3%(   u2H[]H" 1H81(H" H5] H81ۤH   H5/ H=] ,ff.     AUATUHH S1H(dH%(   HD$1HLL$LD$ԝH|$ZH|$IHt跲H<$H"   I謰H} HtgHcLLՉH5F" Lt   tHT$dH3%(   uGH([]A\A]1HH=$ H1 1H" H51 H81诣ff.     @ AWAVAUATE1USHH H8dH%(   HD$(1HL$HHD$(P1LL$(LD$ 豜XZH|$H|$IH|$ IHt@   諍IH|$H   褙IǾ"   HdHk H   RHLMMHLKH5" LtmHT$(dH3%(   HuUH8[]A\A]A^A_@ H|$IHp脊HL$ IeH/" H5 H81~IH" 1H81ffD  AU"   ATUSHH腮Hk H   H@Aą~qT1I    HH趲HNHtUHH" 1҃H" H8kLHpA9uHL[]A\A]D  HA   [L]A\A]H-" 1H81葅H*" H5 H81yf     USHH HdH%(   HD$1HHqH<$tRHH߾"   eH{ HtpH$HPHp軴tHHL$dH3%(   Hu0H[]D  H߾"   H{ Ht&1v菠HH" 1H81謄HE" H5 H81蔄@ ATIUSHH
LH1HHBHt*H߾"   H荬H{ Ht$Hk H[]A\H" 1H81 H" H5* H81     UHSHH" H8xHH譕HH5S HH" H81迃ff.     @ UHSH"   H֫Hm HtGH>" HH0HtH"   H詫Hs HtHXH[]HH" H5P H81.H&fD  UHSH"   HFHm HtGH" HH0kHtH"   HHs HtH訐H[]HHO" H5 H81螂HfD  PX1HH" H81w    SHHtHg" H1H[ٟ@ ATUHSH"   hHm HtBL%" HI4$茤HtZ"   H:Hs Ht,H蹨[]HcA\Hv" H5 H81ŁH^" H5 H81譁I<$4HHiHH5 HH}" H81{ff.     SHCHtH" H1H[ٞ@ PXH5/ HH" H81"fS"   HNH{ Ht4耆Ht#HH" 1[H" H8o       [ff.     S"   HH{ Ht[HcǪRfS"   H辨H{ Ht萔Hc[H_f.     UHHu SH(dH%(   HD$1H\$HOH|$Hu$HL$dH3%(   Hu`H([]f.     軋HHD$螐HD$Ht$H} HPHT$HPHuHB" H5 H81lff.     SHHtH" H1H[@ ATIHUHStJ襅HtJ"   HpHu HtKHt,H" [L1]HA\铜 KHu1Hx" 1H81~    ATI"   USHHk Ht4L"   I|$ Ht:HH踔Ht H[]A\H" H5 H81c~H" H5h H81F~fD  ATUHSH"   hHm HtBL%" HI4$茠HtZ"   H:Hs Ht,Hy[]HcA\Hv" H5 H81}H^" H5 H81}I<$4HHiHH5 HH}" H81{}ff.     UHH SH(dH%(   HD$1H\$HoH|$Hu$HL$dH3%(   Hu`H([]f.     ۈHHD$辍HD$Ht$H} HPHT$HPHuHb" H5 H81|茘ff.     SHӀHtHw" H1H[@ S"   H认HC Ht
Hx[{H" H5e H81C| H=" ATH5 USH8"HC" H" H5q HHHOL%`" H;H5\ Hw" HI$+H-" H5HHE H} HAH5f H} H%H5 ɚH}    H9H5 譚H}    HH5 葚H} 1HH5 xH} HXH5 \H} H,H5 @H} 1H#H5 'I$H;H5 $H-"    HaHH5N HE N~H} H5ΆH} H>H5C H} 1HH5= 詙H} 1HH5 萙H} 1H#H5 wH} 1HjH5 ^I$H;H5 [H-" H5HHE !H} HH5 H}    HH5~ H} H	H5 ݘH}    HH5Q H} 1H$H5< 記H} HH5" 茘H} HlH5 pI$H;H5 mH-" H5HHE 3H}    HcH5 'H}    HH5 H}    HH5 H} 1H"H5 ֗1迢H;H5{ H   裢H;H5 H   臢H;H5^ Hś   kH;H5` H詛   OH;H5] H荛   3H;H5] HqHH;H5\ HS1H;H5[ H:   H;H5Z H   ġH;H5[ H   訡H;H5 H   茡H;H5? Hʚ   pH;H5 H讚   TH;H5 H蒚   8H;H5 Hv   H;H5 HZ    H;H5 H>   H;H5 H"   ȠH;H5 H   謠H;H5 H    萠H;H5 HΙ@   tH;H5 H貙   XH;H5 H薙   <H;H5o Hz    H;H5\ H^   H;H5 HB   H;H5/ H&1ϟH;H5 H   賟H;H5 H   藟H;H5 H՘1~H;H5 H輘   bH;H5 [H]A\霘f.     fU"   SHHdH%(   HD$1)Hk Hto1H趟~N1Hc(HHHH@H$蒟~*H4$HH+sHHT$dH3%(   u2H[]H" 1H81qtH
" H5W H81Yt$@ AT"   USHHdH%(   HD$1gHk H9  H}H  E   L%" E1E11   L1Hc<H}HE1HH@E1   LH$ǞH4$H+s9s   HcHH= Hٺ   HHu" H81蓈HT$dH3%(   u}H[]A\f.     11Hc蟃H}HHH@H$؜H4$H+s9sqH    H5 H=i 8        s豎Hz" H5 H81rHb    H5 H= f.     ATIUSHH:H   HH6t`H߾"   褚H[ Ht2H{HtCtC   LHk[]A\ H" H5 H81rHiH" H5c H81qHj" H5 H81qf     U"   SHHH{ Ht]xHHu4H菋HHtLHHwHH[]fD  著H[H]S}H" H59 H81;qHD" 1H81(q     AUI"   ATAHUSHH(dH%(   HD$1,H{     H1LD$LHH# DtmH,$H= =   HHH1踅Hl$H=    HHH1蒅HL$dH3%(   HusH([]A\A]@ H<$|HH$H$Ht$H{ HPHT$HP}HuH " 1H81pH" H5 H81o跋    SH蓒HtH" H1H[IH" 1H81ofD  ATUHSHH|$Ht$1HI蕈HHt-H"   蠗H} Ht?HOzHD$H[]A\Ð   LSHHuH4" 1H81oH" H5 H81 oHHt3~Ht0HH" H" 1H8HZf.     {H" 1H81nfD  USHHH-T" Hu Ht'H߾"   豖H{ HtVHt9H[]H} ވHHHH5 HH'" H81%nH." 1H81nH" H5 H81mf.     SH" H5% H" HH;|H" H;H5 HH" H{Hi" H5HHyH;H`H55 贌H;   HH5 虌H;1H}H5 职H;   HH5l fH;1HH5 NH;1[HH5 5D  AUH5 ATUSHHÀ"   HHHC H   L M%  HK" HH3H   "   HHE H   HH   HqAH" H8oHHdHվ" LHHLDIHt&HH[]A\A]H" H5 H81讀H" H5 H81kH" H5 H81~H" H5p H81fH;>HHs}HH5 HH" H81kHF" H56 H81ff.     fAUH5 ATUSHH3"   HHsHC HtaL M   L-" HIu 苍H   "   H5HE HtkH8HtKL輐u&HH[]A\A]H" H5K H81aH" H5 H81jHr" H5f H811HZ" H5# H81I} HH%|HH5 HH9" H817jH" H5 H81~ff.     @ AUH5 ATUSHH}"   HH#HC HtkL M   L-o" HIu ;H   "   HHE HtuH8HtUH%" LHu&HH[]A\A]H0" H5 H81~H" H5k H81?iH" H5 H81}H " H5 H81}I} 薃HHzHH5q HH߿" H81hH" H5 H81u}D  AUH5k ATUSHH|"   HHӐHC HtkL M   L-" HIu H   "   H蕐HE HtuH8HtUHպ" LHju&HH[]A\A]H" H5 H81|H0" H5+ H81gHȽ" H5 H81|H" H5y H81o|I} FHH{yHH5! HH" H81gHN" H5> H81%|D  ATH5 USHI{"   HH艏HC H   HH   L%Ѿ" HI4$蝉H   "   HGHE Ht}H8Ht]H" HHktu[   ]A\Ð[1]A\H" H5 H81fHr" H53 H81I{Hr" H5f H811{HZ" H5# H81{I<$HH%xHH5 HH9" H817fH" H5 H81zff.     @ ATH5 USHy"   HH)HC H   HH   L%q" HI4$=H   "   HHE HtuH8HtUHNitu[   ]A\ [1]A\H" H5 H81YeH" H5 H81yH" H5 H81yH" H5 H81yI<$HHvHH5s HH" H81dH" H5 H81wy    H" AVAUIATUSH8H~"   HHӌL54" HLe I6HtQ"   H諌HC H   H0HtxLeI$HtOHHH5 ~[H]A\A]A^I>~HHuHH5 HH" H81cH" H5\ H81cH" H5 H81vxH" H5h H81^xff.      AVAUI"   ATUHSHH dH%(   HD$1請Le I<$   1HL$LD$LH ox   -  L-κ" H|$Iu 蘅H  H\$Iu H~H  "   H(HC H  L(M  H" H|$H0;Ht  H|$zH9" LHH
1cH  H  I$HH5( H|HHL$dH3%(     H []A\A]A^@ L-i" H|$Iu 諄H   H|$H5 vL5" HHI6|H  "   H&HC H  L0M  Iu H|$?H  H|$"   HD$H@ H  H8H  Lb@ L-" H|$Iu HF  H\$Iu HɃH   "   HsHC HtUH8HteH" H52 H81uHq" H5 H81uH" 1H81`H" H5w H81muH" H5 H81UuHf" H5 H81=uH&" H5 H81%u@|I} zHH,rHHHG" H5 H81>`H|$DHlH" H5 H81`Hյ" H5 H81tI>I} ~zH|$HqHH" H5^ H81ttH" H5u H81\tff.     SGHuH?Ht}H[Kff.     SH   螁fH1 HH[|fSH   nfH1 H
  H[|fU"   SHH9HC Ht<H(Ht|CHxHHtOH1HoH߅t#H[]TH" H5V H81Ls7kHp" 1H81^H]" H5G H81l^HE" H59 H81s@ ATU"   SH}HC H   L 舎H xHHtTt#LHxH߃u$[]A\闃    H=" LHNlwjHX" 1H81]H" H5 H81]H" H5N H81Dr@    2f1%D  AWAVIAUIATUH"   SHH舅HC H   L M	  L=X" HI7H   "   HGHE H   H(HtkL
uLItLHLHlu*HH[]A\A]A^A_H" H5Y H81OqHx" H5w H81\HH" H58 H81qH0" H5 H81qI?vHHnHH5 HH(" H81&\H" H5 H81pff.      ATUHSH"   (HE HtaH(HtqL%x" HI4$D~Htq"   HHC Ht+H0Ht;H2" HH[[]A\HHW" H5  H81pH?" H53 H81oI<$uHH
mHH5 HH" H81[ff.     AUATIUSHH5 HnH5 HHnHHHuH1[]A\A]Ð"   LID$ H   L M   L-±" HIu }H&  "   H谂HC Ht~HH   L-" HIu |H   "   HrHE H   H8H   H" HLH蔈¸   &H[]A\A]H" H5k H81nH" H5 H81inI} @tHHukHHH" H5 H81YH`" H5T H81nHH" H5 H81nI} sHHkHff.      AVAUI"   ATUHSHH0dH%(   HD$(1;Lc I<$   HL$HH LHD$(P1LL$(LD$ mZY   }  Hl$@  H|$HpH|$IpH|$ IpH9-" n  H" LLH
H`HHb  I,$HHL$(dH3%(   *  H0[]A\A]A^@ H|$@ueHH9="   H9="   H9="   -HH  HHuH" H5 H81W@ H-I" Hu zHtsHu H|$zH   H|$"   HD$H@ H+  H8H  *_HHH" H5: H81&WfD  H|$&111HIqHHtELcK_H	 KuHHD" H5 H81kk 11Ҿ   LXH5" 11LtxLH)cH<H|$1jHI)i   JHH   HǾ   t   H^H" H5 H81jH" H5 H81jqHk" H5 H81jH" H5 H81UH;" H5T H81bjH" LH5 H81UHp" LH5 H81|UH} pH|$H6gHH5 HHJ" H81HUH!" H5 H81iH	" H5 H81i     SGHuH?HtgH[黀ff.     U"   SHH	}H[ HtS;i{=     Hk H   HnHHtTH1H_xH߅t#H[]zH" H5_ H81i`HѦ" H5 H818TH" H5 H81 TH" H5 H81hH" H5Y H81SAUATA"   USHH|H[ Hy  ;rz=  O  H[ H*  H_H  H1j   HfI؃HpmHH   At>MtQH1HE1j E11HzXZHuKH[]A\A]x HHMt%Po@ HHvf     i_Hc" H5o H81RHI" H5 H81RH1" H5 H81RH" H5 H810gH" H5 H81gH" H5 H81PRH" H5B H81f        2f1%D  SHHHt$"   H$1zH[ H   ;x=     H[ H   H|${bHsbH$Ht$1IHVHHHvD@@dtuH   [@ H1[H" H5	 H81XQH" H5J H81eH" H5 H81eH" H5y H81QUSHH(Ht$"   dH%(   HD$1$yH[ H   ;w=     H[ H   H|$naHdH   Hk1pHc`1ILD$HHD$HMHPHp5uCt$HSHHT$dH3%(   uH([]Hӧ" H5, H81dkH" H5 H81PH" H5 H81OHn" H5U H81dHn" H5& H81Off.     fATUH"   SHwH[ H   ;4v=  0  Lc M  H" HH3qH   "   HwHE H   H(Htm1   _E1LHHx   HVx+HHcQH[]A\H" H5 H81cH[" H5 H81NH" H5s H81ZcHk" H5, H81BcH;iHHO`HH5 HHc" H81aNH" H5 H81bH" H5 H811NATUHSH"   XvHm H   } t=     Hm H   Ht]L%" HI4$RpH   "   HuHC H   H0H   H[TuH[]A\fD  1H>TvH" H5R H81aMH" H5 H81IMH" H5; H81aH" H5 H81aHڢ" H5 H81aH¢" H5 H81aI<$pgHH^HH5K HH" H81L    U"   HSHtH] Htl;9s=     H{ HtiXHHt8H= d1HH1maHtkHHH[]vfD  H   []H" H5 H81`H" H5t H81`H" H5E H81KH]" H5V H81K@ ATUH"   SHsH[ H   ;Dr=     H[ H   Hu1H|Pw.H[]A\    HpcHHIRPuMtH" H5( H81!KuH[]A\H" H5 H81_H|" H5c H81_H|" H54 H81Jff.     AWAVAUATUH"   SHHrLc M   A<$8q=    Ml$ Mh  L5" HI6lH  "   HrHE H   L8M   H5 H^IHtHI6HlH+  "   L5rID$    LH5 H     @    NdH5 Hߺ   :dLL]u*HH[]A\A]A^A_H1" H5 H810^H" H5 H81hIHA" H55 H81 ^H)" H5 H81]I>cHHZHH5 HH	" H81IH" H5o H81]H" H5@ H81HI>_cLH    AU"   ATUSHHpHk H   } @o=     Le M   H5) HY\HHtHH[]A\A]fLhIHtL-" I} PbIu HHjH   H"   KpHE HHH5 L @   kbHHH5 YbHH[]A\A]HL" H53 H81c\HL" H5 H81GH4" H5 H813\I} 
bHH?YHH5 HHS" H81QGAUI"   ATAHUSHH(dH%(   HD$1\oHk H  H}    DHL$LD$LHg 1\Ld$I  L-" LIu DiH   Iu H|$-iH  H|$"   nHD$L` M%  A<$*m=    I|$ Hk  <kA   IM  L꾘  H*l     H5޿ H`It&Hl$H= ^   HHH1[HL$dH3%(   H  H([]A\A]Hq" H|$H0<hHuoH|$t111HIKIHtdL,RL꾘  HlkY     H5  H_i WI sWLd$IfD  11Ҿ   L?G111LqjIHq11Ҿ   LG1LJiIHJ11Ҿ   LF1LlLIXQM#H|$13XHIXW  mIH   HǾ   PG   L3KH" H5P H81XHǖ" H5b H81XH" 1H81DLjH" H5 H81C_Hw" H5^ H81XI} e^H|$HUHH5> HH" H81CHC" H5 H81CH" LH5߿ H81wCH" LH5 H81\Cff.     U11HAWAVAUATSH(dH%(   HE1JHLcILHHHH H)HH9tH   H$   H9u%     H\$LHHfJH   LGIE~uAD$HHDHE ;h   LsI`GLIuNLH
l   MtLXNHLHkLLkH;]uHMdH3%(   Lu$He[A\A]A^A_]    H)HL (]H" H5 H81AD  SH5B HKHH5u KHH5ʼ KHH5 [KfPXH5r HHl" H812VfS"   HiHC H   H8HtrFtWt:tH" H5 H81U H" [HH    H" [HH    H" [HHBH" H5 H81zUf.     S"   HhHC HtH8Ht&xV[HcjHh" H51 H81'UfSHHHt$"   hHC Ht;HHtcH|$PHD$HHPHpaHT$H9Bu!HH[H" H5 H81THҕ" H5 H81?H" H5 H81yTf     U"   SHHgHC HtIHHt<HSHHt HWHH[H]O    H   []H0" H5 H81Sff.     @ ATIUHSH"   HQgHE HtzH8HtZH9" t?H9" tH9ױ" uo   [GL[]A\    FGL[]A\fD     .GL[]A\H" H5s H81>SHg" H50 H81&SH" H5p H81Sff.      UHSH"   HvfHE Ht;H(Ht.HuhSH\HH[]@ [DRH˓" H5 H81Rf.     S"   HeHC HtH8Ht&>[HHD Hx" H5A H817RfS"   HeHC Ht,H8HtNc[HHI        [H" H5ۻ H81QU"   SHHIeHC Ht>HHtf1_HHUHw" HHHARu"HH[]H" H5d H81ZQH" H5c H81<Hk" H5_ H81*Qf.     U"   SHHdHC Ht>HHtf1^HHVTHǎ" HHHXu"HH[]H" H5 H81PHӑ" H5ɸ H81;H" H5 H81zPf.     S"   HcHC HtH8Ht)<H[HHe" H5. H81$Pff.     @ PXH5Ͷ HHԍ" H81OfS"   HncH[ Ht*;a=  u9H{ Ht+G[HHH" H5 H81O~Hw" H5/ H81:fD  S"   HbH[ Ht(;Na=  ubH{ HtA)Qu   [H" H5o H81OH" H5G H81M:HΌ" H5 H81NHΑ" H5 H81:ff.     fS"   H>bH[ Ht*;`=  u9H{ Ht+IM[HHHd" H5 H81cNNHG" H5 H819fD  S"   HaH[ Ht4;`=  uCH{ Ht5LHtH[[    [Hڐ" H53 H81MH" H5u H819ff.     U"   SHH)aHk Ht,} _=  ueH} HtD?u"HH[]HM" H5 H81LMH" H5 H818H" H5 H81MH" H5 H81T8@ ATUSHtSH?^=     H" HH" 1HH8U1H5G HHRHtbH[]A\fJHHtKH" L RHHt4Hھ  H]tHى" 1HL    H9H" 1H817Hv" H5 H81m7ff.     fAUH5v ATUSHH" H" H;HEH" H;H5L HHߋ" H_EL%p" H-ъ" H5( HI$HE :EH" I$H5 H} HEL-" H;H5Q L%" IU I$DH" I<$H5+ HIU DHJ" H= HOH= H" NH= NH= H^" NH= HC" NH= H(" NH= NH=v H" NH=n H" yN   Hͨ" TH} H5M HEYH} 1HhH5Q L9H} HLH5Q TH} 1HH55 TH}    HH5 TH} 1HH51 TH}    HrH5 fTH} 1HiH5 MTH}    HH5 1TH} 1HH5 TH} 1HH5v SH} 1HH5 SH} 1HH5 SH}    HH54 SH}    HQH5' SH}    H5H5 ySH} 1HH5 `SH} 1HH5 GSH} 1HH5ˤ .SH;H5@H;HH5 SH;   HH5 RH;H H5 #EH;1HH5s RH;   HH5T RH;1HH57 RH;1HH5	 pRH;1HH5 XRH;1H<H5  @RH;   HH5 %RH;1HYH5 RH;   HH5ݰ QH;1HH5a QH;   HH5 QH;1HH5 QH;1HH5; QH;1HH5/ wQH;1HH5 _QI<$H5?>I<$H_H5 3QH= wJI<$E11Hƺ   YI<$   HH5 PI<$H H5 .CI<$1HH5ԯ PI<$1HH5ů PI<$1HH5 PI<$1H6H5 zPI<$1HH5 aPI<$1H$H5 HPH} H;I<$H[]A\A]@ USHH HdH%(   HD$1HHEH߾"   XH[ Ht{H<$tTHLAHAHEH<$Hc 3H$Hp1H2H$HL$dH3%(   uBH[] HxAHE1Hc@H$H" H5ұ H810K U"   SHH)XHk Ht$HA1HHK_u"HH[]HU" H5n H81/H" H5Ұ H81/ff.     SH@HtHw" H1H[LH" H5 H81A/PXH5 HH̆" H81"/fSHHH|$Ht$?H߾"   8WH{ HtHD$HPHp]WHH[ff.     @ S"   HVH{ Ht?HNT[H:C S"   HVH{ Ht?H5[HcX
f.     S"   HnVH{ Ht`?HxC[Hc?Xf.     AUATUHSHH'IH9tP"   HVLc MtHL-͂" HIu 9PHt["   HUHu HtL2t&HH[]A\A]H" H56 H81l-HU" 1H81Y-I} GHH?HH5 HH)" H81'-    USHHHt@u@t
?t<H-" HHu aOHtBH߾"   UH{ Ht^H[]= 1A@HHv[HtQH[]H} !GHHV>HH5 HHj" H81h,H" H5 H81P,H" HH5 H815,D  ATUSHHw H dH%(   HD$1Hl$HL$I(AH|$~LH|$ItH<H߾"   TH{ Htb1L;[u;Ht$Hu#HT$dH3%(   HuMH []A\    HEHHd}" H5 H81c+H" H5 H81K+GfD  UHSHH4" H8"   HHTSH{ Ht1HZu"HH[]H" H5 H81*H|" H5 H81*fSH=) OLH= CLH= <H5 HH~" H88H" Hx" H5 HHH8HD|" H;H5Hr6H;HH5 gIH;   HH5p LIH;1H H5p 4IH;H~"    H5 IH;H H5T S;H;HH5K 7H;1H\H5: HH;1HH50 HH;1[HH5Z Hf.     D  HM}" SH5@ H852HN" HUq2TVG-4DEH;   H5 oLH;   H58 [LH;   H5٪ GLH;	   H50 3LH;   H5D LH;   H5X LH;   H5 KH;   H5 KH;   H5 KH;   H5 KH;   H5 KH;   H5 KH;   H5 KH;   H5 kKH;   H5$ WKH;!   H58 CKH;#   H5p /KH;%   H58 KH;'   H5L KH;)   H5X JH;+   H5l JH;-   H5 JH;/   H5# JH;1   H5" JH;3   H5 JH;5   H5& {JH;7   H5( gJH;9   H5) SJH;;   H5) ?JH;=   H53 +JH;?   H5̭ JH;A   H5$ JH;e   H5̭ IH;	   H5 IH;   H5 IH;   H5 IH;   H5 IH;   H5 IH;	   H5 wIH;   H5 cIH;   H5 OIH;   H5 ;IH;   H5 'IH;   H5 IH;   H5 HH;   H5 HH;	   H5 HH;   H5 HH;   H5 HH;   H5 HBH1H;H5 H|HKH0H;H5ک H]HAH0H;H5̩ H>H7H0H;H5 HH'H0H;H5 H H:Hs0H;H5 [HGSHHHtH5@z" sOH{Ht%EH[1ff.     SHHH5 >H[@ PXH5t HH{" H81#fATUHHSHKHߨt3KHIH"   KH} Ht$L1=H[]A\[KH2Iyf     AVAUATUSHH H dH%(   HD$1HLL$LD$d8"   HgKHk HN  L%y" H<$I4$EH   H<$"   /KH$L` M*  H|$E1Ht;=IH|$E1Ht%5ILLLHA+u{H<$H5 |6HtHHH<$H5" [6H5 HH<HT$H5 H<HHL$dH3%(      H []A\A]A^H5x" LBMHSx" 1H81!I<$<H<$H3HH5` HHx" H81!Hey" H5; H81!HMy" H5> H81!g=    ATUHSHt-IIH"   IH} HtD'H[]A\ÐHx0I>ff.      ATUHSHt-IIH"   JIH} HtD7H[]A\ÐH0Iff.      ATUHSHt-IIH"   HH} HtL6H[]A\ÐH/I~ff.      S"   HHH{ Ht
+H[FfD  S"   HnHHC HtH   Ht	[37    [@ S"   H.HH{ Ht@6[H8fS"   HGH{ HtN[HHD fS"   HGH{ Ht>[HHD rfS"   HGH{ Ht`>Hc(B[H?+:f.     UHSH"   HVGHm Ht.HuP4Hf+HH[]@ C%f.     AU"   ATUSHHFH{ H	  c*HH   HAAąxPHc`#IEt-1fD  H H6LHGA9uHL[]A\A]D  HIr" H8t+H[]A\A]L5@ HA   [L]A\A]@ Hs"       H= HMH      H= MH;A  1H H    EtH8u" H5 H81    ATUHHȍ SH dH%(   HD$1HL$LD${2H\$Ld$H=@ 5H   HHSo" IMH8132Hk<   GHH5 Hl7H= p51HH11HI&H5Ƥ HH47H<H5 HH7HH5 HH 7LHL$dH3%(   u!H []A\@ H5 HA0N8    U"   SHHiDHk Ht=HH5ȣ 0HHH,o" 0<HE&H[]Hff.      PX1HH	r" H81    SHKHtHH41H[9@ USHHH{LH߾"   HCH{ HtHJ*u"HH[]Hr" H5Ţ H81#Nff.      USHHHCH߾"   H+CH{ HtHIu"HH[]Hdr" H5U H81ff.      S"   HBH{ Ht u   [Hr" H5 H81\    ATE1USHHtHH-Le"   H`BHk Ht:JHH7HtBE1   L   HGu H[]A\Hvq" H5g H81Hp" 1H81ff.     fATE1USHHtHHA-Le"   HAHk Ht:?HHHtBE1   L   H*Gu H[]A\Hp" H5 H81@HQo" 1H81ff.     fPXH5 HH|p" H81fATUHSHt-IIH"   @H} HtD H[]A\ÐH'Iff.      ATUHSHt-IIH"   @H} HtD!H[]A\ÐHX'I.ff.      ATUHSHt-IIH"   *@H} HtL9EH[]A\ÐH&Iff.      UH"   SHH?H{ Ht-Hj" H0HHH5! 1HH[]kff.     S"   HH{?HC HtuHj" H@x    H߾   HP(bHߺ   H5
 ~1Hߺ   H5 j1Hߺ   H5 V1Hߺ   H5> B1H[     SHCEHtHi" H1H[4@ HtHxl" HHVi" 1H83PHm" H5 H81C USHHH-4l" Hu 8Ht"   HQ>HC Ht9H[]H} 0HH'HH5c HHl" H81Hhm" H5Y H81    USHHH-k" Hu 8HtCH߾"   =H[ Ht_AT         H   HF >HH[]H} /HH'HH5 HHl" H81Hl" H5 H81HtH g" HH1H8l2PHtl" H5 H81 USHHH-f" Hu #7HtHC     HH[]H} /HHH&HH5 HH\k" H81Zf.     ATHki" H5} UH-Tk" SHH} w"L%k" H} H5a HVj" HI$R"Hj" H= H|,H;E11ɺ   H;H= [,H;E11ɺ   H:H= :,H;E11ɺ   H:H= ,H;E11Hƺ   :H;H5H;HH5 2H;   HH5 o2H;   HH5| T2H;   HH5h 92H;   HH5V 2H;   HH5 2H;   HH5' 1H;   HIH5 1H;1HH5 1H;   HVH5 1H;   HH5 1H;HH5֍ d1I$H} H5Ě ` H5YHH/d" HH$H߹HuH5 1H1HH5s 1H1HH5˙ 0H1HH5 0H߹   HRH57 0H1HH5r 0H1HH5 0H1H:H5 n0H1HH5 V0H1HH5 >0H߹   HH5K #0H߹   HH57 0H߹   H)H5% /H[]   HH5{ A\/f.     @ AVIAUATUH	   SH8H} ~6L%h" 1ېHE I4$L,    H<2H   HH9]Ծ"   LW8Mf M   I$H5/f" Hx0&;I$H} H@0    ~)1ېHE H</LH9tMHH9][H]A\A]A^I<$5*HHE J<(e!HH5 HHyf" H81wHc" 1H81dHf" H5F H81Lff.     U"   SHHdH%(   HD$1Y7Hk H   g?H(HHtbHEHH0tG1Hs   HH$HxH0"HHWHHT$dH3%(   u:H[]H5Hb" 1H81Hf" H5d H81j5*D  U"   SHHdH%(   HD$1y6Hk H   >H(HHt^HH&tG1Hs   HH$HxH0FHH{HHT$dH3%(   u:H[]HYHb" 1H81H?e" H5 H81Y)f     U"   SHHdH%(   HD$15Hk Hti1Hf(HcH   1HHHH@H$=(~nH4$H+s9s|BHcHaHHT$dH3%(   uH[]Hd" H5ɕ H81(Hc    H5 H=} Ha" 1H81Hb" 1H81D  U"   SHHdH%(   HD$14Hk H   <H?&HHt^HHtG1Hs   H6H$HxH0fHHHHT$dH3%(   u:H[]HyH:`" 1H81H_c" H5 H81y'f     ATUSHH HdH%(   HD$1H u&HH\$dH3%(      H[]A\fD  H<$Lc HH$?:11LHH+HtHfD  11Ҿ   HLHHIMjH9_" 1H81
&PX1HH_" H81
    SHHtH`" H1H[	(@ UH"   SHH2H[ Ht!He*HH*4t"HH[]Ha" H5 H81
Off.     @ AU"   ATUSHH%2Lc M   L`%ŅxRHcIŅt/1f     Ls&HLH039uHL[]A\A]fD  H]" H8tH[]A\A] @ HQ_"       H=	 H(9H      H=; 9H;A  1H H    0H`" H5ܑ H81fUH"   SHH1H[ Ht'H'HHx(H[]HH/`" H5x H81~f     AUI"   ATIUSHH0Hk Ht3L0LI(LHH5t&HH[]A\A]H_" H5 H816fD  UH"   SHH0H[ Ht!H&HHZ.t"HH[]HE_" H5 H81ff.     @ S"   H/H{ HtHt!H[H^" H54 H81:uD  UH"   SHHV/H[ Ht!HHH
t"HH[]H^" H5Ώ H81ff.     @ S"   H.HC HtH Hx Ht[$H,^" H5u H81{fD  ATIIUSx-HH"   .H} Ht1Lo#t H[]A\HZ" H5I H81VH]" H5 H81ff.      S"   H.HC HtH HxY+[HD H[]" H5 H81f.     AUATUHSHH H9t]"   H-Lc MtUL-uX" HIu 'HthH"   -H} Ht'HHt2L&Hk HH[]A\A]H\" H5 H81H`Y" 1H81I} sHHHH5Nw HH[" H81f.     HHt3NHt0HHW" HZ" 1H8H
"f.     kHX" 1H81VfD  USHHH-LW" Hu &Ht"   Ha,HC Ht9H[]H} HHHH5sv HHZ" H81Hx[" H5 H81    USHHH-V" Hu #&Ht'H߾"   +H{ HtV3Ht9H[]H} HH3HH5u HHGZ" H81EHW" 1H812HZ" H5 H81f.     SH,X" H57 HZ" HH;;HLW" H;H5Hx HH8Z" HHU" H5HHH;H H5Us !H;   HH5u !H;1HH5Ms !H;1HH5As !H;H&s H5&s H;1HH5r [!H;1HH5O C!H;   HH5 (!H;1HH5$ !H;   HH5  H;1HiH5  H;1HH5  H;   HH5  H;   HH5%}  H;   H`H5| t H;1H(H5 \ H;   HH5 A H;[   HH5u % D  SHH= HdH%(   HD$1HHH&HH$ HǸ   tHHT$dH3%(   uH[6fD  SHH= HdH%(   HD$1HH=&HH$a H	Ǹ   t9&HHT$dH3%(   uH[fD  UHSH=z HUHHHT" H8H[]H     UHSH=z HHHHNW" H8H[]     UHSH=Tz HHHHV" H8H[]     UHSH=z HHHHV" H8H[]     UHSH=y HUHHHT" H8H[]H     UHSH=y HHHHP" H8H[]     UHSH=Ty HHHHU" H8H[]     UHSH=y HHHHU" H8H[]     UHSH=x HUHHHR" H8H[]H     UHSH=x HHHHVQ" H8H[]     UHSH=Tx HHHHP" H8H[]     UHSH=x HHHHNS" H8H[]     UHSH=w HUHHHP" H8H[]H     UHSH=w HHHHN" H8H[]     UHSH=Tw HHHHO" H8H[]     UHSH=w HHHHP" H8H[]     UHSH=v HUHHHO" H8H[]H     UHSH=v HHHHvS" H8H[]     UHSH=Tv HHHH>R" H8H[]
     UHSH=v HHHHN" H8H[]
     UHSH=u HUHHHFP" H8H[]H
     UHSH=u HHHHFP" H8H[]
     SHH= HHQ HIH[@ U1H1SH~
H=҃ HIH1L    1H&)HH[]ff.     SHHH|$H|$HD${
Ht$H^H   [ AWHAVIAUATUSHH   H H|$@HT$HHL$DD$DL$dH%(   H$   1H$   zM.HD$Ll$xHw  HD$pHD$(HD$lHD$ H$   HD$0HD$xH$H$   HD$8H$   HD$XHL$(HT$ IHt$0H<$UAǨ  Ld$xT$M)Mc  L$   H$   L)ML$   H9;  D$pH-k"       tH-k" u@H-k" HD-k" A   HD$HHA!u	H  DL$HT$8E1H<$}IH9-Sk" Hc|$l  HIM" 98  HHE" HHDHm  H LIHI" H0EH   |$l   D$lH HcH>$   Ht$X1L$   DHc"IH>  H&Ņ  'HPHH  LHILHIfD  1H=r L   LH1|$lIW      H|$L{ D$Ll$xH+$   u	HHD$@HT$HL(H$   HHD$H$   dH3%(   k  HĨ   []A\A]A^A_     H=jq IIMLHHH" I   IH81RIBf.     KH|$H> HHH$   & HHL HHxH$   HH`DHHcLD$p            @   H5h" HHHHc|$lHHH H|$xIH$   HD$xH$   DL$HT$8E1HH<$LT$PbLT$PIH$   L)H$   fH5	h" HHW@ H5h" HH?@ H5g" HH'@ HH5\~ LH$   Ht$X1D$t    L$   DHcPHH  H=J" HT$tH@HI|$t@ $   Ht$X1L$   DHco  A1EM$   Ht$X1D$t    L$   DHc<HHo  H=IK" HT$tHHIa|$tUW$   Ht$X1L$   DHc IH  HhHc0I|$HHELI*$   Ht$X1L$   DHc	H   H1A   $   Ht$X1D$t    L$   DHcHHttH=NJ" HT$tHHIf|$tZ\D  LHYI1HH" H5| H819LHH" 1H81f     H8HHt$dH%(   HD$(1HD$    H|$HD$H	E1E11HD$ HD$ HT$H|$H@HD$HD$ HpHL$(dH3%(   uH8Nff.      H8HHt$dH%(   HD$(1HD$    H|$HD$H	E11HT$HD$ HD$ H|$A   H@HD$HD$ HpUHL$(dH3%(   u
   H8fD  H8HHt$dH%(   HD$(1HD$    rH|$HD$SHkE11HT$HD$ HD$ H|$A   H@HD$HD$ Hp1HHL$(dH3%(   uH8H   dH%(   HD$x1H|  LWMo  WfHHD$0    )$)D$)D$       HpPHHLVHPLHL@H5y 1 ZY.  |$HcHc|$HD$@Hc|$HD$HHc|$HD$PHc|$HD$XHc<$HD$`tH=y HD$hHL$@   HHA" H8Ht$xdH34%(      HĈ    1H=%y     HpPHHLVHPLHL@H5x 1^_u^|$D)  |$f.        ofD  l  |$<
H]E" H5yx H81THEE" H5:x H81<ff.     USHHt,1HHt5HHH?HH[]HD" H55x H81HB" 1H81f.     SHH=x @HHHt7<uRHH;`" t&H;`" t%H;`" t,H;`" u*   [@ 1[@ @   [f        [HC" H5w H811AUATE1USHH=v H(dH%(   HD$1HHH>" HHD$H2^H  H|$H=Ew OHHH+  HǨ   H   AHD$HpHHcH   1H|$EHH@DHD$HD$HPHD$H|$HpHP HD$HpHt$Ht$H+s9s|hHcH`HHL$dH3%(   uiH([]A\A]f;<@ H|$A   HD$H/B" 1H81Hz   H5/v H=[ OHA" H5u H81g    SHH= v HHUHt'<u'HH;^" tH;o^" u   [fD  1[HA" H5u H81ff.     AUIATUSHL%$@" A$~?H-8" 1 A9$~*HE HHtH0L'HtH[]A\A]Au;ItMMt<ItZAtHI}H5 z HH@" H81TH?" H8H)A" H8H>" H8H?" H8H>" H8     AWAVAUATUSHH(dH%(   HD$1H=`t AgHHH=Ft ]  HHHHAHHA/H=<s AHHH=D   pH*D   ƉD$1HcEDL$HH@HD$   Eu~SH|$ED   HsHSH|$HsHt$Ht$H+u9u   HcH.HHL$dH3%(      H([]A\A]A^A_     Lt$EDDL   USE1D   L?df.      HH`HASH|$E1D   Hw   H5r H=uX Dff.     @ USHHZ H8dH%(   HD$(1HL$HHD$(P1LL$(LD$ XZ/  HT$Hs  HL$H   s  HD$ H   <t  HH;Z"    HH5q HT$HH5p HT$HH5q HT$ HH5nq HH\$(dH3%(      H8[]    H!Z" HHHL$F    HY" HHHD$ >    H׃uhH   HT$*f.     HxHcHD$   HHD$HY" HHHD$ fD  HH<" H5p H81H~<" H5p H81Hf<" H5Np H81HN<" H5u H81ff.     fHH|$H|$]HD$1HxHtH HD$   HxHuH;" H5:p H81PUSHH=n H   dH%(   H$   1HHH#H[      HHHHKHH$   dH3%(   u
HĘ   [] H(H|$Ht$HT$HL$_H|$UH|$KHD$HPHD$HpHD$Hxt
   H(H:" 1H81Jf.     AUATUSH   HHIIHH;RW" HuHuUPHuSLHH5in cLHH5m QHHH5(n ?HH[]A\A]ÐHH:" H5Ls H81H:" H5m H81rfSH3Hߨu'[H~fD  [Hff.      Hc7HSH3HHHt[H"8" 1H81ff.      AUATUSHHdH%(   HD$1H=gl <HH  HUq IHcH>fLx1H^IHH  L-8" +  H5l    HHq  fLHuHHL$dH3%(   A  H[]A\A] I+     IH5l M/IEHHuHI8" H5l H81     L1fL-3" I<    H=\k HHH  HǨd  H    L$$HIHH	IH  H$LHPHp_ID$HL-4" HH	HID$     HL$$IH   H$LHPHpL-5" X I    IHtL-5" 2D  LL-4" IHhHpIHt>HSHsHHL-95" @ L01HIHH6" 1H81    [Ho6" H5j H81fD  L$$1L1AH46" H5j H81 AWAVAUATUSHH=	j HdH%(   HD$1HHtH=i   HHUHHsHAHA1HI     H5i Lc<HH   H$E   Eu^HLD	p 	@+LH4$H)I9   HHL$dH3%(      H[]A\A]A^A_f1LILE¾   LLfHH@HxHL[Him   H5h H=8i 1LDH]4" H5i H81ff.     AWH=i AVAUATUSH2H=h HP" H=h HP" H=h HP" H=T HP" H=h HP" H5h HP" H61" H8&HG2" H5" H5h HHHSH|3" H;   H5h HHsH;   HH5U H;   HH5Rh xH;H5Ih HI L51" Ab   L-%*" 1E   L%g D  Me IA$<[t,HwH;LHL1HLH#HA9.H{3" H;H5g HQL%B." H=e I$zI<$E1      HH=Lf UI<$E1      HH=
f 0I<$E1   Hƺ   I<$   H7H5,L I<$1H.H5JL I$H;H5g H- 1" H=e HE H} A      Hƺ   <H} HH5K 0H} 1HCH5K I$H;H5f H-" L-." HH2IE gH=Le +I} A      Hƺ   I} HH5$K I} 1HFH5BK I} 1HH5c qHU H;H5f nH/" H;H5e HH^HU H;H5e 6Ho/" H;H5e HHHU H;H5e H-" H;H5e HHnYHU H;H5ye L5w0" H;H H5We I!HU H;H5Ke H71" H;H50e HH~HU H;H5e VHG-" H;H5e HHHU H;H5d Ho-" H;H5d HHyHU H;H5d H," H;H5d HHAHU H;H5d H*" H;H5d HH	HU H;H5rd vHO," H;H5Wd HH&HU H;H5Id >H?." H;H5.d HHHU H;H5d Hw+" H;H5 d HH6aHU H;H5c HW+" H;H5c HH)HU H;H5c H+" H;H5c HHFHU H;H5c ^H." H;H5c HHHU H;H5sc &H-" H;H5Xc HHVHU H;H5Ec H(" H;H5*c HHIHU H;H5c L%," H;HpH5b I$HU H;H5b }H." H;H5b HHHU H;H5b EH-" H;H5b HHuIU H;H5b H-" H;H5ob HHhIU H;H5[b H)" H;H5@b HH0I<$   HH5b I<$1HH5b kI<$1H>H5a RI<$1HH5_N 9I<$Ha H5a rI<$Ha H5a [H=^ OI>HE1[   ]   A\HA]A^A_f     ATIUHHSH0  dH%(   H$(  1HH^H<$u   H5$d HE Ht5LHHKHH$(  dH3%(   u9H0  []A\HH(" H8tH &" H5Ad H81H)"       H=[ HH<$	H;   Hc 1H;Aw   1HZc Hu[    ^zf     S"   HH dH%(   HD$1zH{ Ht`HT$Ht$H|$t$1HT$L$H|$	9uID$H|$4 7 HL$dH3%(   uH [Hj*" H5b H81H$" H5b H81    AVIAUATUSH0H$H|$HT$dH%(   HD$(1HH$LLhL`HD$HXHhHE1MHT$$HLHRZY1ɋt$HT$ H\$49u'H|$ 7HL$(dH3%(   u%H0[]A\A]A^H#" H5a H81}ff.     fAVIAUATUSH H$H|$HT$dH%(   HD$1*H"H$LLhL`HD$HhHXHE1MHT$LHHR!ZYHct$HrHL$dH3%(   uH []A\A]A^SHH[f.     UH   SH1HxHHH     HHHǀ      1H)   HHHHHHH[]ff.     @ PXH5@` HH'" H812fS"   HH dH%(   HD$1JH{ Ht3HT$Ht$bt$H|$4HL$dH3%(   uH [y@ SHHH|$Ht$eH߾"   H{ HtHD$HPHpHH[ff.     @ S"   HH{ Ht111H[AUATUHSHHWH9tL"   HELc MtDL--$" HIu iHtD"   HHu HtLHH[]A\A]HQ&" H5^ H81I} 'HH\HH5A HHp%" H81nff.      ATIUSHHH|$Ht$"   HrHk Ht,LHt$HHHVHvHH[]A\     SH#" H5^ H!" HH;H" H;H5e HH%" HH"" H5HHH;   HH5] H;   HH5] H;   HH5= ~H;   HH5@ cH;1HH5@ KH;   H<H5] 0H;H] H5k@ jH;1HH5] H;1HVH5\ H;H\ H5\ $H;[H\ H5p= f.      AVIAUATUH	   SHH} ~6L%; " 1ېHE I4$L,    H<H   HH9]Ծ"   LGMn M   IE H5#" Hx0IE H} H@0    ~?1A HE H<LDHI*LtRHH9][H]A\A]A^I<$HHE J<(?HH5= HHS"" H81QLH" 1H819H"" H5[ H81!U"   SHHdH%(   HD$19Hk H   GHHHt^HHtG1Hs   HH$HxH0HH;HHT$dH3%(   u:H[]HH" 1H81fH!" H5Z H81Nf     U"   SHHdH%(   HD$1YHk H   gHHHt^HHtG1Hs   HH$HxH0&HH[HHT$dH3%(   u:H[]H9H" 1H81H!" H5Y H81n9f     U"   SHHdH%(   HD$1yHk H   HHHt^HHtG1Hs   HH$HxH0FHH{HHT$dH3%(   u:H[]HYH" 1H81H? " H5Y H81Yf     AVIAUATUH	   SHH} ~6L%S" 1ېHE I4$L,    H<H   HH9]Ծ"   LWMf M   I$H5g" Hx(&I$H} H@(    ~)1ېHE H<LHtUHH9]L[H]A\A]A^I<$-HHE J<(]HH5: HHq" H81oH" 1H81\H" H5W H81D@ U"   SHHdH%(   HD$1YHk H   gHHHtbHEHH0tG1Hs   HH$HxH0"HHWHHT$dH3%(   u:H[]H5H" 1H81H" H5V H81j5D  ATUSHH; HdH%(   HD$1Hbu&HH\$dH3%(      H[]A\fD  H<$Lc HH$11LHHHtHpfD  11Ҿ   HLHHIAMjH" 1H81PPX1HH" H81g    SH#HtH" H1H[@ PXH5U HH" H81fATUH"   SH8H[ Ht/HHߺHITLtH[]A\H" 1H81 AU"   ATUSHHLc M   LŅxRHcBIŅt/1f     LSHLH9uHL[]A\A]fD  H)" H8tH[]A\A],@ H"       H=K HH      H=L H;A  1HET HK    H3" H5T H81fUH"   SHHH[ Ht*HHH:x+H[]HH" H5S H81fD  AUI"   ATIUSHH/Hk Ht3LLIcLHHt&HH[]A\A]HL" H5%S H81fD  UH"   SHHH[ Ht)HEHH:t*HHH[]H" H5R H81,    AU"   ATUSHHELk M   IE Hx(ŅxUHcIąt/1@ IE ރHx(.HLHK9uHL[]A\A]f     H" H8tH[]A\A]@ Hi"       H=!I H@H
      H=Q 'H;A  1HQ HI    H" H5Q H81f.     UHSHHHdH%(   HD$1"   HH$HC Ht4HH1H{ HC Ht7HL$dH3%(   HuH[]H" H5P H81b-     UHSHHHdH%(   HD$1("   HH$WHC Ht0H 1HHxHt7HL$dH3%(   HuH[]Hw" H5PP H81ƿ<ff.     S"   HHC HtH [Hx S S"   HHC HtH [Hx# UH"   SHHvH[ Ht!H5HHt"HH[]H" H5~O H81off.     @ S"   HHC HtH [Hx ATIUSHt=HHHx\L"   I|$ Ht-HtH[]A\    HHH" H5N H816H" H5LG H81ff.      S"   H>HC HtH H8z[Hff.     AUATUHSHHH9t]"   HLc MtUL-" HIu 	HthH"   H} Ht'	HHt2L	Hk HH[]A\A]H" H5M H81/H" 1H81I} HHHH5~/ HH" H81f.     USHHH-" Hu CHt"   HHC Ht9H[]H} (HH]HH5/ HHq" H81oH" H5L H81W    USHHH-" Hu Ht@H߾"   aH[ Ht\H{A7         HL XHH[]H} uHHHH5P. HH" H81輻HU" H5.L H81褻@ HHt3.Ht0HH" H8" 1H8Hf.     +H" 1H81FfD  SH\" H5K HF" HH;kH|" H;H5*2 HHh" HHH9" H5HHH;HpH5+ H;   HH5. H;1HH5C H;   HH5] H;1H*H5C H;1HrH530 H;   HH5J kH;1HH5J SH;   HH5J 8H;1H<H5J  H;   HH5J H;1HH5J H;   HH5J H;   HH5zJ H;   HXH525 H;   HH54 H;1HH5!* iH;1HH5) QH;H) H5) H;1HH5) #H;1H7H5I H;   HLH5I H;[   HH5I @ ATI"   USHHPHT$H$dH%(   HD$H1Hk H   LH\$HH覹H|$HH$HHPHpHD$HHHPHp(t$u#   HL$HdH3%(   u9HP[]A\Ð1H" 1H81蹷HR" H5' H81Qlff.     AT1UHSHH`HT$1dH%(   HD$X1H^
" H01tH   "   H}Lc M   HHl$ HH舸H|$HD$HHPHpyL!1pHcDHT$LHHpHmtkHct$H;sAHHHL$XdH3%(   u!H`[]A\H	" H5G H81肶MHfH    H5G H=G H/
" 1H81KH" H5=& H81 H
" SHH0詾HuH[H	" H5G H81    SHHt-H" H1HZ1H5% HH6H[H	" 1H81螵ff.      ATA   USYIcH1HHaHcH߾   HIH[]A\ff.     fSHtgH?t'~tt0=  u2H[u$H[钿fH[W    H[ǷH" H5F H81迴H" H5F H81觴    USHH|$H|$GH|$HD$H5G Hx8Ht5H	" 11HHHH"Ht6HŽH[]虴8"H5P HH" H81H" 1H81@ USHHH-" Hu SHt"   HHC Ht9H[]H} 8HHmHH5& HH
" H81H" H5q# H81    U11SHHHH" H01^Hu5H-" HHu HtM"   HSHC HtH[]Ht" H5$D H81H
" H5" H81H} ZHHHH55% HH	" H81衲USHHH-T" Hu Ht@H߾"   H[ Ht\H{Au   
      HC HH[]H} HHHH5$ HH	" H81H	" H5! H81@ U11SHHH" H01HuXH-" HHu 5HtpH߾"   H[ HtBH{A   
      HB HH[]H" H5B H81XH" H5J! H81H} HHHH5# HH" H81ff.      H" SH5TB H8H" HO" H5<B HHHH" H;H5B HH" HH`" H5HH趼H;1HJH5/! H;   HH5), H;   H5+ HxH= ! H%" HM[]f.      U"   SHHdH%(   HD$1Hk H   'HHHt^HHܷtG1Hs   H趱H$HxH0HHHHT$dH3%(   u:H[]HH" 1H81FH" H57A H81.f     U"   SHHdH%(   HD$19Hk Htx1HvHcH~S17HHHH@H$Q~2H4$H+s9s|UHcHHHT$dH3%(   u2H[]H" 1H81xH" H5i@ H81`+H@ ]   H5`@ H= |ff.     PX1HH" H81    SHHH|$Ht$赾"   H(HC Ht(HL$H HQHqHxt#HD$H[HP" H5? H81蟭jf.     S"   HHC H   H H@Hc0~Hx[鹽f     Ha" H8t11[陽f     H)"       H=4 H H      H=#? H;A   1H> H4    Hk" H5> H81躬f.     UH"   SHHH[ HtIHHHʾtuH   []D  H1[]H" 1H81DH" H55> H81,ff.     ATUHSHHHIH߾"   H/H{ HtHL+t H[]A\Hh" H5= H81跫fUH"   SHHH[ Ht!HHH*t"HH[]H" H5]= H81Tff.     @ S"   HnH{ Ht`Ht!H[颴H" H5= H81D  S"   HH{ Ht HHt+HH[HN" H5< H81蝪h     USHH H(dH%(   HD$1Hl$H菿uHL$dH3%(   HusH([]ÐHHD$Hx5HHtH{ Hk 諪f     HD$Ht$1HPHT$HPHHuSHCHtH'! H1H[9t@ H! SH5; H8腲H! H! H5; HHH買H! H;H5; HH " H菷H " H5aHHVH;HH5 KH;1HH5 3H;1HH5 H;H H5 UH;1HH5 H;1HaH5C H;   HH5& H;   HKH55$ H;   HH5# H;1HH5: lH;[   HH5u: PU"   SHHdH%(   HD$1)Hk Htx1HHcH~S1'HHHH@H$~2H4$H+s9s|UHcHHHT$dH3%(   u2H[]H4! 1H81hH! H59 H81PH: ]  H59 H= lff.     AW"   AVAUATUSHH(  dH%(   H$  1+HC H$H  H<$AŅ   Hc螫HD$E   1Hl$f     H<$IH(  H   H虰  H趨IIFHcHHc0HxLt	裶LI8LL   H1H|$HA9mH$  dH3%(   HD$   H(  []A\A]A^A_    H! H8tHD$H!       H=p- HH      H=58 vH;A   1H8 Hj-    SH! 1H81NH! H57 H816ATUHHS SH dH%(   HD$1HL$0H|$HtuIHHHH   "   HHu H   HL1H߅tdAHT$dH3%(   uH []A\     H"   H} Ht@111HHVHHD$9HD$ݰH! 1H81*H! H56 H81ݿff.     fAUATUSHH H(dH%(   HD$1Hl$ILL$ILLxHpH|$   "   HHk H   HD$H|$L`Lh@uR轸H$HLEAHHpj ZYt{HL$dH3%(   Hu{H([]A\A]D  {    H=5 L$$Hc-V" 艻HHg! H8臥L   HH1HD$$H! 1H81赢耾HI! H5#5 H81蘢     ATI"   UHSHH0dH%(   HD$(1HC H$H6  1HL$LD$LH au%HL$(dH3%(   H   H0[]A\D  H|$莨HHtMHT$H   H޿   1觬H=+ IXM11L   HHD  H|$nH|$ HD$ OHD$ Ht$HHPHT$HPPH$HS H2H! 1H81L@ H=3 ̹HH! H8ʣHHD$7H! H53 H81 ATUH1SHHH dH%(   HD$1tH   Id	   HH1HJ   HH$9   HHD$'HD$Ht4HL   l   HL$dH3%(   uYH []A\fD  Hc5" H$H1   NHD$HuH=2 觸HH! H8襢HD$ɻf     SHHtH! H1H[YH! 1H81趟fD  S"   HH{ Ht[HgH ! H51 H81off.     @ ATUHSH"   Hm Ht:L%! HI4$Ht:"   H^Hs Ht[H]A\yH! H5|1 H81I<$xHH議HH5S HH! H81连ff.     @ HCHx1҃HTHH @u.HtpHt[Htu@tHVH! H9t1@ H! HH! H9uH¸   t1H    H! H@ H! H@ H! H@ HI! HvS"   HH{ Ht`[H釼H@! H50 H81菝ff.     @ HHt3Ht0HH! H! 1H8Hںf.     kH! 1H81&fD  USHHH-! Hu 胿Ht"   H1HC Ht9H[]H} hHH蝮HH5C HH! H81诜HH! H5"/ H81藜    AVH=h/ AUATUSH! H5R/ " H! H;H袪H! H;H5[/ HH! HH! H51HHFH;HwH5 ;H;HH5.  H;HH5 H;1HH5. H;   HH5: ҺH;Hs: H5. H;   HH5Q 衺H;1HH5S. 艺H;1HmH5@. qH;1HH5 Y   ?   I2   I%H;LH5- I`H=2 Lp HȦLHHH=- 讦LHHКH=- 蔦LHH趚H=- zLHH蜚H=- `LHH肚H=- FLHHhH=|- ,LHHNH;HH5, 茽1H;H5t HsɸH;H57- HW 譸H;H5#- H; 葸H;H5- [H]A\A]A^    USHHH-! dH%(   HD$1H$Hu ۻH   H=9
 ֱ1HH1WH?1HHH   HHH۝Hu4蟥HwH$H~>H! H5, H81֘fD  kHHL$dH3%(   umH[]ÐH! H57, H81蘘H0H! 1H81}H} HH9HH5
 HHM! H81KfD  UH5+ SHH0! HI! H;HfH! H;H5+ HHc! HCH-<! HE sHHأH} H5+ HEHH[]駶    U"   SHHdH%(   HD$1ɿHk Htx1HHcH~S1ǧHHHH@H$~2H4$H+s9s|UHcH蕨HHT$dH3%(   u2H[]Ht! 1H81H! H5* H81軲HD+    H5* H== ff.     AVAUATUSHH$ H@dH%(   HD$81Hl$HL$HD$0    ID$    裫   E1H|$   H|$bHs HH裥HۢH{ HL$(LHT$ LD$0   Hl$Ht$ H=! HT$Iƅ   A   A   H|$(ʶH5! H|$0LH5 H7LH5) H%HLH5) |$   HL$8dH3%(   HuwH@[]A\A]A^    H蘵IHt$(H=! HA   FIŋD$CHt$0H5H=! HIͶȰHQ! H5( H81AWH) AVE1AUATUSH   dH%(   HD$x1H\$0Hl$(HHD$xIHPHD$xPHD$xPLl$xAULd$xATHD$xPHD$xP1LL$x蕩H@H|$(tH葴IE1H|$0tH{IH|$81|H|$@HD$譼H|$HHD$HtxH1H|$Pg  E1H|$Xx  H|$`E1Ht@0  +AH|$h1Ht@  H|$p1HtT$@   T$PALLRIAUATHL$0HT$(H5V! H HHH  Ho! H ! 1HH8軰HT$8H53 HH蔭HT$@H5' H耭HT$HH5' HlHHL$xdH3%(      HĈ   []A\A]A^A_ T$,f@ A LȲHpŅLL訲HPAąmL荲H5w& HH! H81H! 1H81f.     SH賽HtH! H1H[yHB! 1H81֑fD  H-! SH5& HH! H8H! H! H5% HHH؟H! H;H5	 HHH;H5I脝H=V+ ةH;E11ɺ   HcH=D% 跩H;E11ɺ   HBH=0% 薩H;E11Hƺ   !H;H"H5 H;1[HH5 f.      U"   SHHdH%(   HD$1ɸHk Htx1HHcH~S1ǠHHHH@H$~2H4$H+s9s|UHcH蕡HHT$dH3%(   u2H[]H! 1H81H! H5m$ H81軫H& $  H5e$ H==  ff.     AVAUATU1SHH H dH%(   HD$1HLL$LD$貤H<$)H|$IH|$IHt@tx賕ž"   H脷Ls Mt|薿H.HHtTLAHLLBH߅t4覴HT$dH3%(   uOH []A\A]A^f     +rHc! 1H81迎HX! H5$# H81觎rfAWAVAUATE1USHH HHdH%(   HD$81HL$D$    HHD$8P1LL$8LD$0yH|$@ZYHt@  荔AHD$(H3  H#H|$IHI  Ht$GIŋD$  H|$ 螝"   HHD$L{ MK  H貧HH  HT$ELILLLA"E   H   HtHZHH5^ HȧH۲H5! HH詧H5! LJ1AHHL$8dH3%(      HH[]A\A]A^A_ H5{! HɠHD$(HH|$E1HE1AyL;H5! L輷H! 1H81yDH! H5  H81\L|$ff.     S"   HnH[ H   H{舻tSH{z   H{htSH{Z   H{H¸   tL[f.     H=Y  D[HHf.     H=J  $[HHf.     H=  [HHf.     H=   [HHf.     H= ģ[HHH! H5 H81fAWAVAUATUSH   H$ H(Ht$IHdH%(   H$  1߹"   LIMn M   I}   1LH\$HHuS    HHA9u:   HLޖAǅHL<t   H5 L贤H̖LĖHu?H$  dH3%(   HD$uRH(  []A\A]A^A_þ   L胬;Hl! 1H81ȉHa! H5- H81谉{ff.     AU"   ATUSHHűH[ H	  H{߸   HC L`M   LmŅ   HcIŅtl1LH59! H=! HʘH   HH/! 1҃H! H8胦LH舲9tLJHu fD  HL[]A\A]f.     H{uHC L`0M<H[]A\A]鲟H! 1H81oH! H5 H81WH! H5 H81?ff.     @ AU"   ATUSHHUH{ HE  #IH   HŅ:  Hc轌IŅtn1NfH5! H=! HjH   HH! 1҃H[! H8#LH(9tLHu fD  HL[]A\A]f.     Ha! H8tH[]A\A]dH-!       H= HH'      H= H;A  1Hv H    ȮHg! 1H81ÆH\! H5( H81諆H<! H5 H81蓆 ATUSHH  HdH%(   HD$1H蒛u&HH\$dH3%(      H[]A\fD  H<$Lc HH$/11LHH]Ht8H蠒Hߺ   H5 l   H5 HXu H11Ҿ   ߇LHD}ff.     fAUH  ATUSH8dH%(   HD$(1HL$D$    HHD$(P1LL$(LD$ 胚H|$(ZYH   IH|$ 1Ht@   ~H|$"H|$Ht$HPIŋD$   LLHaHHH   mHV! 1HHj! H8BHT$H5@ HHH5! L輯HHT$(dH3%(   u.H8[]A\A]fD  賙@@ IH52! LbH! 1H81H跐|$ޥff.      AVH AUATUS1H@dH%(   HD$81HD$0HL$D$    PHD$0P1LL$0LD$(ݘZYH|$1H|$IDH|$0IHt@   ׉H|$ {H|$(HH   Ht$蟃IċD$   AHLLL輧H   HH! H! 1H8蘠HT$ H5 HHq   H5
 H]HuH5! LHHT$8dH3%(   u+H@[]A\A]A^fD  @ E1HSHH5l! L蜭H! 1H81YH|$     AUH ATUS1H(dH%(   HD$1HLL$LD$7H|$Ht@   MH|$H<$   H-d! Hu KH;  H<$"   H$L` MT  E1H|$   H臛HH   LLH   LHHT$dH3%(      H([]A\A]@ {H|$H<$>H5 H<$HD$$    I|$^t!H|$H   I9D  11ɾ   Lڃ@HEHBL:H+! 1H81臀H} H<$HBHH5  HHV! H81TH! H5 H817E1ff.     @ PXH5" HH! H81fS"   H.HC Ht
Hx[鋝fD  S"   HHC HtH@[HxǭfS"   HΧHC HtH@[Hx闭H! H5 H81_ff.     @ S"   H~HC HtH@[H8鈝 PX1HH! H81    USHHH{H߾"   HH{ HtHJt"HH[]HU! H5 H81~ff.     @ SH賬HtH_! H1H[D@ S"   H莦H{ Ht/4   蛌Ht88t   [f.     Hx[馡H! H5/ H81}f     AUATIUHSHHH聦LIVHIKH߾"   HH{ Ht HLLdt&HH[]A\A]H! H5 H81j}ED  SHHtH! H1H[ɚ@ U"   SHHYHk Ht2kHHHtMHH0H߅t#H[]~Hw! H5C H81|aHR! 1H81|f     PXH5
 HH,! H81|fS"   H貤H[ Ht#H{Ыtt1[fHC [H@HHH׉    ATIUHSH     H訪H`HuH= oMH1LP  1HH[]A\ff.      S"   HH[ Ht#H{ tt1[fHC [H@ATIUHSH     H8H谤HuH= 迓MH1L  1HFH[]A\ff.      HCHH7    ATI"   USHHk HtLǫHH謘t H[]A\H9! H5 H81zc HHH두ATI"   USH蘢Hk HtLעHH<t H[]A\H! H5 H81z HHH두ATL%! UHSHI4$H_Htc"   HHS H   H5! H=2! ]HH   H"   ԡH} HtfHt:H[]A\I<$HH3HH5  HHG! H81EyH蝋H! H5r H81%yH! 1H81yH! H5
 H81xD  ATL%! UHSHI4$HOH   "   HHS H   H5! H=! IIH   "   HH] HtnLH\t?H{ϧt
H[]A\f   L   2   H聓H[]A\L!H! H5o H81	xdH! 1H81wH! H5
 H81wI<$`HH蕉HH5;  HH! H81w    UH"   SHHƟH[ Ht!H5HH語t"HH[]H! H5 H81Dwff.     @ S"   H^H[ Ht7H{|t1[ 11ɾ   HH¸   Hu19f     S"   HH{ Ht11Ҿ   ן[HH@ UHSH"   H趞H} Ht-HuA1H   1Ht"HH[]H! H5
 H81(vH! H5 H81vff.     AWAVAUATUHSH"   HdH%(   HD$1Le M   H$Htu   ?$   HЕIL=! H=
 1M     II} HtwL˗t?u߾   LRtrHL$dH3%(   HuZH[]A\A]A^A_@ HcHAt/f.     HHT|I_H}! LH5d
 H81t蜐H`! H5,	 H81tff.     @ AUATUHSHHǏH9tZ"   H赜Lc MtRL-! HIu ٖHteH"   臜H} Ht$ِHt2HC LX{HH[]A\A]H! H5 H81tH! 1H81sI} vHH諅HH5Q  HH! H81sff.     fSH胎HtHG! H1H[d@ ATHUSHdH%(   HD$1lHH$    HHxHHHtwH<$A   HtIH! H! 1HH8蔐LH5 HHo   H5  H[HHL$dH3%(   uH[]A\腎D  S"   HޚHC HtH@[H8H!! H5 H81prATHk! H5 L%! USH8I$藀Hh! H! H5 HHHtH! H;   H5 HHuH;HH5 uH;HH5  iuH;HH5  NuH=B 2H;E11ɺ   H轘H=  H;E1   Hƺ   虘H;H5}H;   HH5  H;HH5  dH;   HH5 IH;1HH5  1H;   HRH5 H;1HH5 H;1HH5 H;   HH5v ˏH;   HH5c 谏H;1H4H5V 蘏H;   HIH5C }H;1HH59 eH;   HH5) JH;   HH5 /H;1HH5 H;   HH5h  H;   HH5 H;1HUH5 ɎH;   HjH5 讎H;H H5 H;HH5  }H;HnH57  bH;1HH5  JH;H  H5  脀H;1H8H5  I$H;H5- }H-! H;H5" HHE ,H} H5AzH}    HH5A  H} 1HH5T  觍H} HD  H5K  H} 1HH5+  wH} 1HH5 ^I$H;H5 [|H-,! H5mHHE !zH}    HH5  H} 1HxH5  H} 1HH5  H} 1HH5 ʌ   谗H;H5	 H   蔗H;H5~  HҐ   xH;H5s  H趐   \H;H5^  H蚐   @H;H52  H~    $H;H5.  Hb@   H;H5f HF   H;H5S H*   ЖH;H5> H   贖H;H5) [H]A\f.     @ AT"   USH苔H[ H   ;t   HHC Hx詎H=N  I
xLHH,lHC Hx H=  IwLHHlHC Hx(UH=  IwLHHkHC Hx0+H= IwLHHkHC Hx8H= HbwHHHkH[]A\H! H5>  H81H! H5( H81kff.     ATUHSH"   H4Hm H   HtiHLe HI|$8HtHt/HH[]A\fHD$覙Ht$ID$8HE Hx8HuH! 1H81|j@ HE Hx8;HE H@8    HH[]A\H! H5E  H81~ff.     ATUHSH"   HTHm H   HtiHLe HI|$0HtHt/HH[]A\fHD$ƘHt$ID$0HE Hx0HuH ! 1H81i@ HE Hx0[HE H@0    HH[]A\H! H5e  H81~ff.     ATUHSH"   HtHm H   HtiH9Le HI|$(Ht3Ht/HH[]A\fHD$Ht$ID$(HE Hx(HuH ! 1H81h@ HE Hx({HE H@(    HH[]A\H,! H5  H81+}ff.     ATUHSH"   H蔐Hm H   HtiHYLe HI|$ HtSHt/HH[]A\fHD$Ht$ID$ HE Hx HuH@! 1H81g@ HE Hx HE H@     HH[]A\HL! H5  H81K|ff.     ATUHSH"   H贏Hm H   HtiHyLe HI|$HtsHt/HH[]A\fHD$&Ht$ID$HE HxHuH`! 1H81f@ HE Hx~HE H@    HH[]A\Hl! H5  H81k{ff.     SHHHt$"   H$юH[ HtX;1tuwH|$2wH*wH$Ht$1LK HVHHHvD@趍x*H[HHɽ! H5"  H81zHi! 1H81fH! H5  H81eff.     fUHSH(Ht$"   dH%(   HD$1H] H   ;Pt   H|$MvH{ H8 tb{1pHcuLK 1LD$HHD$HMHPHpLmtxHct$HvHHT$dH3%(   uSH([]ÐH5V  HyHuNH{ H! H5  H81dH! H5  H81y蠀H!! 1H81dH! H5  H81dD  AT"   USHHdH%(   HD$1跌Hk H   } t   H} H8 tnL%! 1AHcH~c1tHH} HH@H$AԅxCH4$H+s9s|aHcHbuHHT$dH3%(   uzH[]A\fD  L%i! H(! 1H81cH]! H5  H81cHE  '  H5  H=  rH&! H5  H81%x@AUI"   ATAHUSHH(dH%(   HD$1|H[ HL  ;؉t  Hl$DHL$LIH  1.xH|$Hu{E1E1HH|HH   Hs H~8 tyHL! 1LATE1HlZY   H:HT$dH3%(      H([]A\A] 3wE1H|$ItH虂IdHHE1E1j H=b! HH5~  j j sH yHnHd! 1H81 bH! H5  H81a}H|! H5  H81{vff.     U"   SHHH[ Htq;ItuMH{HHt%Hs H1vHtH[]mH! 1H81GaH! H5;  H81/aHȸ! H5!  H81u    U   SH8dH%(   HD$(1H\$H要~   9E1ɅuRHL$H   j HLD$tHXZHtIH!|t-HT$(dH3%(   Hu.H8[] Ly!     H舅     1'|    AVI"   AUAHATUSHH dH%(   HD$1ZLc M  Hl$1HL$LIHn  Du   H|$@   E1H|$tHH|$IkHHD$踎H! L1HI}HH   LlHt   L]9  HL$dH3%(   H/  H []A\A]A^Ðe$HHuH}! 1H81_f     یHfD  11Ҿ   LaE1E11H=p! LH5$  `HH@11Ҿ   L`111LaHH11Ҿ   L`1LdHH11Ҿ   L`1LwLHjHH! H5  H81,^HDyH! H5  H81rfAUIATIU1SHxHt?Lt   HHt=H! 1HLI{1H5  HH%xHH[]A\A]    H_HH[]A\A]f.     U"   SHH虅Hk H   } t   HU H5! H=Q! lHu<HtvHtaHt{   H{Ht(HHtH[]D  H! H8HuHH! 1H81\fD  H! H8@ HI! H8@ HA! H8@ H! H8sH
! H5c  H81	qH! H5M  H81A\UHHSHt+bHHt+HHHtH[]KqHHuHH5! 1H81[U"   HSHH] Hta;Ytu=HC Hx8 tH   []D  H5  HioH1HtH[]H ! H5[  H81O[H! H5A  H81o    PXH5'  HH! H81ofS"   H>HC HtH@ Hx8Ht[r}f   [@ S"   HHC HtH@ Hx0Ht[2}f   [d@ S"   H辂HC HtH@ Hx(Ht[|f   [$@ S"   H~HC HtH@ Hx Ht[|f   [@ S"   H>HC HtH@ HxHt[r|f   [@ S"   HH[ Ht ;^tu,HC [Hx0 HH.! H5  H81-nH! H5q  H81eYD  SHtNH?tuzH0! Ha! H1H8v1H5`  HHsHt3H[fD  ӆHtHH! H8H    H1! 1H81XH! H5  H81XD  SH|! H5	  H! HH;fHܭ! H;H5  HH8! HfHQ!    HHH5  H[H;HH5  hwH;1HLH5  PwH;1H4H5  8wH;1H,H5   wH;HaH5  wH;H  H5  ?iH;H  H5  )iH;1HH5y  vH;1HH5i  vH;   HzH5  vH;   HH5  svH;1HH5\  [vH;   H|H5O  @vH;1HH5  (vH;   HiH5
  vH;1H1H5  uH;   HVH5  uH;1HH5  uH;   HCH5  uH;1HKH5q  uH;   H0H5  tuH;1[HH5m  [uf.     AULATIUSHAHt$H$   D\H|$fHf1Hc&fLAHLhtF\AH$HD$HAHJHpHRHxAU}ZYu,HH[]A\A]fjAfD  jrH-! H5  H81<Uff.     AWLAVIAUATULSHAHt$H$   ][H|$eHeHqu1HcI4eLAHH$L}LhtL[AHD$H$MHJHpLHxAWSqgZYu6HH[]A\A]A^A_     iAfD  iYH-! H5  H81<Tff.     H-! SH5  H8]H6! H! H5  HHHBbH˥! H;   H5  HHjH;[   HH5  jU"   SHHdH%(   HD$1{Hk Htx1HdHcH~S1cHHHH@H$cx2H4$H+s9s|UHcHdHHT$dH3%(   u2H[]Hl! 1H81SH! H5  H81RnH4    H5  H==  bff.     U"   SHHzH{ Ht]iHH u4HlHHtLHH|XHH[]wfD  xH[H]C^Hܩ! H5<  H81+RH|! 1H81R     p    ATIHUSHHt$]H|$HD$bHD$C  H5  HxaHtvHHD$HHpHP.fفHH   HD$HHHPyH߅tb]pL"   yI|$ Ht.HkHD$H[]A\H! H5`  H81(QH! H5!  H81QoH#THT! 1H81PHofD  AUI"   ATUHSHH8dH%(   HD$(1xH{  %  Ld$1LL$LLD$LH  e   Ld$H=  h   HLH1neLd$H=  h   HHL1He#HL$(dH3%(   H   H8[]A\A]ÐHl$H=/  h   HHH1d     H|$[LHD$y`HD$Ht$ H{ HPHT$ HPpHmH! 1H81}OH! H5v  H81eO0kAUATUSHHA  H(dH%(   HD$1Hl$ILL$ILPdL_H_H|$u	HD$    H$HxBQŅ   HD$H  H=  HDZHt$HIh`"   HvLc M   HH5  b1HtH_YHIMLjH   HHS! Hl! 1H8kH\$dH3%(   uaH([]A\A]    H$Hx`Ņ)H$H5U  HPHS! H81MH! H5  H81MiHD$H50  HHH$HPH! H81Mff.     U"   SHHuHk Htm}HsgHHtE11HHgtHH[]rf.     HuHTHH[]rHw! 1H81MH! H5  H81Lff.     PXH5  HH|! H81LfS"   HtH{ Hth[Hff.      UH"   SHHtH{ Ht1H@+ZHH[]\ff.     ATUHSHH|$Ht$bl1HI5eHHt-H"   @tH} Ht?HolHD$H[]A\Ð   LdHHuH! 1H81K PXH5  HH<! H81KfATUH"   SHsLc Mt-HH5  HeH5VLHmH[]A\ff.     fATUH"   SHXsLc Mt'HHH5r  }eH|ID$ H[]A\3 ATUH"   SHsLc Mt'HHH5'  -eHeMID$H[]A\ ATUH"   SHrLc Mt'HHH5  dHrID$H[]A\ ATUH"   SHhrLc Mt'HHH5  dHrID$H[]A\C SHH  H0dH%(   HD$(1HL$HHD$(P1LL$(LD$ ^Ht$XZHtHXHt$HtHHt$HtHHt$ HtH/   H5  HcHHT$(dH3%(   uH0[dff.     fUp   HH5+  S8   HMXHt1111HE1E1H1UHHH[H1]WfH`! H5k  H81Hff.     @ SHS`HtH! H1H[	fHʟ! 1H81fHfD  HHt3>_Ht0HH7! HP! 1H8Hef.     _Hj! 1H81HfD  USHHH-! Hu cjHt"   HpHC Ht9H[]H} HbHH}YHH5#  HH! H81GH(! H5  H81wG    USHHH-T! Hu iHt'H߾"   oH{ HtV#^Ht9H[]H} aHHXHH5  HH! H81FHF! 1H81FH{! H5  H81Ff.     ATHۛ! H5t  UH-ĝ! SHH} TL%! H} H5\  H֝! HI$TH! H5DHHRH;HZH5  ~eH=  ^H;E11ɺ   HMmH=  ^H;E11ɺ   H,mH=k  ^H;E11ɺ   HmH=E  _^H;E11ɺ   HlH=  >^H;E11Hƺ   lH;   HJH5k  dH;   HH5d  dH;   HtH5^  dH;   H	H5T  mdH;   HH5>  RdH;HH5+  7dI$H} H5"  3SHԘ! H55HHPH;HH5p  cH;   H`H5ս  cH;   HH5  cH;   HH5  cH;1HH5  cH;1HH5  ncH;1HRH5_  VcH;1[HY]H5  A\:cf.     HoHH UHSHHH|$Ht$qTHoHD$HpHxGNHH[]ff.     fHH|$Ht$)THD$HpHx'LHD$Hff.     fPX1HH! H81'C    SHHHt$tBeIHH|$SH|$~QHD$HxltH   [    XHyf     HH|$Ht$YSH|$QHD$Hx!ct
   H.ff.      UHSHt.H1HcRHxHOdtHH[]ÐkWfUHSHt.YH1HcMRHxHbtHH[]ÐWfHH|$Ht$iRH|$/PHD$Hxat
   H=ff.     fHH|$Ht$RH|$OHD$HHxZGt
   H    H! SH5q  H8JH&! H! H5[  HHH2OHS! H;   H5  HHB_H;   H.H5i  BDH;   HH5  _H;   HH5  DH;   HH5  _H;   HH5  CH;   HgH5  [_H;   HLH5  CH;   HH5  %_H;   HH5t  jCH;   H[H5f  ^H;   H@H5K  4CH;   HH5=  ^H;   HH5"  BH;   H/H5  ^H;   HH5  BH;1H,H5  P^H;1[HH5  B    AT"   USHgH[ H   ;we   yhHHC Hx9aH=޻  IJLHH>HC HxaH={  IpJLHH>HC Hx `H=c  IFJLHHh>HC Hx(`H=A  HJHHH>>H[]A\H! H5  H81RH! H5  H81=fD  ATUHSH"   HeHm H   HtiHULe HI|$(HtjHt/HH[]A\fHD$flHt$ID$(HE Hx(HuH! 1H81<=@ HE Hx(THE H@(    HH[]A\H! H5  H81Qff.     ATUHSH"   HeHm H   HtiHTLe HI|$ HtiHt/HH[]A\fHD$kHt$ID$ HE Hx HuH! 1H81\<@ HE Hx THE H@     HH[]A\H̓! H5%  H81Pff.     ATUHSH"   H4dHm H   HtiHSLe HI|$HthHt/HH[]A\fHD$jHt$ID$HE HxHuH! 1H81|;@ HE Hx;SHE H@    HH[]A\H! H5E  H81Off.     ATUHSH"   HTcHm H   HtiHSLe HI|$HthHt/HH[]A\fHD$iHt$ID$HE HxHuH ! 1H81:@ HE Hx[RHE H@    HH[]A\H! H5e  H81Off.     ATI"   USHxbH[ HtV;`uuHk L7RHIL^1HcbJHLHxH9x+HcHAKH[]A\Hr! H5˩  H81qNH! 1H819HG! H5u  H819fD  U"   SHHdH%(   HD$1aHk H   } `uzH} 1fHcH~T1IH} HHH@H$ex2H4$H+s9s|mHcHbJHHT$dH3%(   uJH[]H! 1H818Hn! H5  H818HV! H5  H81UMpTH    H5t  H=  GU"   SHH`H[ Hto;	_uKhHGRHHt#Hs HSHtH[]]DHM! 1H81	8H! H5  H817H! H5  H81Lf     U"   SHH_H[ Hto;Y^uKgHQHHt#Hs H;HtH[]]DH! 1H81Y7H! H5   H81A7Hڎ! H53  H81Kf     USHqV1҅tH! 1ɉ	7HHtH);tHH[] H1NFff.     AUI"   ATAHUSHH(dH%(   HD$1^Hk Hn  1HL$LD$LH  DK   H|$@t~HD$A   HtHǨ   <H|$A<DIH   L   H[   HL$dH3%(   H   H([]A\A]AHHD$d111HIGIHt5L=B AIfD  JH|$AQfD  11Ҿ   L7H=x! 1LH5! 'WLIAM)Hd! 1H81 5LDPH! H5  H81If     AUIATIU1SHOHt?L   HHZt=Hކ! 1HL9R1H5ݤ  HHOHH[]A\A]    H6HH[]A\A]f.     U"   SHH\Hk H   } Z   H} 2>Hu:HttHt_Hty   H{Ht&HHtH[] H! H8HuHICH! 1H813fD  H! H8@ HI! H8@ HA! H8@ H! H8uH
! H5c  H81	HH! H5   H81A3UHH  S   H(dH%(   HD$1HL$LD$8H   H|$@tDO9މHHtDHHHt4HT$dH3%(   ujH([]    GމHHuHBHÆ! 1H812    H|$@t8bGUNff.     @ PXH5  HH̉! H81"2fS"   HNZH[ Ht<;Xu+HS    Hz( t	[    1H    [HHb! H5  H81aFS"   HYH[ Ht ;>Xu,HC [Hx  HH! H5g  H81F     PXH5G  HH܈! H81EfS"   H^YHC HtH@ Hx(Ht[Sf   [@ S"   HYHC HtH@ Hx Ht[RSf   [d@ S"   HXHC HtH@ HxHt[Sf   [$@ S"   HXHC HtH@ HxHt[Rf   [@ U"   SHHYXHk Ht$} VuGH} :4t"HH[]H! H5ޟ  H81DH! H5  H81/HU! H5  H81/@ S"   HHdH%(   HD$1WH[ HtD;VuUH{ Ht$G1҅t|$H҃HL$dH3%(   HuH[HƆ! H5  H81CJff.     AUIATIUHSHX:HtI1DLH3I1Ҿ   HHC IH{ HCtHtHH[]A\A]H>H˂! 1H81.    SHtNH?UuzHh! H! H1H8K1H5  HHHHt3H[fD  9HtHH! H8H    H1! 1H81-Hބ! H5  H81-D  SH! H5  H.! HH;;H܁! H;H5  HHX! H;H! H5HH5  H1H;HH5	  LH;1HH5  pLH;1HH5  XLH;1H<H5ݝ  @LH;1HtH5͝  (LH;H  H5  b>H;H  H5  L>H;1H H5  KH;1H8H5  KH;1HH5  KH;1H8H5  KH;   HH5!  KH;1HH5j  iKH;   HH5]  NKH;1HRH5  6KH;   HH5  KH;1HH5  KH;   HH54  JH;1HlH5  JH;   HH5
  JH;1HyH5  JH! @   H=*! EH.!    H=r! HHH! #HĀ! H[    AU"   ATUSHH5SH[ H  BHICHH      L-  Bf        H=f  6HHH ,THL!T   AH{Hf6HHSH{R6HHSCt?vuH=  ,6f.     u+H=~  6of.     L5X H=  5D    HL[]A\A]Hc! H5  H81)fAWI"   AVAHAUATUSHH(dH%(   HD$1QHk H   Ld$Ll$LDMLH  1w>L9H|$u?1HD$1HHp2t\HL$dH3%(   HuDH([]A\A]A^A_@ L9HD$HtHPHx! H5   H81(DH3~! 1H81(ff.     @ AUE1ATUSHH  H(dH%(   HD$1Hl$Ld$IL=H|$tLHIE1H|$tHzHIH߾"   jPH{ Ht51LL4-Ht@H1HL$dH3%(   u#H([]A\A]H! H5-  H81'CH@}! 1H81'ff.     AUE1ATUSHH  H(dH%(   HD$1Hl$Ld$IL<H|$tLGIE1H|$tHGIH߾"   zOH{ HtO1LL(HtZH0   H5H  HHAHHL$dH3%(   u#H([]A\A]H{~! H5#  H81&BH6|! 1H81&fAUATIUSH=H.Ht8L-^y! H L1HL DHHPH}JHHuHH[]A\A]    H2   Hf     SHH  HdH%(   HD$1HH%;H<$tnH6H$   H5K  HPH t41HH=@  F   HL$dH3%(   u*H[     k.   @ M   ?Aff.     @ UHSHH\$Ht$H6   HHHD$HxS9HthHw! 1HHHBH_Du;H1t9L8z! H11Ҿ   Ur%HH[]     Hx$H'z! 1H81$ PXH5  HH,|! H81$fUHHSHt3*H"   LH} Ht4H   [] 9f.     PX1HHy! H81$    USHHH|$Ht$$DHHRHt;HCH߾"   KH{ Ht;]NHt*Hp6H[]H
y! HH5  H81~#YH{! H5  H81a#USHHH|$Ht$CHHRHt;H(H߾"   ]KH{ Ht;2Ht*H?H[]Hjx! HH5w  H81"Hrz! H5  H81"S"   HJH{ Ht't   [H.z! H5ּ  H81}"X     S"   HJH{ Ht B[HG.fS"   HnJH{ Ht)[H.rfATUHS NH<H=  I-LHH;BH5z  H,BHHHi3H5^  H
BH2HHG3HH5B  AH[]A\SHc-HtH?t! H1H[>4@ Hx! SH5  HH;u! H8{/HLv! Hv! H5ջ  HHHX/Hyv! H;H5wH-H;HH5  t$H;1HH5  \$H;1H H5y  D$H;   H5H5f  )$H.  HD  H+  HA  <I  HxH5T  )*H;1HH5  q?H;1HH5  Y?H;1HMH5  A?H;   HH5ɺ  &?H;   HH5  ?H;HH5  >H;HH5  >H;   HH5  >H;HH5v  >H;1HCH5g  >H;1H+H5  o>   UIH;H5;  HB   9IH;H5*  HwB   IH;H5  H[B   IH;H5  H?B@   HH;H5  H#B   HH;H5  HB  HH;H5ݹ  HA1HH;H5Ϲ  [HAH	s! H8H!u! H8Hr! H8Hr! H8Hys! H8AVIAUATUH	   SH!FH} ~6L%q! 1ېHE I4$L,    H<7@H   HH9]Ծ"   LEMn M   IE H5t! HxHHIE H} H@H    ~?1A HE H<;/LDHI7LtR.GHH9][H]A\A]A^I<$7HHE J<(.HH5u  HHs! H81FH%s! 1H81Hbt! H5c  H81U"   SHHdH%(   HD$1DHk Htx1HFHcH~S1,HHHH@H$F~2H4$H+s9s|UHcH-HHT$dH3%(   u2H[]Hdr! 1H81Hs! H5  H817H4     H5  H==  +ff.     ATUSHH  HdH%(   HD$1H0u&HH\$dH3%(      H[]A\fD  H<$Lc +'HH$_J11LHHIHtH'fD  11Ҿ   H7LH<(HI'MjHAq! 1H816PX1HH!q! H81    SH+HtHp! H1H[)8@ PXH5/  HHr! H81rfATUH"   SHBH[ Ht/H7,HߺHI4Lt(DH[]A\DH_p! 1H81 AU"   ATUSHH%BLc MtkLdŅxNHcIŅt+1D  L:HsJLH8C9uHL[]A\A]fD  H[]A\A]0ff.     USHHHAH߾"   H{AH{ H   HfE   tHH[] H!m! H8t3~8H@H=  H19H1H[]f     Hn!       H=  HH+8H3@H;   He  H1z@H;A[  1H9  Hn     W@_Ho! H5  H81Jf.     USHHH{6H߾"   H[@H{ HtHZx(H[]HHo! H5  H81f     ATUHSHHj@HI?8H߾"   H?H{ HtHL{ t H[]A\Ho! H5  H81gfUH"   SHH?H[ Ht!H5HHGt"HH[]Hn! H5  H81ff.     @ S"   H?H{ HtAHt!H[R H[n! H5\  H81D  UHSHHHdH%(   HD$1x"   HH$>HC Ht4H 1HH@ Hx9 Ht7HL$dH3%(   HuH[]Hm! H5ı  H811(     UHSHHHdH%(   HD$1"   HH$>HC Ht3H 1HH@ H8Ht7HL$dH3%(   HuH[]H$m! H5%  H81s>1f     S"   H=HC HtH H@ HxHt[8Hl! H5ɰ  H812fS"   H>=HC HtH H@ H8Ht[p8Hyl! H5z  H81 UH"   SHH<H[ Ht!H*HH9t"HH[]Hl! H5  H81dff.     @ S"   H~<H{ HtPHt!H[2Hk! H5  H81
%D  UH"   SHH&<H[ Ht!H)HH$t"HH[]HUk! H5V  H81ff.     @ S"   H;H{ Htp)Ht!H[1Hj! H5  H81JeD  UH"   SHHf;H[ Ht$HHHH)HCHH[]d@ S"   H;H{ Ht[H@2fATUHS>H8-H=D  ILHH2HH5h  2H5̛  H2HH?HH$HH5.  2H5  H2HHd?HH#HH5  j2H5  H[2HH+?HH#HH5  12H5  H"2HH>HHW#HH5  1H5  H1H!H>HH#HH5  []A\1ff.     U"   SHHy9Hk Ht:AH#+HHtUHE HH@H0H߅t#H[]6Hh! H5  H81yH"g! 1H81ATIUSHt=HHHx\L"   8I|$ Ht-H;tH[]A\    HH~Hg! H5  H81FHf! H5\  H81.ff.      S"   HN8HC HtH H85[H!:\ff.     U"   SHH	8Hk Ht2@H)HHtMHH@-H߅t#H[].5H'g! H5(  H81vHe! 1H81^yf     U"   SHHy7Hk Ht2?H#)HHtMHHpH߅t#H[]4Hf! H5  H81H*e! 1H81f     AUATUHSHH)H9tZ"   H6Lc MtRL-e! HIu 0HteH"   6H} Ht$Y>Ht2HC L8/HH[]A\A]He! H5ԩ  H81"Hkd! 1H81I} (HHHH5q  HHd! H81ff.     fHHt3=Ht0HHe! Hc! 1H8H*+f.     {Hc! 1H81vfD  USHH|$H|$H|$HD$H5k  Hx+HtC111HH2HH%HtIHkd! Hb! H1H8*H[][8H5X  HH#c! H81Hc! 1H81fD  USHHH-c! Hu /Ht"   H4HC Ht9H[]H} &HH-HH5~  HHAc! H81?Hc! H5٧  H81'    USHHH-lc! Hu .Ht@H߾"   14H[ Ht\H{Aj         H  (5HH[]H} E&HHzHH5 ~  HHb! H81H%c! H5&  H81t@ SH`! H5e  Hvb! HH;Ha! H;H5S  HHb! HxHb! H5ZHH?H;H@H5{  4*H;   H%H5=~  *H;1HH5{  *H;1HeH5{  )H;H{  H5{  #H;1HH5X{  )H;1HOH5  )H;   HH5  )H;1HH5  p)H;1H4H5  X)H;   HH5  =)H;1HaH59  %)H;   HH5&  
)H;1HnH5  (H;   HH5W  (H;1H{H5  (H;   HpH5Z  (H;1HH5  (H;   HH53  q(H;1H5H5  Y(H;   HH5  >(H;   HH5  #(H;   HH5z  (H;   HYH5  'H;1HH5  'H;   HH5  'H;   HH5  'H;1[HH5  'fD  HM\! H ÐHc1fHdH%(   HD$1HH$H<$~H$HT$dH3%(   uH#ATUSHLgHoH=  A H;M[HH]   1A\D  AVAUATUSH   H$ H   H$ HdH%(   H$   1IHIk1IH_  HIغ   M        Ho=  L-&[! IE Mtat]H'  L.H      HcL  HL/  LDH)޺   PHcH1ZYIE L-  H   .    ~>HH!сကt  DHPHD@ H)HcHL!H$   dH3%(   ufH   []A\A]A^    1HLH1	t%HuWf.        1H1L!ff.     SH1HfHHH#/$HuH[@ H}Y! SHHH0H9tHt@Ht
H[D  1i$   H-[!    H=  H	5H[@    6$   HZ!    H=l  H4H[ÐAVAUATUS   ,69   H   HAI    }H5O  IHH   EtQEMLE1MHc  HH7@2B HBDIL9uHcH  MtA,$[]A\A]A^    Ht)[]A\A]A^ýff.     @ HHH=?W! 'f.     HdH%(   HD$1Ht$D$    |$uHT$dH3%(   u
HT%Off.     @ AUATUSHHt}Hu&AąxNHc&IEt+1@ HHcLH,A9uHL[]A\A]D  HW! H8   H[]A\A]HV! A   H8uHX!       H=~  H2H	      H=O  2H;Av   1H1  Hx     a*Y@ HaX!       H=  H82H      H=  2H;Av   1H̞  H     )    AUATUSHHt}H%AąxNHcIEt+1@ H+HLHH+A9uHL[]A\A]D  HU! H8   H[]A\A]HU! A   H8uHVW!       H=  H-1H	      H=ߝ  1H;Aw   1H  H     (Y@ HV!       H=  H0H      H=  0H;Aw   1H\  H     (    ATIH=PUSHcHHdH%(   HD$1HT$D$    b$HHtHxHLL"|$uHL$dH3%(   HuH[]A\!@ AWAVAUIATAUSHHdH%(   HD$1D$    Ht>HDL
HL$dH3%(      H[]A\A]A^A_    tALt$D}MIALLH=;f#T$uNHPӃ~39HpHcLw DH=  1' D  H=  1 똻BAUATIUSLHHL-Q! dH%(   HD$81D$    Au +H   HHu(HL$8dH3%(      HH[]A\A]    H=T! HT$Lt"T$u:1҅H=Q! Ht$ HHl$ HHD$0HT$(HU! XHtZL*t.1q    Au I<$k.HRDD     LD$G
D$0fD  1L.
   ff.     @ H1dH%(   HD$1H7T! H01HH$)H$HL$dH3%(   uHff.     HS! SHH09%uH[H[     PXH   HT$0HL$8LD$@LL$Ht7)D$P)L$`)T$p)$   )$   )$   )$   )$   dH%(   HD$1H$   H$   HD$HD$ D$0   HD$H ff.      AV	   AUATIUS$" H   I|$ I~JL5S! 1D  HL(I6HHHt*HHfLHI9\$[L]A\A]A^H5Q! L&HP! H5  H81HP! 1H81ff.      H   HT$0HL$8LD$@LL$Ht7)D$P)L$`)T$p)$   )$   )$   )$   )$   dH%(   HD$1H$   H$   HD$HD$ D$0   HD$hHL$dH3%(   uH   ff.     USH+ H=  HN! H=  HH;H5  HH=w  rH;H5  H_! $H;H5x  HHEM! H;H5v  H{H-LO! 11E1H5f  1HE H,M!    HN! H;1HH5C  H     H;   HUH5'  H"Q! H;1H5  qH=j  %HFP! H#,WH''O&
U0H[]H} H5  1# H     AVIAUATUH	   SH1!H} ~6L%L! 1ېHE I4$L,    H<GH   HH9]Ծ"   L Mf M   I|$H5O! #H} ID$    ~21AHE H<S
DLHUtMHH9][H]A\A]A^I<$HHE J<(	HH5j  HHO! H81H5O! 1H81HO! H5  H81f     PX1HHN! H81    SH#
HtHL! H1H[@ UH"   SHHH[ Ht&HE	HHEt"HH[]HN! H5*  H81Jf.     AU"   ATUSHH5Lc M   LŅxRHcIŅt/1f     LcH{'LH@ 9uHL[]A\A]fD  HJ! H8tH[]A\A]@ HaL!       H=~  H8&H      H=K  &H;A   1H6  H~     HM! H5  H81fUHSHHHdH%(   HD$1"   HH$HC Ht-Hx1HHt7HL$dH3%(   HuH[]HM! H5t  H81i4ff.     @ PXH5H  HHL! H812fS"   H^HC Ht
Hx[fD  UH"   SHH&H[ HtH3HHHH[]pS"   HHC Ht	H8["G    HHtCHH5G! H=G! Ht/HH^K! HI! 1H8Hf     HjK! 1H81&fD  USHHH-K! Hu Ht5"   H1HS HtdH5!G! H=zF! Ht9H[]H} PHHHH5+f  HHJ! H81HJ! 1H81HK! H5w  H81lff.     SH|H! H5y  HfJ! HH;HlJ! H;H5c  HHJ! HhHJ! H5ZHH/H;HH5c  $H;1HH5h  H;   HH5  H;1HuH5z  H;   HH5ig  H;1HbH5u  H;   HGH5e  H;[   HH5U  of.     D  H     UHH{b  S1H(dH%(   HD$1HL$LD$H|$Ht@tj%H"   H} HttH>D! E1H|$ AE11Ht6u5   H\$dH3%(   uKH([]D      1HE! 1H819HH! H5l  H81!ff.     ATUSHH2f  HdH%(   HD$1HtmH߾"   H[ Hc  H{HH   HH߉HHT$dH3%(   H;  H[]A\f.     H<$@ufH߾"   H[ H      ~J
n   H	HHeHeD! 1H81[    ur1H"1HcI5 HHpHA9# HD`DI1AIcHHpH8A9fHA! H5  H81`HF! H5  H81H UHHed  S1HdH%(   HD$1HBt]H"   @H} Ht{HA! E11҉Ht%uI   H\$dH3%(   u_H[]@ 1@ H<$@tD  HB! 1H81|HF! H5  H81d/
ff.     @ AVIH  AUATUSH dH%(   HD$1HLL$LD$D      H|$E1H|$A@   AH<$A@utHH   DDHlt{H!B! 1HL$H\$dH3%(   urH []A\A]A^    E1E1H<$@t    AfD  H|$E1@tGHeHvA! 1H81ff.     fAVIH>  AUATUSH dH%(   HD$1HLL$LD$      H|$E1H|$A@   H<$A@utxHH   DDHt{H@! 1HL	H\$dH3%(   urH []A\A]A^    E1E1H<$@tk    KAfD  H|$E1@tGHH&@! 1H81ff.     fATUHH[  S
   H dH%(   HD$1Ld$LD$L    L""   HHE H$Hh  H}=! H|$H0H     ~I
   H  HD$HHp&tEfHL$dH3%(   H  H []A\Å	  HD$H$HpHxb
HuH>! 1H81f.     H|$@tuf     H|$"   HD$Hp HtwH<$zHQ    HD$HHp/mf.     [@ HD$H$HpHxJH/HuA! H5  H81H0<! H5  H81D  PX1HH=! H81    SHsHtH=! H1H[@ PXH5  HH@! H812fS"   H^HS HtJ1~H   H HE[ S"   HHS Ht%1zt[ H
H9uR1[H[ff.     S"   HHC Ht@[H U"   SHHH{ Ht4HHt?   
   H!HHHH[]H?! H5O  H81_ff.     @ S"   HH{ Ht[HHD rfS"   HH{ Ht[PHHHD 6fD  USHHHt;H߾"   H{ Ht,HtHH[]fD  {H>! H5U  H81
f.     USHHHt;FH߾"   H{ Ht,HdtHH[]fD  H;>! H5Մ  H81f.     ATI"   USHHk Ht5LAuHtH[]A\ H=! H5]  H81fUHHSHt;VH"   'H} Ht'H[]HD  bfATI"   USHHk Ht5LAuHtH[]A\ H<! H5  H81BfATI"   USHhHk Ht5LAuaHtH[]A\ SJH<! H5  H81fUHSHHukHu2H6! HH0 HtUHHH[]    tɋ?
t!tuH11KHfD  HHH4;! H5  H81+ff.     AT"   USHKLc M   HH   H~6! LHHH	   u3HtMHt8HtRt]H{H*8! [H1]A\,@ HQ8! H8@ Hi:! H8@ H!8! H8@ H8! H8@ H8! H8HH7! 1H811H:! H5d  H81f     AUATUSHHH   Nž"   HLk M   IH   LH   uGHtaHtLHtftqH{H7! HL1[]A\A] fx@ H7! H8@ H19! H8@ H6! H8@ H6! H8@ H7! H8LLH]6! 1H81H9! H5,  H81AUATUSHHH   ž"   H	Lk M   IH   LH$   uGHtaHtLHtftqH{H5! HL1[]A\A]fx@ H5! H8@ H8! H8@ H5! H8@ H5! H8@ HY6! H8LH*5! 1H81H_8! H5~  H81ff.      HHt3Ht0HH2! H4! 1H8Hf.     [H4! 1H81FfD  SH Hp2! H|$H3dH%(   HD$1HD$    H   H|$@u8HuH6! H5t  H81f@t?
tuH|$HD$H|$H*tuHt$HtNH4! H;1HD$HT$dH3%(   u@H [H|$"   HD$H@ HD$HuH6! H5q}  H81&Hr3! 1H81ff.      AUATUSHHH"   HILc M   HH   HJ1! LLHHH   u;HtUHt@HtZteH{H2! HH1[]A\A]fD  H3! H8@ H)5! H8@ H2! H8@ H2! H8@ H3! H8HDHU2! 1H81H5! H5$|  H81f     AWAVAUIHP  ATUSH8dH%(   HD$(1HL$HHD$(P1LL$(LD$ H|$^AX@   H|$E1H|$ AH   E1E1DHH   HLDE1j MHZYHtlH1! 1HLHT$(dH3%(   ucH8[]A\A]A^A_f+i@ H|$ E1IHmI`HH0! 1H81Yf     ATUHHSIeHt*LHHtH0! HH[1]A\HiHz0! 1H81fD  ATUHHSI
Ht*LHHtHW0! HH[1]A\V!HH
0! 1H81fD  USHHHH߾"   HH{ HtH*HH[]HD     USHHH[H߾"   HkH{ HtHzHH[]HD     HHHHÐAUATUSHHH"   HILc M   	HH   H*-! LLHH   u<HtVHtAHt[tfH{H.! HH1[]A\A]    H.! H8@ H	1! H8@ H.! H8@ H.! H8@ Ha/! H8H$H5.! 1H81Hj1! H5x  H81f     AVAUATUHSHHHI"   HILc M   iHH   H+! LLLHL    u5HtOHt:HtTt_H{H-! [H1]A\A]A^fH-! H8@ H/! H8@ H-! H8@ H-! H8@ H).! H8HH,! 1H81H20! H5v  H81AUATUSHHH"   HI Lc M   EHH   H*! LLHH   u<HtVHtAHt[tfH{Hs,! HH1[]A\A]o    H,! H8@ H.! H8@ Ha,! H8@ HY,! H8@ H-! H8HH+! 1H81qH
/! H5u  H81Yf     AUATUSHHHW"   HIgLc M   HH   H)! LLHH   u<HtVHtAHt[tfH{HC+! HH1[]A\A]?    Ha+! H8@ Hy-! H8@ H1+! H8@ H)+! H8@ H+! H8HH*! 1H81AH-! H5tt  H81)f     AVAUATUHSHH&HI"   HI+Lc M   HH   H^(! LLLHL R   u5HtOHt:HtTt_H{H*! [H1]A\A]A^fH)*! H8@ HA,! H8@ H)! H8@ H)! H8@ H*! H8H\Hm)! 1H81	H,! H5<s  H81AVAUATUHSHHHI"   HILc M   HH   H.'! LLLHL B   u5HtOHt:HtTt_H{H(! [H1]A\A]A^fH(! H8@ H+! H8@ H(! H8@ H(! H8@ Hi)! H8H,H=(! 1H81Hr+! H5r  H81AVAUATUHSHHHI"   HILc M   yHH   H%! LLLHL    u5HtOHt:HtTt_H{H'! [H1]A\A]A^fH'! H8@ H)! H8@ H'! H8@ H'! H8@ H9(! H8HH'! 1H81HB*! H5p  H81AUATUSHHH"   HILc M   UHH   H$! 1LLHL    u:HtTHt?HtYtdH{H&! HH1[]A\A]}D  H&! H8@ H(! H8@ Hq&! H8@ Hi&! H8@ H'! H8HH%! 1H81H)! H5o  H81if     AVAUATUSHHi"   HIyLk MH  ' IH$   HH>  H#! LLHLL    urH   H   H      L-5%! H{L1L4H{IHL1 [L]HA\   A]1A^FfD  H)%! L-$! H;L1LH;If.     H!'!     H$!     H$!     Hy%! L?H7HH$! 1H81H}'! H5n  H81L    AUATUSHHH"   HILc M   HH   H
"! LLHHa   u<HtVHtAHt[tfH{H#! HH1[]A\A]    H#! H8@ H%! H8@ H#! H8@ H#! H8@ HA$! H8HH#! 1H81HJ&! H5l  H81f     AUATUSHHH"   HILc M   UHH   LLH   u>HtXHtCHt]thH{H"! HH1[]A\A]f     H"! H8@ H$! H8@ Hy"! H8@ Hq"! H8@ H#! H8HH!! 1H81H"%! H5k  H81qAUATUSHHHw"   HILc M   5HH   LLH[   u>HtXHtCHt]thH{Hm!! HH1[]A\A]if     H!! H8@ H#! H8@ HY!! H8@ HQ!! H8@ H!! H8HH ! 1H81iH$! H5j  H81QATUHSH}H9t."   HkLc Mt H:LH?Ht H[]A\H#! H55j  H81ED  SHg! HHA  H! H ! H5Cj  H;HH! H;H5/j  HH"! HH! H5HHH;HH5<  H;   HH5>  qH;   HH5>  VH;1HJH5i  >H;1HH5i  &H;   HgH5i  H;   H,H5ji  H;   HH5vi  H;1HiH5Yi  H;   HH5i  H;   HH5i  H;   HxH5h  lH;   H-H5h  QH;   HH5h  6H;   HH5h  H;   HLH5h   H;   HH5h  H;   HH5uh  H;   H+H5_h  H;HPh  H5_\  H;   HH5-h  ~H;   H/H5G  cH;HG  H5h  H;HF  H5g  H;1HKH5g  H;1HH5g  H;1HH5g  H;HH5g  4H;H5H5g  H;   HZH5yg  H;   HH5Wg  H;HdH5Ng  H;HH5Bg  MH;   HH5.g  2H;   H3H5g  H;   HH5g  H;   H-H5f  H;   HH5;  H;   HgH5f  H;   H\H5f  H;   HH5f  uH;HH58  ZH;1HH5;  BH;H;  H5cf  |H;1HH5]E  H;   HH59e  H;   HH5f  H;[H~H5f  H! H5d  H81jf.     S1H=f  [   t1   u
H! H [D  H! [H ff.     S"   H>H{ Ht[HD f     1H=l     [ff.     AU"   ATUSHHH{  tH   []A\A]fH5^e  Hq"   IHI|$ HH   HC H57e  H8H LhL4L,LI} HAHz! HH0LH5L  HHH! 0LH5d  HHH>! 0LH5d  HHH! 0H   []A\A]HU! H5Td  H81lff.     ATUHSHH"   Hm HtGL%H! HI4$HtJ"   HRHs Ht~HquYH[]A\@ 1   H=j  H[]A\I<$\HHHH576  HH! H81Ht! H5c  H81H$! H57  H81s S"   HH{ HtP[Hcw    1H=7j  B   [ff.     U"   SHHIH[ Ht`HHHH! H8 uHH[]fD  H5J  H!HYHHHH[]@ 1H=i     HH[] UH   SHdH%(   HD$1=HHHJHHHH/HHHt$HHHcHt6Hct$HHt6HT$dH3%(   u
HH[]fD  S"   HH{ Ht [H'    1H=h     [ff.     AU"   ATUSHHH{ Ht|HHtWHgHcIIE~)1fHH[LHA9uHL[]A\A]D  HA   [L]A\A]@ 1H=g  A   HL[]A\A]ff.      U"   SHHH{ Ht@+HHt#HHH`HH[]fD     HH[]Ð1H=Gg     MHH[] ATUHSHH|$Ht$"   HEH5_  HH] HL`LH   HD$HHpHPH߉Ɖ4t_~u0I<$ofD  u$HcH[]A\ u޿ u0H9! H5v_  H81PI<$f 1aH=P_  H=f  H1#Ld$HH5^     HHL1
aD  AUATUHH&/  SH(dH%(   HD$1Ld$HL$MH|$@t[H|$Lct[LAH|$'H|$LuKHD$HL$dH3%(     H([]A\A]fH|$LcuL1HD$t"   HNH5]  HH] HLhLH   H   L%g  HD$HHpHPH߉Ɖ&  IcL>kuwHur-D  I} ?fD  I} 'fD  H|$HcHD$HH   fD  19f     I}  H=]  lH=c  H1Ll$HLd$H5\  ML   HH14Hf! H5\  H81}H     AWI׺   AVAUIATUHSHL5! I6"   HxH5\  HH] HL`L1HAՅ   HwtjuXHŋ    L    H߉D$[H#L$ILD Hw! H5b  H81莻fD  I<$O1HAՅgI6HHu^HH[]A\A]A^A_D  I<$p HDE L   IH! H5#b  H81HǨtM1ff.     @ SHH5d! H[HZ  <ff.     SHH5! H[HZ  ff.     Hu  11ff.     USHHt/  HdH%(   HD$1HTH߾"   WH<$Hk H   H! H0H   H=.  qH<$1H1H=.  uFQH<$1H1HHHHHL$dH3%(   u7H[]@ H<$1H1HH 1HH! H5Y  H81    UHSH"   HVHm t%HHH1ɾ*   (HH[]fD  HHff.     S"   HH{ 11Ҿ+   [H UHSH"   HHm t%HHH1ɾ,   HH[]fD  HHff.     S"   HnH{ 11Ҿ-   L[HC AT"   USH;Hk 11Ҿ   HHHH=@X  IWLHHHH11Ҿ   HHH=W  ILHHHH裷11Ҿ   HHH=W  ILHHHHe11Ҿ   HTHLH=W  ILHHHH'11Ҿ   HHH=W  I_LHHHH11Ҿ   HHH=5W  I!LHHHH諶11Ҿ   HHH=W  ILHHHHm11Ҿ   H\HTH=V  ILHHHH/11Ҿ   HHH=V  IgLHHHH11Ҿ   HHH=oV  I)LHHHH賵11Ҿ   HHH=>V  ILHHHHu11Ҿ   HdH\H=V  HHHHHH7H[]A\ff.     @ U	   SHH1HoH5T  HHtBH5U  HHHt*H=P  &HHHH[   1] H   []ff.     U	   SHH1HH5T  H HtBH5"U  HHHt*H=lP  HHHH[   1] H   []ff.     AT"   USHH4! H{ 0	H1H   H=O  Hٺ   HH1	   HH1HHI   HHHLH5AT  HHH54/  H   []A\ff.      UHcSHcHl-H\H8dH%(   HD$(1H?	! 0(HT$Ht$Hl$H=  HD$H\$ T$u;t7H|$H5S  vHH@ HL$(dH3%(   uH8[] 1'    ATIUHSHdH%(   HD$1H! 0HT$H=DHHT$uu1HL$dH3%(   uHH[]A\fH5R  HH9H5-  HI$H>HE    nff.      USHH<H߉RH3! Hǋ2HHH|! 0-HHމ[]ff.     fAV"   AUATUSHH?THHx H! 0_HtLLsLkHH=HM  L#oHMMHL   1HH	8bt[1]A\A]A^fH;HH5Q  [   ]A\A]A^ATUHSHHdH%(   HD$1Ho! D$    H8   H! H0DHHtqH=! H8=   A  H(Q  IH     WI\$    ȴHHHzLHoHT$HH=HD$dH3%(   uoH[]A\fL%!       H=Q7  I$oI$#      H=V  UI<$   1A  HjP  HC7  1    ATUHSHHdH%(   HD$1H! D$    H8   H^! Hߋ0DHø   H   H! H8Ax  HO     IH     Il$    oHHH!LHH=HT$HrHc|$H   HL$dH3%(      H[]A\@ L%!!       H=5  I$I$       H=U  I<$   1Ar  HN  H5  @ HHHf! H01Vjf.     AVIAUIATUHSHdH%(   HD$1Hv! D$    H8   H! H0IH      LHHHcLlHHH=HT$HHc|$HÅuQH-! HHu ^HtSHu H=H   "   HHC H   AE    LHH6! H01HL$dH3%(   uxH[]A\A]A^    L%I!       H=4  I$I$       H=S  I<$   1AD  HM  H3  H} nHH製HH5I  HH! H81赫HN! H5  H81蝫ff.     fAU"   ATUSHHHC HtsHhHt[H{HcI0IE~-1fD  H裭HLHA9uHL[]A\A]D  H[]A\A])H=L  A   D  SHHtH ! 0HtH[6fD  HC    H[ff.     @ AUATUHSHdH%(   HD$1uHtHE      "   HH5:J  HLe #H  H5LH ! HL0TH5AK  HH$Ht)H裹LHH     L0H5K  H製H$Ht&H=]3  -H<$I1L	  1HH5?1  H1bH$HtHHH5j%  H>H$HtKHIHt;Ht6HL  LLa  L  H5J  HڼH$HtvH  H  <  H?	  Hx ~61fD  HB H<LH   H$HH9ZH52J  HKH$H  ILH5J  HH H$H  H1H  @ H5J  H1H$HtHǨ  ELHIH5G  H赻H  H5I  H蚻H$Ht  HHL
H5I  HkH$Ht  HLH5uI  H=H$H  O  HH1ɾ    LRHzH5<I  HH$Ht$H蹷H$LHPHp  H5G  H辺H*  H5G  H裺H  H5H  H舺H      HL$dH3%(   H  H[]A\A]D  H5YLA4@ H5H  H)H$H1IL^HH	HHHLH=G       HhLHM[H  H5pG  H81譥D  H5!LiH  HHH-~        H=6-  HM THM !      H=M  :H}    1AL  HOF  H(-  H5LaH"  H8YH        H=,  HH      H=L  H;AH  1HE  H,         H5LYH  H8Hq        H=),  HHH      H=TL  /H;AD  1HJE  H#,     U    [!@ H5LQ3@ HH        ?fD  HMHزH1ɺ     L輳eRHS  H5D  H81jH;  H5D  H81RH#  H5D  H81:H  H5K  H81"fUSHHi  H(dH%(   HD$1HL$LD$   H|$H-  Hu OH   H|$   HT$H5B  H#HT$H5lB  H1H5D  HH|$11苵HHL$dH3%(   u8H([]ÐH=O  ԺH-  1H1H} MHHD$HH} 袼H|$HճHH5{  HH  H81    S"   HH{ Ht-11Ҿ   HtHu)   [D  1[@ 1H=H     [HT  H5C  H81kff.     S"   HH{  u1HtH[rfH=)H  12   [ff.     U"   SHH9Hk HtHH0H5)C  HHuH   []D  H=C  <HH5@  H芴H1H1諵H   []ff.     @ ATUHSH"   Le H-e  HHu Ht/"   HoHs HtKL莧[]A\HH} 蔺HHɱHH5o  HH  H81۟Ht  H5  H81ß UHSH"   HHH[ H1Ҿ   HH赯Ht
HH[]HG  1H81c UHSH>H&Ht11ɺ   !   HHZHHH[H81]頼H  H5qA  H81     SHHtH&H[]ff.     fAVAUATIUSHHt$Ht/H@u&@t
?$uHݥH     H|$覾HL-  1M    I>Ht1IuH  HH5@  H81f.     HcHATHHtǾ"   L/I|$ H"uHD$H[]A\A]A^H  H5R@  H81賝 AWLg%  IAVL5  AUM   ATL%3@  UHSHX|$H\$ dH%(   HD$H1MI       H1M    M   HH護M9uȋ|$1HL$LHG  >tHt$H=HL$HdH3%(   HuHX[]A\A]A^A_覸fD  ATUHSH"   Le H-  HHu !Ht/"   HHs HtKL[]A\HH} HH)HH5  HH=  H81;H  H5M  H81# AUATIUSHHdH%(   HD$17H  H   H      ?	   11L-;  1H{ H$    HH9   HHu/Ht)Ht$HtHt<t?	u
1HH]H<$HHCHPH9~H<$LxHCfHH$īL"   7I|$ HtLH$Hp0t#HL$dH3%(   HuH[]A\A]艶H  H5]=  H81衚Hr  H5;  H81艚f     AWH=>=  AVAUATL%n  UM$   SHH  11E1H5=  H1脭H  11E1H5=  1fH  11E1H5=  1HHa  11E1H5[B  1*HS  11E1H5]B  1H  H56  H  H8蝢H  H-  H56  HHHE ɧHJ  HL5  H} H5o<  I蠧H)  H5HHgH=       I<$I諱H;E1      H3M9uH;H:  H5<  xH;H)H5	  H;   HH5;  H;1HH5  ڷH;   HkH5;  迷H;1HH5;  觷H;   H5;  ӻH;   H5;  迻H;   H5;  諻H;   H5;  藻H;  H5;  胻H;  H5@  oH;  H5@  [H;  H5;  GH;   HH5;  H;   H-H5q;  ѶH;1HEH5h;  蹶H;   HH5`;  螶H;1HH5\;  膶H;   HH5T;  kH;1HH5P;  SH;HH5I;  8   ΛL=  IM   D  I?I\LHHHYM9uLH;LH5:  IH} H5:  פH   H5	HH螢H=O6  H;E11ɺ   H}H=6  ѮH;E11ɺ   H\H=v8  谮H;E1   Hƺ   8H;H5  H5d:  肧H;HH5  H;1H+H56  H;1HH55  H;HH55  ̴H;   HMH55  豴H;1HUH59  虴H;1HH5
  聴H;1HH59  iH;1HH59  QH;1H5H5/  9H;1HH57  !H;1HeH5d9  	H;1HH5T9  H;   HBH5I9  ֳH;1HzH5:9  辳H}    H539  H}    H5*9  ԷH}    H5!9  迷H} 	   H5(9  誷H}    H5&9  蕷H}    H5*9  耷H}    H5<  kH}    H5=  VH} A   H59  AH}    H59  ,H}   H59  H}   H59  H}   H59  H}   H5<  ضH} H59  H     辶H}   H5<  詶H}   H58  蔶H}    H58  H}    H58  jH}   H58  UH}   H58  @H}   H58  +H}   H58  H}   H58  H}   H58  H}    H58  ׵H}    H58  µH}   @H58  譵H} H  [H5;  ]A\A]A^A_銵f.     USHH|$Ht@u@t
?t2H|$舢HD$HpHx膧HtoH[]f.     [HXH菼H臭H;OHŅxJH5$  THHt-   H?HuH"Hc  1H81/H1QH1Ҿs   dH%(   HD$1HH$HxH0IHT$dH3%(   uH蟬ff.     @ HHH=  麴f.     HHH=?  隴f.     USHHdH%(   HD$1Ht$D$    aHH|$uHT$dH3%(   HuH[]  HH           PKEY wasn't initialized! THIS IS NOT A RSA! q dmp1 dmq1 iqmp private private key needed. 11 ossl_pkey_rsa.c newlen <= len 02 Neither PUB key nor PRIV key: Not a RSA key! RSAError generate initialize public? private? to_text export to_pem to_s to_der public_encrypt public_decrypt private_encrypt private_decrypt q= dmp1= dmq1= iqmp= params PKCS1_PADDING SSLV23_PADDING NO_PADDING PKCS1_OAEP_PADDING  ossl_rsa_to_der %s#<< is deprecated; use %s#update instead      salt must be an 8-octet string  argumtents for %s#encrypt and %s#decrypt were deprecated; use %s#pkcs5_keyivgen to derive key and IV    unsupported cipher algorithm (%s)       wrong argument (%s)! (Expected kind of %s) data must not be empty Cipher not inititalized! ossl_cipher.c out_len < RSTRING_LEN(str) 13 iv length too short key length too short out_len <= RSTRING_LEN(str) Cipher CipherError initialize_copy ciphers reset pkcs5_keyivgen << final key_len= key_len iv= iv_len block_size padding=            ossl_cipher_update              ossl_cipher_final               OpenSSL for RubySSL Session wasn't initialized. SSL Session already initialized BIO_s_mem() SSL_SESSION_print() no session available unknown type i2d_SSL_SESSION i2d_SSL_SESSION too large to_i Session SessionError time= timeout= 21 Response wasn't initialized! 22 Cert ID wasn't initialized! 01 ossl_ocsp.c Request wasn't initialized! OCSP OCSPError Request add_nonce check_nonce add_certid create status_string basic BasicResponse copy_nonce add_status CertificateId cmp_issuer serial RESPONSE_STATUS_SUCCESSFUL RESPONSE_STATUS_INTERNALERROR RESPONSE_STATUS_TRYLATER RESPONSE_STATUS_SIGREQUIRED RESPONSE_STATUS_UNAUTHORIZED REVOKED_STATUS_NOSTATUS REVOKED_STATUS_UNSPECIFIED REVOKED_STATUS_KEYCOMPROMISE REVOKED_STATUS_CACOMPROMISE REVOKED_STATUS_SUPERSEDED REVOKED_STATUS_REMOVEFROMCRL NOCERTS NOINTERN NOSIGS NOCHAIN NOVERIFY NOEXPLICIT NOCASIGN NODELEGATED NOCHECKS TRUSTOTHER NOTIME V_CERTSTATUS_GOOD V_CERTSTATUS_REVOKED V_CERTSTATUS_UNKNOWN V_RESPID_NAME V_RESPID_KEY  cannot load DER encoded response        cannot load DER encoded request RESPONSE_STATUS_MALFORMEDREQUEST        REVOKED_STATUS_AFFILIATIONCHANGED       REVOKED_STATUS_CESSATIONOFOPERATION     REVOKED_STATUS_CERTIFICATEHOLD  ossl_ocspreq_to_der             ossl_ocspres_to_der ATTR wasn't initialized! ossl_x509attr.c decode could not get ASN1_TYPE oid= value= AttributeError Attribute oid    couldn't set SEQUENCE for attribute value.              ossl_x509attr_get_value @group EC_POINT is not initialized EC_GROUP is not initialized EC_POINT_point2bn EC_POINT_set_to_infinity EC_POINT_invert EC_POINT_make_affine EC_POINT_is_on_curve EC_POINT_is_at_infinity EC_POINT_dup EC_POINT already initialized unknown type for 2nd arg wrong number of arguments BIO_new(BIO_s_mem()) EC_GROUP_set_generator EC_GROUP_new EC_GROUP_dup unknown curve name (%s) unable to create curve (%s) EC_GROUP_new_by_GF* THIS IS NOT A EC PKEY! EC_KEY is not initialized EC_KEY_print outlen=%d ECDSA_verify Private EC key needed! ECDSA_sign ECDH_compute_key EC_KEY_set_public_key EC_KEY_set_private_key @key EC_KEY_set_group EC_KEY already initialized unknown curve name (%s)
 unable to create curve (%s)
 EVP_PKEY_assign_EC_KEY group= EC_get_builtin_curves clone EC_GROUP_set_seed EC_GROUP_get_cofactor EC_GROUP_get_order EC_KEY_check_key EC_KEY_generate_key Not a EC key! ECError EC Group Point GFp GF2m GFp_simple GFp_mont GFp_nist GF2m_simple uncompressed hybrid NAMED_CURVE private_key= public_key= private_key? public_key? dh_compute_key dsa_sign_asn1 dsa_verify_asn1 eql? curve_name asn1_flag asn1_flag= point_conversion_form point_conversion_form= seed= degree infinity? on_curve? make_affine! invert! set_to_infinity! to_bn       missing ossl_ec_point structure missing ossl_ec_group structure wrong argument type: must be OpenSSL::PKey::EC::Point or OpenSSL::Pkey::EC::Group       1st argument must be OpenSSL::PKey::EC::Group   missing group (internal error)  EC_GROUP is already initialized unknown symbol, must be :GFp_simple, :GFp_mont, :GFp_nist or :GF2m_simple       unknown symbol, must be :GFp or :GF2m   unknown argument, must be :GFp or :GF2m can't export - no public key set        can't export - EC_KEY_check_key failed  EC_KEY_get0_get0_group (has public_key but no group???  unsupported point conversion form: %d, this module should be updated    form must be :compressed, :uncompressed, or :hybrid Digest initialization failed. EVP_MD_CTX_create() failed openssl Digest::Class Digest DigestError finish digest_length block_length Digest CTX wasn't initialized!  Unsupported digest algorithm (%s). X509 V_OK V_ERR_UNABLE_TO_GET_CRL V_ERR_CERT_SIGNATURE_FAILURE V_ERR_CRL_SIGNATURE_FAILURE V_ERR_CERT_NOT_YET_VALID V_ERR_CERT_HAS_EXPIRED V_ERR_CRL_NOT_YET_VALID V_ERR_CRL_HAS_EXPIRED V_ERR_OUT_OF_MEM V_ERR_CERT_CHAIN_TOO_LONG V_ERR_CERT_REVOKED V_ERR_INVALID_CA V_ERR_PATH_LENGTH_EXCEEDED V_ERR_INVALID_PURPOSE V_ERR_CERT_UNTRUSTED V_ERR_CERT_REJECTED V_ERR_SUBJECT_ISSUER_MISMATCH V_ERR_AKID_SKID_MISMATCH V_ERR_KEYUSAGE_NO_CERTSIGN V_FLAG_CRL_CHECK V_FLAG_CRL_CHECK_ALL PURPOSE_SSL_CLIENT PURPOSE_SSL_SERVER PURPOSE_NS_SSL_SERVER PURPOSE_SMIME_SIGN PURPOSE_SMIME_ENCRYPT PURPOSE_CRL_SIGN PURPOSE_ANY PURPOSE_OCSP_HELPER TRUST_COMPAT TRUST_SSL_CLIENT TRUST_SSL_SERVER TRUST_EMAIL TRUST_OBJECT_SIGN TRUST_OCSP_SIGN TRUST_OCSP_REQUEST DEFAULT_CERT_AREA DEFAULT_CERT_DIR DEFAULT_CERT_FILE DEFAULT_CERT_DIR_ENV DEFAULT_CERT_FILE_ENV DEFAULT_PRIVATE_DIR  V_ERR_UNABLE_TO_GET_ISSUER_CERT V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE  V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE   V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY        V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD    V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD     V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD    V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD    V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT       V_ERR_SELF_SIGNED_CERT_IN_CHAIN V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE   V_ERR_AKID_ISSUER_SERIAL_MISMATCH       V_ERR_APPLICATION_VERIFICATION @time STORE_CTX is out of scope! STORE wasn't initialized! @verify_callback @cert OSSL_DEBUG:  certs in chain < 0??? ossl_x509store.c  [%s:%d]
 @error @error_string @chain STORE_CTX wasn't initialized! StoreError Store verify_callback= flags= purpose= trust= add_path add_file set_default_paths add_cert add_crl StoreContext error= error_depth current_cert current_crl cleanup Req wasn't initialized! ossl_x509req.c count < 0??? version must be >= 0! RequestError version subject subject= signature_algorithm attributes attributes= add_attribute        ossl_x509req_to_der @value each value is too short @unused_bits %2d%2d%2d%2d%2d%2dZ bad UTCTIME format %4d%2d%2d%2d%2d%2dZ bad GENERALIZEDTIME format unknown time format utc ASN1_INTEGER is NULL! @tag_class invalid tag class @tag tag number not specified ossl_asn1.c @tagging invalid tag default must specify tag number invalid OBJECT ID nil expected unsupported ASN.1 type ASN1_TYPE alloc failure cannot alloc buffer reallen <= len EOC UNIVERSAL CONTEXT_SPECIFIC APPLICATION PRIVATE IMPLICIT ASN1 ASN1Error traverse decode_all UNIVERSAL_TAG_NAME ASN1Data Primitive Constructive Boolean Integer Enumerated BitString OctetString UTF8String NumericString PrintableString T61String VideotexString IA5String GraphicString ISO64String GeneralString UniversalString BMPString Null ObjectId UTCTime GeneralizedTime Sequence Set register sn ln short_name long_name BOOLEAN INTEGER BIT_STRING OCTET_STRING NULL OBJECT OBJECT_DESCRIPTOR EXTERNAL REAL ENUMERATED EMBEDDED_PDV UTF8STRING RELATIVE_OID [UNIVERSAL 14] [UNIVERSAL 15] SEQUENCE SET NUMERICSTRING PRINTABLESTRING T61STRING VIDEOTEXSTRING IA5STRING UTCTIME GENERALIZEDTIME GRAPHICSTRING ISO64STRING GENERALSTRING UNIVERSALSTRING CHARACTER_STRING BMPSTRING             z}}0~z~zzzz~zzzzzzzzzzzz'}'}F<LFFFFLFFF̐̐LLLLLLLLLFLossl_asn1data_to_der            ossl_asn1prim_to_der            ossl_asn1cons_to_der    universal tag for %s not found  tag number for Universal too large ossl_hmac.c Allocating %d mem HMAC wasn't initialized Memory alloc error Cannot convert buf to hexbuf HMACError hexdigest inspect    Cannot allocate memory for hmac CRL wasn't initialized! ossl_x509crl.c num < 0??? CRLError issuer= last_update last_update= next_update next_update= revoked= add_revoked extensions extensions= add_extension Private key is needed. ossl_pkey.c unsupported key type PKey PKeyError   (long)buf_len <= RSTRING_LEN(str)       OpenSSL::PKey::PKey is an abstract class.       Cannot make new key from NULL.  ossl_pkey_sign SPKI wasn't initialized! ossl_ns_spki.c Challenge.length <= 0? Netscape SPKIError SPKI challenge challenge=      ossl_spki_to_der Name wasn't initialized. ossl_x509name.c name entries < 0! OBJECT_TYPE_TEMPLATE DEFAULT_OBJECT_TYPE [] NameError add_entry to_a <=> hash hash_old countryName serialNumber dnQualifier DC domainComponent emailAddress RFC2253 ONELINE MULTILINE               ossl_x509name_to_der wrong config format error in line %d ConfigError Config DEFAULT_CONFIG_FILE PKCS12 wasn't initialized. ossl_pkcs12.c PKCS12_parse @certificate @ca_certs 46 Unknown PBE algorithm %s PKCS12 PKCS12Error    ossl_pkcs12_to_der PKCS7 wasn't initialized. ossl_pkcs7.c @data signed encrypted enveloped signedAndEnveloped Negative number of recipient! Negative number of signers! 32 PKCS7ri wasn't initialized. PKCS7si wasn't initialized. Could not add recipient. Could not add signer. must specify a boolean unknown type "%s" PKCS7 PKCS7Error read_smime write_smime type= detached= detached detached? cipher= add_signer signers add_recipient recipients add_certificate certificates= certificates crls= crls add_data data= SignerInfo Signer signed_time RecipientInfo enc_key TEXT DETACHED BINARY NOATTR NOSMIMECAP       OpenSSL::PKCS7#get_signer_info == NULL!         ossl_pkcs7_to_der THIS IS NOT A DSA! pub_key priv_key Private DSA key needed! ossl_pkey_dsa.c DSA PUBLIC KEY Not a DSA key! DSAError syssign sysverify pub_key= priv_key=       ossl_dsa_to_der PKCS5_PBKDF2_HMAC_SHA1 PKCS5_PBKDF2_HMAC PKCS5 PKCS5Error pbkdf2_hmac pbkdf2_hmac_sha1 EXT wasn't initialized! ossl_x509ext.c malloc error critical= critical, unknown OID `%s' @config %s = %s @crl @subject_request @subject_certificate @issuer_certificate 04 CTX wasn't allocated! ExtensionError ExtensionFactory issuer_certificate= subject_certificate= subject_request= crl= config= create_ext Extension critical?   ossl_x509ext_to_der Random RandomError random_add load_random_file write_random_file random_bytes pseudo_bytes egd egd_bytes status? THIS IS NOT A DH! ossl_pkey_dh.c Failed to generate key Not a DH key! DHError params_ok? generate_key!     ossl_dh_to_der ENGINE wasn't initialized. NUMERIC NO_INPUT no such digest `%s' no such cipher `%s' #<  id=" " name=" "> Engine EngineError load engines by_id cipher load_private_key load_public_key set_default ctrl_cmd cmds METHOD_RSA METHOD_DSA METHOD_DH METHOD_RAND METHOD_CIPHERS METHOD_DIGESTS METHOD_ALL METHOD_NONE        no such builtin loader for `%s' CERT wasn't initialized! ossl_x509cert.c Check private key:%s ,  serial= not_before= not_after= CertificateError Certificate not_before not_after check_private_key     ossl_x509_to_der call %s%s error on stack: %s OSSL_DEBUG: IS NOW ON!
 OSSL_DEBUG: IS NOW OFF!
 ossl.c empty sk! items in sk < -1??? object not X509 cert in array OpenSSL 1.0.0 OpenSSL 1.0.2u  20 Dec 2019 OPENSSL_VERSION OPENSSL_VERSION_NUMBER OpenSSLError ossl_verify_cb_idx debug debug= errors  password must be longer than 4 bytes    password must be shorter then %d bytes  X509_STORE_CTX_get_ex_new_index         0123456789abcdef REV wasn't initialized! ossl_x509revoked.c RevokedError Revoked BN wasn't initialized! invalid radix %d Don't know how to coerce Cannot init BN_CTX BNError BN num_bytes num_bits + - / % mod_add mod_sub mod_mul mod_sqr ** mod_exp gcd ucmp === zero? one? odd? pseudo_rand pseudo_rand_range generate_prime prime? set_bit! clear_bit! bit_set? mask_bits! >> lshift! rshift! to_int mod_inverse prime_fasttest?    Cannot convert into OpenSSL::BN using default DH parameters. @context SSL_new: @io @client_cert_cb @tmp_dh_callback SSL_set_session SSL_write: syswrite SSL_read: sysread SSL_accept SSL_connect arg must be Time or nil cache_num connect_good connect_renegotiate accept_good accept_renegotiate cache_hits cb_hits cache_misses cache_full timeouts @session_new_cb @session_get_cb @x509 @tmp_dh ossl_ssl.c SSL_CTX is not initialized. @cert_store @extra_chain_cert SSL_CTX_use_certificate: SSL_CTX_use_PrivateKey: SSL_CTX_check_private_key: @client_ca SSL_CTX_add_client_CA @ca_file @ca_path can't set verify locations @verify_mode @timeout @verify_depth @options @session_id_context @session_remove_cb @sync_close SSL_session_reused SSL_CTX_new: unknown SSL method `%s'. SSL_CTX_set_ssl_version: @%s SSL_CTX_set_cipher_list: @callback_state ossl_ssl_ex_vcb_idx ossl_ssl_ex_store_p ossl_ssl_ex_ptr_idx SSLContext ssl_timeout ssl_version= ciphers= setup SESSION_CACHE_OFF SESSION_CACHE_CLIENT SESSION_CACHE_SERVER SESSION_CACHE_BOTH SESSION_CACHE_NO_AUTO_CLEAR SESSION_CACHE_NO_INTERNAL session_add session_remove session_cache_mode session_cache_mode= session_cache_size session_cache_size= session_cache_stats flush_sessions METHODS SSLSocket to_io sysclose peer_cert peer_cert_chain pending session_reused? session= verify_result VERIFY_NONE VERIFY_PEER VERIFY_FAIL_IF_NO_PEER_CERT VERIFY_CLIENT_ONCE OP_MICROSOFT_SESS_ID_BUG OP_NETSCAPE_CHALLENGE_BUG OP_MICROSOFT_BIG_SSLV3_BUFFER OP_MSIE_SSLV2_RSA_PADDING OP_SSLEAY_080_CLIENT_DH_BUG OP_TLS_D5_BUG OP_TLS_BLOCK_PADDING_BUG OP_ALL OP_SINGLE_ECDH_USE OP_SINGLE_DH_USE OP_EPHEMERAL_RSA OP_CIPHER_SERVER_PREFERENCE OP_TLS_ROLLBACK_BUG OP_NO_SSLv2 OP_NO_SSLv3 OP_NO_TLSv1 OP_NO_TICKET OP_PKCS1_CHECK_1 OP_PKCS1_CHECK_2 OP_NETSCAPE_CA_DN_BUG TLSv1_server TLSv1_client SSLv2_server SSLv2_client SSLv3_server SSLv3_client SSLv23 SSLv23_server SSLv23_client SSL session is not started yet. %s SYSCALL returned=%d errno=%d state=%s        %s returned=%d errno=%d state=%s        SSL SESSION remove callback entered     SSL SESSION new callback entered        SSL SESSION get callback entered        SSL_CTX_set_session_id_context: SSL SESSION get callback added  SSL SESSION new callback added  SSL SESSION remove callback added       ossl_ssl_ex_client_cert_cb_idx  ossl_ssl_ex_tmp_dh_callback_idx SESSION_CACHE_NO_INTERNAL_LOOKUP        SESSION_CACHE_NO_INTERNAL_STORE OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG     OP_SSLREF2_REUSE_CERT_TYPE_BUG  OP_DONT_INSERT_EMPTY_FRAGMENTS  OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION       OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG      Ș;h    T$  U    ԉ  8  |  t  T  4H      Ԑ  P  4    Ԗ  8    D  $  <  Ԟh        $  d(  L  p  $  d      ,  L  tl    T  ԩ  h    4  T      d   <  ĭX  t      t  $   d0   D\   D   T   d   !  P!  |!  !  T!  D!  4$"  T"  "  4"  "  4"  #  Խ #  L#  p#  Ŀ#  $#  4#  D#  T#  d4$  $  D$  8%  dd%  T%  D%  T%  P&  &  &  $&  t'  H'  t'  '  '  '  '  (  d8(  T(  p(  (  (  T(  )  D)  tp)  )  )  )   *  4*  Td*  *  D*  *  $(+  D+  4p+  4+  +  ,  d@,  |,  ,  d,  4-  x-  -  -  -  -  (.  <.  P.  $.  .  /  l/  D/  4/  /  0  $0  P0  t|0  0  t	0  d
1  dP1  d1  1  (2  DX2  t2  2  d2  2  d2  43  |3  T3  3  3  4  d@4  \4  x4  d4  4  4  $4  5  L5  D%5  $&5  &5  & 6  '6  d'@6  '\6  'x6  $(6  )6  )7  *<7  d+h7  ,7  17  27  $27  D27  2$8  4h8  48  T58  58  59  $6,9  T6H9  6d9  69  69  T79  8(:  9\:  T::  t::  ::  ;:  ;;  ;4;  <d;  4=;  T=;  =;  ><  t>4<  >`<  t?<  ?<  ?<  t@<  $A=  dA=  AH=  Et=  F=  G=  H>  I8>  Jd>  dK>  K>  K>  $L>  DML?  Mx?  4N?  N?  N?  dO(@  OD@  4Pp@  P@  tQ@  Q@  dRA  S<A  DU\A  UA  DVA  VA  VA  WB  DWDB  WlB  WB  XB  DXB  XC  X4C  Y\C  DYC  YC  YC  ZC  DZ$D  ZLD  ZtD  [D  D[D  [D  [E  [0E  D\XE  \xE  dE  dE  Te F  eF  g\F  dhF  hF  jF  4kG  lTG  4nG  tpG  pG  dq H  q<H  rxH  rH  sH  DsH  vI  dxPI  I  ĂI  I  DJ  4J  TJ  ԅJ  J  dK  Ć<K  XK  ćK  4K  K  $L  PL  Č|L  L  L  ďM  HM  ĐdM  M  M  M  N  DN  N  N  4N  ԕ(O  tTO  pO  ԖO  DO  tO   P  TP  DXP  ԙP  P  P  P   Q  TQ  4pQ  Q  Q  Q  4R  Ģ@R  lR  4R  $R  $R  S  <S  XS  |S  tS  S  tT  4T  4PT  lT  TT  T  T   U  PU  $U  U  $ V  44V  tPV  ĶlV  tV  V  TV  V  W  0W  lW  W  tW  dW  D4X  X  TX  tX  d Y  dY  Y   Z  PZ  Z  Z  $[  $l[  [  [  $\  T0\  L\  h\  \  $\  \  \  4]  H]  d]  ]  ]  ]  ]  t^  8^  $d^  D|^  ^  ^  ^  $^  4,_  h_  _  T_  _  $_  D`  t`  `  t`  `  a  La  a  a  b  \b  tb  Db  b  $c  d|c  c  c  $$d  pd  d  Td   e  e  T@e  de  e  e  Te  e  tf   ,f   tf  f  tf  dg  Pg  $dg  Dg  g  h  4	Hh  T	dh  	h  	h  t
h  
h  
(i  DTi  i  i  4i  j  4j  Pj  $lj  j  dj  4j  Tk  4k  Lk  hk  tk  k  k  d l  l  8l  4Tl  Tl  4l  m  Pm  m  m  m  Tn  Hn  dtn  4!n  !n  "(o  #To  $po  t$o  $o  $o  4%o  t%p  %8p  %\p  &p  $'p  'p  T(q  +$q  t,`q  -q  t.q  t/$r  /\r  0tr  0r  1r  1r  2s  $2(s  2Ts  d3s  3s  3s  4s  4 t  4t  $8<t  t9|t  d:t  D;t  d;t  ;u  ;0u  $<\u  <u  =u  T>v  >@v  4?lv  ?v  $@v  @v  Av  dAw  ADw  $B`w  Bw  Bw  4Cw  dCw  Dx  dEHx  Ftx  DFx  Fx  dGx  TH$y  H@y  tIly  Jy  Jy  My  My  Nz  TN(z  NTz  tPz  Pz  DQz  4RH{  TR\{  Rx{  $T{  U|  $VL|  4W|  X|  X|  Y}  Y,}  Zl}  T[}  ]}  ]}  T^~  t^$~  ^@~  _l~  4`~  `~  `  $a   daL  ah  b  b  d  d  e  f@  gl  $i  tj  l(  lD  l`  l|  4m  m  m؁  4n  dn   n<  $oh  o  p  tp  p  TqD  rp  s  Dt܃  u  u4  $wX  Tx  y  z(  zT  z  ${  D{ą  t|   }@  ~|    4  d8  x  Ą  d  0  l  ԉ  DԈ  ď    d4  đ         TL  l  tȊ    D<  x  Tċ      ԛ  <  Th      ̌  4  ġ,  T`  $  ԣ      `    Ȏ    D\  |    D  Ĵ  ,  `  d  Ķ  4  d  tH  T  đ     $L  x  d             zR x  $      1   FJw ?:*3$"       D    ?p1          ,   \   8q   FFA 
ABA  @      r    FAD L0
 DABCU
 DABA  @      ts    FAD L0
 DABCU
 DABA  @     t    FAD L0
 DABCU
 DABA  @   X  t    FAD L0
 DABCU
 DABA  @     Hu    FAD L0
 DABCU
 DABA  @     u    FAD L0
 DABCU
 DABA  @   $  v    FAD L0
 DABCU
 DABA  @   h  w    FAD L0
 DABCU
 DABA  8     w   FJD F(DP
(A ABBG 8     ,y   FJD F(DP
(A ABBG 8   $  zI   FJA D(IP
(A ABBE 8   `  {I   FJA D(IP
(A ABBE 0     |7   FFA G0
 AABA D     }|   FJG A(GPXN`LXAPK
(A ABBB(         EFG H
AAE @   D     FJH A(A0GP<
0A(A BBBKH     ,    BED C(D0M
(D ABBHL(D ABB  (     p   EFG h
AAD 4      d    EID p
FAG^
AAA     8  ܃    AAK      T  <    Ed
GF
A      x  <    Ed
GF
A        <    Ed
GF
A        4<    Ed
GF
A        P<    Ed
GF
A        l<    Ed
GF
A      ,  <    Ed
GF
A      P  <    Ed
GF
A  0   t      FKF D@
 AABE      ^    Eh
A     Ѕ    EL
G        `   E     $      q    EID YDA$   ,  XX    EDG qJH 8   T  x   FBA K(DP
(A ABBG l     ԋ   FBB E(A0K8GaLMDRPCX
8A0A(B BBBC         t&    E`             EZ      8      AAF     T  V    Es
A   p  ԍ!    JL  (     v    FGA v
ABI     <    AAK       @6    Ed
H     d6    Ed
H(   	      EAG0h
AAA    8	  6    Ed
H(   T	  0v    FGA v
ABI(   	      EAG0i
AAA    	  =    Ek
H(   	  ,    EFG0r
AAA X   	     BBB E(A0A8QVPDy
8A0A(B BBBD   P
            d
         0   x
  |    FAA G0V
 DABA 8   
      FBA D(G0_
(D ABBA (   
      EAG o
AAE  ,          MDA J
ABA      D  `3   L     (   d      EFG0
AAA (     D    EFG0
AAA ,         FAI h
ABA   ,        FAA Y
ABD               (   0      EG L@LPo
AA   \  H    AAK      x  Lm    EL P
AA      .    E\
H(         FAI 
ABN      @l    E@
[F
A (         FAI 
ABN   4   [   L<        T  `          h  \          |  X       8     T	   FBA K(FP
(A ABBF T     (h   FBB B(A0C8NpYxFRxAp
8A0A(B BBBFL   $  @p   FGB B(A0A8G
8A0A(B BBBA   X   t  `@   FBE E(G0D8DpxH[xAp
8A0A(B BBBH (     D    EAN0l
AAF (         EFG0
AAA (   (      EFG0
AAA 8   T     FBA K(FP
(A ABBA T     Tj   FBB B(D0A8NpYxFRxAp
8A0A(B BBBEL     l    FGA A(G0
(D ABBFD
(G DBBA   (   8      EAN0l
AAF ,   d      FDA N
ABA         A    ADD   (     P    EDL L
DAD (         EDL L
DAD          AAF     (  ,    E]
E,   D  0    FAD M
AEE      t  Ь,    E]
E         AAK        T    Em
VF
A       $.    E\
H     86    Ed
H(     \    EKD@
AAK     4  ,    E]
E(   P      FJD y
FEH,   |  h    FIA A
ABA   ,     Ȯ    FAD M
AEE   (     h    EKD@
AAK       ,    E]
E   $  =    E[
E(   @  4$   MHA DB (   l  8    EFG0w
AAA 0     ̷   FFA G0
 AABK ,     H    FDA ^
ABD   4         EFG F
DAKK
ADE 8   4  `9   FJG A(GP
(A ABBE    p  d:    E]
E0         FAD D0K
 AABB      Z    Hi
O  (     8    EAG y
AAA           E  8   $     FIA A(G0
(D ABBA 8   `  A   FIA A(G0u
(D ABBA 8     K   FIA A(G0
(D ABBA 8     K   FIA A(G0
(D ABBA 8     0Q   FHA 
FBBA
CBA   8   P  TI   FHA }
FBDA
CBA   <     h   IBE A(A0|
(D BBBA   @     H   FBJ A(D0IP3
0A(A BBBE     %    E[      ,  .    Ed      H  ,.    Ed   (   d  @    EFG C
AAE ,         BAH F
ABL        d            `       H     \b   FBE E(A0I8G@
8D0A(B BBBA ,   4      FAD g
AEJ   L   d  @   FBD A(N0k
(C ABBB
(A ABBA   L        FBJ A(F0G`mhRpRhA`
0A(A BBBE      %    E[   (          EFG Z
AAE D   L  x   BBI A(G08J@P8A0L
(A ABBH                         (         EG 
FED
CA(     S   EAG@
AAA ,        FAI 
ABA   ,   D  @y   FAD 
ABG   4   t      EID [
GAKD
FAA 8     H    FAI M
ABHA
ABA  H        FBB B(A0I8G@
8D0A(B BBBA L   4  o   FGA A(G0N
(D ABBC{
(D ABBA  8        FJG A(GPZ
(A ABBA,     k   EGM
H        >    Ax            AAK  (   (      E[
PH
PH
I      T  N    Ed
H    p      EG N
DA 4     `    EFG r
DDLD
FAA  D         FDD K
ABDN
ABGN
ABA   (     Pv    EDL q
DAE     @  N    Ed
H    \  _    Ek
PF
A  (         EFG F
DAA (         EFG F
DAA      Q    Eg
H     `    AAK       dz    Es
M   ,      E}
A   H  \z    Es
M    d      E{
HF
A  (     ,    EFG t
DAA  ,         FAA R
ABC   <     p|   FIA A(D0\(A ABB       (   $      EAN0
AAD (   P  dt    EFG l
DAA     |  ?    E]
E         AAK        Q    EG {
DA       =    Ek
H     @6    Ed
H      d6    Ed
H8   ,       FBA D(G0^
(D ABBA 4   h   ,    EAG Q
AAH[
AAA 0          FAA N@
 AABH (      ~    EDD {
DAA      !  a   EI    !  H   L        <!  4    Ej      X!  <    EV      t!  @    AAK  (   !  Dg    FAG ~
ABA@   !     FBB A(A0NP,
0A(A BBBA(    "  $R    FAD p
ABB(   ,"  XR    FAD p
ABB(   X"  R    FAD p
ABB   "  *    E_
A    "  <    Ec
HF
A     "  .    E\
H   "  .    E\
H   "  .    E\
H   #  ,6    Ed
H(   4#  PV    EDL i
DAE  \   `#  I   FGA A(G0s
(D ABBFQ
(A ABBID
(G DBBE 0   #  t9   FAK D@
 AABE(   #  b    EFG B
DAD     $      AAF     <$  ,    E]
E(   X$  b    EAJ o
DAA  (   $    b    EAJ o
DAA     $  d I    Ef
A,   $       FDA d
ABA   ,   $      FDA d
ABA      ,%      AAK  (   H%  R    FAD p
ABB(   t%  R    FAD p
ABB(   %  R    FAD p
ABB(   %  8U    EIG u
DAA     %  l    E
A      &  ,    E]
E   4&   =    e(   H&  ,    EAG o
AAA  (   t&      EAG R
DAA    &  =    e(   &  @f    EAG a
DAA  (   &     FOH AU <   '  (4   FEB A(I0
(D BBBA   (   L'  (	    EFG0
AAA (   x'  	    EFG0
AAA (   '  
    EFG0
AAA (   '  d    EFG0
AAA 0   '      FAA N0w
 AABG     0(      AAF     L(  ,    E]
E(   h(  a    EIG i
DAA  L   (      FGA A(G0b
(D ABBGQ
(A ABBI   (   (  g    EIG l
DAD  8   )  4z    FJD A(G0w
(D ABBA  (   L)  xa    EIG i
DAA     x)  K    Ed
E(   )  a    EIG i
DAA     )  4J    Ec
E(   )  hr    FGA k
ABA   *  F    Ec
F8   $*      FBA D(G0k
(D ABBA    `*  Z    Hi
O  (   |*      EAG o
AAA  (   *  L    EAG y
AAA     *  +   E         *  z    EN `
AA     +  <z    EN `
AA $   <+  8    EDM [AA $   d+  8    EDM [AA $   +  8    EDM [AA $   +  8    EDM [AA $   +  8    EDM [AA $   ,  8    EDM [AA $   ,,  (8    EDM [AA $   T,  @8    EDM [AA $   |,  X8    EDM [AA $   ,  p8    EDM [AA $   ,  8    EDM [AA $   ,  8    EDM [AA $   -  8    EDM [AA $   D-  8    EDM [AA $   l-  8    EDM [AA $   -   8    EDM [AA $   -  8    EDM [AA $   -  08    EDM [AA $   .  H8    EDM [AA $   4.  `8    EDM [AA $   \.  x8    EDM [AA $   .  8    EDM [AA    .  ,    Ef   $   .  D    AHD qDA    .  =    EG jF L   /     BEE B(A0A8J
8A0A(B BBBH      `/  D    H@
A    |/      H@
A    /  L    H@
A <   /     K^H[A
D]H[A   (   /  !f    EAD k
DAA  ,    0  !    AR
EC
EF
JF
A 8   P0  4"   FBD A(NP,
(A ABBC    0  #d    A@
GC
A 8   0  $    BEA A(D0E
(C ABBA H   0  $   FBB B(A0A8G`H
8A0A(B BBBI4   81  &3   ECNPYXF`RXAP
AAH    p1  (`    D h
D  (   1  (    EAQp
AAA   1  <)v    H0Z
A 8   1  )    FBA A(D0w
(D ABBB    2  4*2    EU
NF    02  T*          D2  P*2    EY
A8   `2  t*=   FBA A(G@
(A ABBD H   2  x-   FBB B(A0A8NP
8A0A(B BBBCH   2  /'	   FIB B(A0A8D@8D0F(G EBB   0   43  7'   BDG Gs
 AABA    h3  8    EL0|
AA L   3  9    FEB A(A0D`PhUpHhA`|
0A(A BBBA L   3  8:    FEB A(A0DPPXU`HXAPa
0A(A BBBA    ,4  :    EL   $   H4  :q    EID YDA   p4  :    AAK      4  :l    EL0O
AA     4  D;Q    EG {
DA     4  ;0    Ee
A8   4  ;    FBA D(G0Z
(D ABBA 0   ,5  (<h    FDA G0I
 DABA    `5  d<s   E[ <   |5  =O   FEB A(I0
(D BBBA   (   5  >    EFG0
AAA (   5  ?    EFG0
AAA (   6  @@    EFG0
AAA <   @6  @<   FEB A(I0
(D BBBA   (   6  A    EFG0
AAA 0   6  B    FAA N0w
 AABG     6  TC    AAF     6  XC,    E]
E   7  lC    AAK  (   47  pCm    FAI |
ABAL   `7  C   FGA A(G0b
(D ABBGQ
(A ABBI   (   7  Dj    EIG o
DAD  8   7  Dz    FJD A(G0w
(D ABBA  (   8  Ei    EIG q
DAA  L   D8  PE&   FGA A(G0g
(D ABBJQ
(A ABBI   (   8  0F    EDJ0`
AAA (   8  F    EDJ0\
AAA    8  G-    EZ
I   9  ,G-    EZ
I(   $9  @Ga    EIG i
DAA     P9  G-    EZ
I(   l9  G    FDA z
ABH   9  H4    Eb
H8   9  0H    FBA D(G0k
(D ABBA (   9  H    EAG o
AAA  (   :  HI    EAG O
DAA    H:  IZ    Hi
O     d:  J   E     0   :  L    FIA Gp
 AABB 0   :  lM]   FCD G
 AABA   :  N9    LT
A   ;  NR    Ey
A(   $;   OS    FIC yAB   ,   P;  4O    Ef
EI
GD
LD
E  (   ;  O    EAD0e
AAA (   ;  P    EAG o
AAA  (   ;  |P    EEG I
AAA (   <  Q    EAG O
DAA (   0<  Q    EEG i
DAA    \<  XR    L      (   |<  8S    EFG0
AAA (   <  S    EFG0
AAA    <  T    AAF      <  Tv    EG K
AA     =  U    Em
NR
N  4   8=  U    EIG n
FAFD
CAA  ,   p=  $Vn    FAD B
ABA   (   =  dVa    EIG i
DAA     =  VK    Ed
E   =  VX    Eo
G(   >   W    EAN@x
AAB     0>  W,    E]
E   L>  W   Ll     (   l>  8Y    EFG0
AAA L   >  Y   FGB B(A0A8J
8A0A(B BBBH   0   >  [#   FAK D@
 AABI D   ?  \h   FBA A(NPXU`FXAP[
(A ABBF 0   d?  ]   FIF GPb
 AABF 0   ?  _   FAF J@
 AABG    ?  _:    E]
E   ?  `A    E\
H,   @  P`    BAD E
DBE      4@  `-    Hd    L@  `    RV   d@  aA    E\
H   @  aZ    Hi
O  (   @  a    EAG o
AAA  8   @  \b   FIB A(A0(D BBB (   A   eJ   EAG0
AAB (   0A  Df    EHD nDA    (   \A  f    EFG0
AAA @   A  lg   FBB A(A0Np6
0A(A BBBH   A  i   FIE B(A0A8G^LFFGGFFPJEBZ
8A0A(B BBBD      TB  Pk:    E]
E   pB  tk   L  (   B  xl    EFG0
AAA @   B  <m   FBB A(C0NP
0A(A BBBJ \   B  nU   FBB B(D0A8NaFWAL
8A0A(B BBBD   8   \C  p.   Ep
KM
SM
SM
SM
SM
I L   C  qe   FBB B(A0A8G I 
8A0A(B BBBAL   C  ,ra   FGA A(G0
(D ABBKc
(A ABBE   L   8D  Ls   FGA A(G0
(D ABBKQ
(A ABBE   0   D  t    FAA N0w
 AABG  D   D  Xu   FIA A(D`ahFpWhA`
(A ABBG L   E  v   FIB A(A0FpcxFRxAp
0A(A BBBG8   TE   x   FIA A(FP
(A ABBE    E  z    AAK     E  z*    E[
E   E  z.    E[
I   E  0zA    E[
I    F  dz-    E[
H   F  xz    AAF  (   8F  |za    EAJ n
DAA     dF  z,    E]
E    F  zg    Ep
KE
E  8   F   {    FBD D(J0J
(D ABBA    F  t{,    E]
E(   F  {    EFG y
AAE     (G  {    AAK      DG  {?    Al
CE
E     hG  |    HI (   G  |b    FDD PAB      G  X|?    Al
CE
E  (   G  t|b    FDD PAB     G  |    HI (   H  |]    FIA l
ABA   @H  |       (   TH  |]    FIA l
ABA   H  $}       ,   H   }   FHD s
ABA   8   H   ~I   FHD 
ABCc
ABA   (    I  a    EIG i
DAA     ,I  XW    Eg
D   HI  <    Ee
M(   dI      EDL u
DAA  H   I  $Q   FBB B(A0D8LP
8A0A(B BBBE 8   I  8    FBA D(G0h
(D ABBA    J  ,    E]
E0   4J       FDA D0
 AABA    hJ  @    E[
H,   J     FVA DB     ,   J  D   FFA 
ABA  @   J      FAD L0
 DABCU
 DABA  @   (K  \    FAD L0
 DABCU
 DABA  @   lK      FAD L0
 DABCU
 DABA  @   K      FAD L0
 DABCU
 DABA  @   K  0    FAD L0
 DABCU
 DABA      8L  ̌    EG l
DD (   \L  x;   EDD@
AAB 0   L  0   FFA G0
 AABG T   L     FJG A(GPXN`LXAPh
(A ABBDlXK`ShBpIP  (   M      EFG H
AAE 4   @M  d    AHDPzXI`QXAPh
AAD  @   xM  N   FJH A(A0GP
0A(A BBBB H   M      BED C(D0M
(D ABBHL(D ABB  (   N  </   EFG v
AAF (   4N  @o    EGD m
AAA  4   `N      EID i
FAF^
AAA     N      AAK      N  <    Ed
GF
A      N  <    Ed
GF
A      N  (<    Ed
GF
A       O  D<    Ed
GF
A      DO  `<    Ed
GF
A     hO  |k    Eg
O   O  Ж    EL
G      O  `   E}     D   O      FED A(D@[HUPFHA@I
(D ABBC T   P  x    FEE B(A0D8DP~XA`FXAPI
8D0A(B BBBI    dP       L[      (   P      EFG0
AAA 4   P  D    EFG F
DAKK
ADE    P  	       0   P     FGA D0
 AABA 8   0Q     FJA F(G`
(A ABBB 8   lQ     FBA A(NP
(A ABBH4   Q  l    EFG z
DAOP
DAE     Q      AAK     Q  2    E\
L(   R  D    EIG d
DAA  0   DR  0    FAD D0K
 AABB    xR      AAK  (   R  S    FAI z
ABA(   R  ġM    FAI t
ABA(   R  M    FAI t
ABA(   S  M    FAI t
ABA(   DS  0M    FAI t
ABA,   pS  T    EN@YHFPWHA@r
AA (   S  q    EPI e
GJE     S  H:    E]
E   S  lZ    Hi
O  (   T      EAG o
AAA  (   0T      EAG y
AAA  ,   \T     FOH HI        T  8    HN $   T  @C    EDG0mDA    T  h3    H j    T      AAF       U  g    EG ~
FH     $U  B    H t
A  (   @U  N    EDD l
DAB  (   lU  8N    EDD l
DAB     U  \C    H u
A     U  I    H {
A     U  Ĩ)   L
 ,   U  ت   FFA 
ABA   @   V  ȫ    FAD L0
 DABCU
 DABA  @   `V  d    FAD L0
 DABCU
 DABA  @   V       FAD L0
 DABCU
 DABA  @   V      FAD L0
 DABCU
 DABA  ,   ,W  8    FIA c
ABA   (   \W  Ȯ   EFG0
AAA (   W      EFG F
AAE (   W  0    EFG F
AAE (   W  T    ACF u
DAD  8   X     FJG A(GP
(A ABBA H   HX  |    BED C(D0M
(D ABBHL(D ABB  (   X     EFG h
AAD (   X      EKI@m
AAH    X      AAK      Y  o    Es
HK
G     ,Y  شX    Eg
O   HY      AAK      dY   <    Ed
GF
A      Y  <<    Ed
GF
A      Y  X<    Ed
GF
A      Y  t<    Ed
GF
A  (   Y      EFG l
DAA       Z      EL `
AA 8   DZ  py    BED D(D0A
(D ABBA    Z      EL
G      Z  D   E 8   Z  ^   FGA A(G0&
(D ABBAH   Z     FJH B(A0A8G`
8A0A(B BBBE 8   D[  л    FEA A(NP
(A ABBA 8   [      FEA A(NP
(A ABBA 4   [  Hi    FBD A(D0N(D ABB   [      HN     \      EK v
AI (   0\  $    EDD0
DAI    \\      AAK  (   x\  V    EGD m
FAD     \      AAF  (   \      EAG0W
AAA (   \  h    EAG0W
AAA    ]  ܿH    Ee
A   4]  .    E\
H   P]  $.    E\
H(   l]  8    FAD AB     ]  ,    E]
E   ]  O   L
I  <   ]  O   FEB A(I0
(D BBBA   (   ^      EFG0
AAA 0   @^      FAA N0w
 AABG     t^  `    AAF     ^  d,    E]
E   ^  x    AAK  (   ^  |m    FAI |
ABAL   ^      FGA A(G0Z
(D ABBGD
(A ABBE   4   D_     EAJ w
DADo
FAJ  (   |_  g    EAJ q
DAD  ,   _  <n    FAD B
ABA   (   _  |a    EIG i
DAA     `  K    Ed
E(    `      EDJ0`
AAA (   L`  h    EDJ0_
AAA    x`  N    Eg
E   `  M    Ef
E(   `  Da    EIG i
DAA     `  K    Ed
E(   `  a    EIG i
DAA     $a   K    Ed
E(   @a  4L    EIG l
DAA     la  X.    E\
H(   a  le   FAD RAB (   a      EFG A
AAE (   a      FDA z
ABH   b  4    Eb
H(   (b      EFG y
AAE  (   Tb      EFG y
AAE  8   b  t    FBA D(G0h
(D ABBA    b  (Z    Hi
O  (   b  l    EAD0s
AAA (   c       EAG o
AAA  (   0c  d    EAG O
DAA    \c  *   E        |c            c            c  P    H B
A (   c  $;    FAA ^GI   \   c  8   BBB A(A0G L@I@@H@N@A@
0A(A BBBH      Ld  <    Ev   $   hd      L^
Fk
En   L   d  D    FBB A(A0
(C BBBHJ
(A BBBA    d            d  Q    H ~
A  L   e  4i   FBA A(D0S
(D ABBFU
(A ABBE   L   `e  Ti   FBA A(D0S
(D ABBFU
(A ABBE   0   e  t    FKA J0a
 AABA H   e     FBB E(D0C8GPI
8A0A(B BBBH 8   0f  A   FBD A(IpT
(A ABBH    lf  U    H G
A    f  )    LS
AD    f      EAG <   f      FGB D(A0i
(D BBBA      g       K
A(    g     EAD 
AAE   Lg  H       <   `g  D7   FEB A(I0
(D BBBA      g  D    AAF     g  H,    E]
E(   g  \f    EIG n
DAA  L   h     FGA A(G0b
(D ABBGQ
(A ABBI   (   Th  p    EDJ0Y
AAA    h      AAK     h  *    E[
E(   h  @    EIG `
DAA     h  )    EZ
E    i  $j    Hz
N  (   i  x    EAG G
AAA    Hi  1   E    di  0       (   xi  ,    EKF@
AAF 0   i      FAA N0{
 AABK (   i      EKF0k
AAE @   j  `C   FLB A(A0DP
0A(A BBBH @   Hj  lC   FLB A(A0DP
0A(A BBBH 0   j  x   FAK I@
 AABA    j  T    AAF     j  X,    E]
E   j  l    AAK     k  p=    Er
A    0k  E    E_
DO
I     Tk  0    EZ
L(   pk  q    EFG |
DAA     k  (.    E\
H   k  <:    E\
T(   k  `v    EAJ t
DAG  (    l  v    EAJ t
DAG  (   ,l  n    FIA q
ABD(   Xl  L^    EGD r
DAI  (   l  n    FIA q
ABD(   l  n    FIA q
ABD(   l      EDG l
GAL  ,   m     FFA j
FBI   8   8m  l/   FBA A(J0z
(F ABBG 8   tm  `2   FBA A(J0z
(F ABBG    m  dZ    Hi
O      m  2   ED0
AA 8   m  '   FBA A(J0~
(F ABBK d   ,n  G   FBB L(A0A8DpYxFWxBpHxKNxApm
8A0A(B BBBC   (   n  j    FAG r
CBE(   n  j    FAG r
CBE(   n  (I    EAJ j
CAF  (   o  LI    EAJ j
CAF     Do  p    HP 8   \o  x'   FBA A(J0}
(F ABBL <   o  l/   FBB A(D0
(F BBBG   8   o  \'   FBA A(J0}
(F ABBL 8   p  P'   FBA A(J0}
(F ABBL <   Pp  D/   FBB A(D0
(F BBBG   <   p  4/   FBB A(D0
(F BBBG   <   p  $/   FBB A(D0
(F BBBG   8   q  '   FBA A(J0
(F ABBJ <   Lq     FBB A(A0
(D EGDK   8   q  h'   FBA A(J0}
(F ABBL 8   q  \   FBA A(J0s
(F ABBN 8   r  @    FBA A(J0s
(F ABBN (   @r  $k    FAD 
ABA   lr  hv   EA
X     r  D    Em
FH    r  E    E\
OT L   r  (T   BGA A(G0P
(F ABBC 
(F ABBA  8   s  8    FAD ]
ABEW
ABA      Xs  E    E\
OT <   xs  	    EFG r
DAGf
DAEWDA (   s  |	    AID0
DAA    s   
E    E\
OT X   t  0
    FGA A(G0c
(D ABBFD
(G DBBEX(D ABB<   `t  
}    EFG r
DAGI
DABWDA 0   t  
K   FAD D0
 AABD 8   t   h   FBA K(DP
(A ABBC H   u  4   BJB E(A0D8DP
8D0A(B BBBF   \u  $    ES      xu  $    ES      u         (   u     EAN0
AAE (   u  U    EDL g
DAG      v  -    E`   (   v  U    EDL g
DAG     Hv  ,-    E`   (   dv  @   FFA  AB 0   v  4    EFG L
JHHDFA0   v      EFG L
JHHDFA(   v      FFA AB  (   $w      EDQP
AAD 0   Pw      FDD D0W
 AABC $   w  S    ECG xFA H   w      FGB A(A0s
(C BBBCS(F BBB0   w  <I   FAD G0
 AABC 0   ,x  X   FAD G0
 AABE @   `x     FEE A(D0F@
0A(A BBBHL   x      FGA A(G0c
(D ABBFD
(A ABBE      x  A    E`
KL 8   y  n   FBA D(D@
(A ABBF(   Py  D#9   EAN@
AAB $   |y  X$u    Eu
FC
ET
A   y  $E    Ed
GT 0   y  $    EFG y
FAFqFA ,   y  L%    FAD H
AEJ   (   (z  %]    EDO l
DAA  (   Tz   &h    EDD m
GJE     z  D&#    EY   @   z  X&   FBB D(A0D@
0A(A BBBA H   z  $'    FLI I(H0D8D
8A0A(B BBBA,   ,{  '    FAD H
AEJ   8   \{  8(   FBD A(G@G
(A ABBAH   {  )v   FIB B(H0I8D@38F0H(B BBB   (   {  1    EAD0I
AAK    |  2Q    H C
A    ,|  2          @|  2       (   T|  2f    EAG0L
AAA              GNU                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     y     py     @$                                         {                                                .                                                                                              %     1               
                                    1                                                                                                                     (             -             8             E             P             ]             l             {                                                                                                                                                            	                          *                    ?             ?             +?             ;?             K?             V?             a?             o?             y?             ?                         ȷ            0$                          8$                   o    `             f             	      
       @                            $            (J                                        H                   	              o          o           o    Ʀ      o    F                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       p$                           0     @     P     `     p                                                              0     @     P     `     p                                                              0     @     P     `     p                                                              0     @     P     `     p                                                              0     @     P     `     p                                                              0     @     P     `     p                                                              0     @     P     `     p                                                              0     @     P     `     p                                                              0     @     P     `     p                                                              0     @     P     `     p                                                                 0      @      P      `      p                                                       !     !      !     0!     @!     P!     `!     p!     !     !     !     !     !     !     !     !      "     "      "     0"     @"     P"     `"     p"     "     "     "     "     "     "     "     "      #     #      #     0#     @#     P#     `#     p#     #     #     #     #     #     #     #     #      $     $      $     0$     @$     P$     `$     p$     $     $     $     $     $     $     $     $      %     %      %     0%     @%     P%     `%     p%     %     %     %     %     %     %     %     %      &     &      &     0&     @&     P&     `&     p&     &     &     &     &     &     &     &     &      '     '      '     0'     @'     P'     `'     p'     '     '     '     '     '     '     '     '      (     (      (     0(     @(     P(     `(     p(     (     (     (     (     (     (     (     (      )     )      )     0)     @)     P)     `)     p)     )     )     )     )     )     )     )     )      *     *      *     0*     @*     P*     `*     p*     *     *     *     *     *     *     *     *      +     +      +     0+     @+     P+     `+     p+     +     +     +     +     +     +     +     +      ,     ,      ,     0,     @,     P,     `,     p,     ,     ,     ,     ,     ,     ,     ,     ,      -     -      -     0-     @-     P-     `-     p-     -     -     -     -     -     -     -     -      .     .      .     0.     @.     P.     `.     p.     .     .     .     .     .     .     .     .      /     /      /     0/     @/     P/     `/     p/     /     /     /     /     /     /     /     /      0     0      0     00     @0     P0     `0     p0     0     0     0     0     0     0     0     0      1     1      1     01     @1     P1     `1     p1     1     1     1     1     1     1     1     1      2     2      2     02     @2     P2     `2     p2     2     2     2     2     2     2     2     2      3     3      3     03     @3     P3     `3     p3     3     3     3     3     3     3     3     3      4     4      4     04     @4     P4     `4     p4     4     4     4     4     4     4     4     4      5     5      5     05     @5     P5     `5     p5     5     5     5     5     5     5     5     5      6     6      6     06     @6     P6     `6     p6     6     6     6     6     6     6     6     6      7     7      7     07     @7     P7     `7     p7     7     7     7     7     7     7     7     7      8     8      8     08     @8     P8     `8     p8     8     8     8     8     8     8     8     8      9     9      9     09     @9     P9     `9     p9     9     9     9     9     9     9     9     9      :     :      :     0:     @:     P:     `:     p:     :     :     :     :     :     :     :     :      ;     ;      ;     0;     @;     P;     `;     p;     ;     ;     ;     ;     ;     ;     ;     ;      <     <      <     0<     @<     P<     `<     p<     <     <     <     <     <     <     <     <      =     =      =     0=     @=     P=     `=     p=     =     =     =     =     =     =     =     =      >     >      >     0>     @>     P>     `>     p>     >     >     >     >     >     >     >     >      ?     ?      ?     0?     @?     P?     `?     p?     ?     ?     ?     ?     ?     ?     ?     ?      @     @      @     0@     @@     P@     `@     p@     @     @     @     @     @     @     @     @      A     A      A     0A     @A     PA     `A     pA     A     A     A     A     A     A     A     A      B     B      B     0B     @B     PB     `B     pB     B     B     B     B     B     B     B     B      C     C      C     0C     @C     PC     `C     pC     C     C     C     C     C     C     C     C      D     D      D     0D     @D     PD     `D     pD     D     D     D     D     D     D     D     D      E     E      E     0E     @E     PE     `E     pE     E     E     E     E     E     E     E     E      F     F      F     0F     @F     PF     `F     pF     F     F     F     F     F     F     F     F      G     G      G     0G     @G     PG     `G     pG     G                                                                                   %9\T%֟LLSt @׺p(a`LI_`=ө^d`&u1WLe1o} vO{)hW@T@5%WQw                               q?O`.|	qc'DȓHLmzJMRJ1DGJȋ$             o             |                                                                                                                                           GA$3a1      շ              GA$3p1067  y     Ʒ               GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign             GA$3p1067  0     ֵ               GA*             GA$annobin gcc 8.5.0 20210514            GA$plugin name: gcc-annobin              GA$running gcc 8.5.0 20210514            GA*             GA*             GA!              GA*FORTIFY               GA+GLIBCXX_ASSERTIONS             GA*GOW *            GA*cf_protection             GA+omit_frame_pointer             GA+stack_clash            GA!stack_realign            GA*FORTIFY     y                   GA+GLIBCXX_ASSERTIONS   openssl.so-1.8.7-16.el8.x86_64.debug    
/%7zXZ  ִF !   t/!] ?Eh=ڊ2Nv-]W:WEv	4Z]HKDVTsVI;~>?]8Nh8\;-%gNo~2m
ڥ[瘙ym	YvdPci_	wuyb#lO^Ix%yLSo+n]ZDbÈڗ>;F{ؿoH&jUSۉl:}R
5$ǥ2vk܍X鲖\j78iw=Ο[beEwssƹ!|/Ljme8g	HI
w;Q݂7:܃`qo6`p`~}욑qXTT8A֦nyH/eUSƝ?T3Rþ+u}:#@gDy5֌Qh4I23[#qo2	?VsމgSP+06^2SQBŗcc,8'JG3t|Zݠ7Z@ك)F4ҋpdG B1S6,sn+g*+-'}_Bc6+b_&rcTy3{KDsj=ȹ$%${:(B	N,!-2cem2Ks2L$K8%%1w)72$t:~ }EzP c4RwH7FZ)aa=th0,PBghbUGe	&7UTBi8]+wl[MZkiCg-OBd(i/}`Ņ!W([KnM>XxP-Za*~L_XmFkwMƾ̈
epU_a^:Ph;wQRڿrLNwMխ)d1]>#|DiA}`#A	D(1X|bߎS;G#jzbjtJpt`y>ZW b-B#0 x5%
%f >fN}k.e~f`=Xou++yTo9hYgcⷳbjӽIb$Q˺S!6Fu-p֪mr$BwH~bTX9|ـ3|Xj4A$z98Ay&@jA[c9Bv9'i#0q>7R}mf#bm\/eE5w,vkL{s29˵P%mqV哜dӹ1"&.jg^D@/J%YQEę6wNTathJ$kl3HSܙ4 @[铆dP0^Vv)*[Z3SW#CWu<҂[1d,ﻵ3_"\#nxpap:	|sO}EP~bъޜQ+n~QlepkG+M"k_i#`.;bnRZ {"M?NՉ(0+;eQuϧ?Z.4i:x0'#,`)#Gbote]e%p
+&1[рe: 
D~jA+v_oKw[>*jc6ۙ+.ey솲]-Ivu2崝R8հ#<w}stuSe}
qgE)YqlJs~ݦt/O"C3?W" /.G,ӯʑDU?>ڒFUtү/+Ž}xٖuM[>Uʢ&uXʼDvǫ/0zXqjPsbttY0
{7~Le/bN!pp8!L@̗+ޫknGH'%2n㼫U#l;vlUw e,k`\!'Z2<E߬61E6wDX0nf:j7W VXVtWw1/(BGJ2u8%U2f.Dw$YӘ6qSc3W>1,̲~]`+)s	P]pT^
T8HՀ

@Gz,-8XoWExc5F'Qv6(6z,k3c_qkFw]ʻ~a&,u*|'F P0V'8%;8*	uoGMR(~~#Wu
#|td3=x|ɖ>Q	E6kRJY(D}_]v8 }S.[d0tZj?^JM2ϔu3A.q,/jYұp.!G+Pȍ|=@~4%FBnFK.	`cpABh]tE^[حxL9=IPBzQ+Z˝:KɌYw,s4|u,}2Rv KY{(+qwgBhU4!)S'>].q[4[	u͐oCŌbbDt5;#Eg6s~yaћшF(8gdN!|:N[s֛ݏ-W5?F}5I84c?hro{=00T^%t$SOY!VB-pg$ fNAzGxҰ[qԠ= nhs@ä`Lho9=rr:[)ѢMnոo#=ƦP
a	Mڢ݉XAܖf8C?6*c)rMX$0?.PYMG$WUԨE6ѓ:Xw#_ 7Y=ķ1fE禡ovWLGt[ڹ
13mi'trҵĩ]xKEBm;
lgrC8bN\C,v^]qYD	VܨC4$n'-`K/P7fH޷tԤkîdLc梀'f@t5qVar"|YטSe-7j7rB1赻$17LHzCS0;6k'
ԑJ:%t~\1[rb"'mZb<`VI)Nm5i(|J:rSGmV.|.{Ĵa> >F+yG\PG 	dYNy?&ZgWpsO@COh˥xO)TxʒlphP	o"|BzT[E4nF2jCrȰPGN͜|
UXBfoY:TP35.-ļgQbyfU)et7"ʜz`I`b)l~aԼix90Q|oHc>d/T5!ZP4hpR#t+YC iEvڱoqG]i|aڨ>M>U'ӏ̻_GKzZdx^??
<.$,`;ޔKKFo!,92Pe?M")tC(*JƔb6{1w8fF\G͘k
_jIo4>N/R9LcWco{"hHSA:-49I0NIm˂T|leKUs#e^BwK^G͘ޝ`R*$7kKyD"kPT~#ZzR` 5A8^j/5-[+w-ѭz6R,ddx(^gK`iZYH_G;CN$$4fpv.a`բrqK
}{NVp~]h쳋X<'+NBST"My
NqQ˦irȎHkC#$h)s	_OG6c0o@5ȧj0+wݘnHF'ĺE#$e)ṗ[D1?ho&?{t[` ݓ_[Z
PPΤڗJ"dRrv
IYWu"-
n݂<76Tj`
2|"nQ/k~2vRc׸ݿg)E'wJ2Hc I2)-Ϊ"5C>I6kUcҫXv.!<tjC 0I$__}lHMa4qJM%\#:HAu~[ӂa\hnёe+A!NdF ylXo/o\wȏDq<ܫNts$ӝW|"V_ktMHu?L<D4ϊJHJU>8/@nbR?#&4Դ\uT5P Y<oo'2=gq{ iZ>Fy>辧tLXOKr	k$sxӸJh
IOMKjJz/g2M-@`D ^5ڗSKy$R5(`"-\2'JpAB~]2l-Ez[k%HђP{dA=hxجy=NYX/!	˽Vᚍ8ZJo#(2/ku6ze`c {u AY0:j٥ ƿLrRw.ƥFƯa*Dr?^Ab5X=jVG	@ ~	gI<7ls+hA"߫;͛ OB?78a#8-SЮT+oѫ),ًoY;&9+hm@!h aw&;'ܨY/z71t]8qyh@ l~]JuLBV$CBt_tTrҏI)nue	q1GMTvVhr*okn~⎁XF[7/*3bR?nP$;oHɄ,$	LklH286Wsx2.jȯ+iZW:Cmh! F|79:%%\u 0<YCv8VrpjK~
9A(el_:Lh2n2gO͕v{\ەES <ł]o ۥeQ,z'2WQp`h>{Qe)ȐN08Q
мX 9tAq#S}$9|Łj;{JpܣQ&яwp}!,ԁm$M$mge5;0㔊3|6q~f}2Ą#Z4/#csk1~0mv
h$Ev:P!bʦWoW0ls0oL3]=K'~l}daE7^e7PWN$bnGfI6q<?~G`MhC&#*FvN9$O)Y8ofjq?5ͭCt!8kC|"{Wq@DX$7DI_o?OB^#o3:[οQ5^Wc v+O#dEucc|b<xU~qE%3[٧Y1us"ձ-Lhyк 2f
K0%u+24CLW?oY;ۑly3)8j^37s¤ڕn?ZZEk}&.|4-N_%I~-|^2.}@nG{9}Lc0u[<G'oG|ą)?yߚ_!Xp1ⷿH.)!GJ, F-E"jյj<te96}rdw}r3Ҝ~I*C@]ieѣ6Zxv\8kHŶ ^kvQg]eт/ES\=F׋YTâ&zfrΏԾVý=)}qBORyL6!Fo-6a&vs!{l,I @~K'q|E2Oc58Mͣ=P쨤%*a+d>R \d7Åa럇>>`2"Qc/ߛ{f?f5t؛.Kr6eoWrvgͧSsq(?rWZ?Wҋ U\D2;0.nqËT3sF&6rb@q+?ϲoj4C NX]y%4u[8r]o{|k?o%ެAdk{$0DJ!P{SHz怼q9F58B9`]o` fpjKǽӨҟ5iPd];Z|YF-0֐9vPΙyefM^"M*ub߯n;m4[>҄	jE$Po
G!U%:<u+7 ;ti"_$+I!_Ѧ-&șNٿqln{hHqp+-!qD>im5VĊaSG gpE|%fz>I7>Хd>gt OxMI։"O{Z/U˓'T
-ϒc(6X*/Ys1lNle_+F;ẽnS;aOvzI0<'ăp)ܣPO?(C@*jv<|}^)bEV׻>Mav>hkT=ѳXjP;M0(B-րd!)k!Fz}3mw^;4嬐+wyJMc(8:#
[ŭ~B~`rdjz8-@P!<OH]W&WپR$ >8̗~Κy31 \
~1s1)zŘAΏJƌlsZ%\1ׁP}feiߝYTzs`uqL!xJ6u*ebk8S%_ƽS0Ȍ{ܪ)Uef=5+wYmJ&X}Qh&BU.;#[ƥY[K/\9mZҷNSb4[gc?2H
;gI*!nC0uV&j)-ByW	ɉ$`pp'D  gKCL	 z*u@~}{G˴j{YHѨյ#     > 0g    YZ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .note.gnu.property .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data .bss .gnu.build.attributes .gnu_debuglink .gnu_debugdata                                                                                 8      8      $                                 o       `      `                                  (             	      	      \                          0             f      f      @                             8   o       Ʀ      Ʀ                                 E   o                                               T             H      H                                 ^      B                   (J                          h                                                     c                       1                            n             G     G     p1                            w              y      y     >                            }             ȷ     ȷ                                                          9                                                    l                                          (     (     |                                                                                                0$     0                                               8$     8                                               @$     @     0                                           p$     p     P                                        $          @                                          $                                                    $                                                     $                                                     d                                                            ܾ     ,                              "                          d                                                   l     1                             PK     Y\g<#  #    x86_64-linux/regex.hnu [        /* Definitions for data structures and routines for the regular
   expression library, version 0.12.
   Copyright (C) 1985,89,90,91,92,93,95,96,97,98 Free Software Foundation, Inc.

   This file is part of the GNU C Library.  Its master source is NOT part of
   the C library, however.  The master source lives in /gd/gnu/lib.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The GNU C Library 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.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file LGPL.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */
/* Multi-byte extension added May, 1993 by t^2 (Takahiro Tanimoto)
   Last change: May 21, 1993 by t^2  */
/* modified for Ruby by matz@netlab.co.jp */

#ifndef REGEX_H
#define REGEX_H

/* symbol mangling for ruby */
#ifdef RUBY
# define re_adjust_startpos ruby_re_adjust_startpos
# define re_compile_fastmap ruby_re_compile_fastmap
# define re_compile_pattern ruby_re_compile_pattern
# define re_copy_registers ruby_re_copy_registers
# define re_free_pattern ruby_re_free_pattern
# define re_free_registers ruby_re_free_registers
# define re_match ruby_re_match
# define re_mbcinit ruby_re_mbcinit
# define re_search ruby_re_search
# define re_set_casetable ruby_re_set_casetable
# define register_info_type ruby_register_info_type
#endif

#include <stddef.h>

/* Define number of parens for which we record the beginnings and ends.
   This affects how much space the `struct re_registers' type takes up.  */
#ifndef RE_NREGS
#define RE_NREGS 10
#endif

#define BYTEWIDTH 8

#define RE_REG_MAX ((1<<BYTEWIDTH)-1)

/* Maximum number of duplicates an interval can allow.  */
#ifndef RE_DUP_MAX
#define RE_DUP_MAX  ((1 << 15) - 1) 
#endif


/* If this bit is set, then character classes are supported; they are:
     [:alpha:],	[:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],
     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
   If not set, then character classes are not supported.  */
#define RE_CHAR_CLASSES (1L << 9)

/* match will be done case insensetively */
#define RE_OPTION_IGNORECASE (1L)
/* perl-style extended pattern available */
#define RE_OPTION_EXTENDED   (RE_OPTION_IGNORECASE<<1)
/* newline will be included for . */
#define RE_OPTION_MULTILINE  (RE_OPTION_EXTENDED<<1)
/* ^ and $ ignore newline */
#define RE_OPTION_SINGLELINE (RE_OPTION_MULTILINE<<1)
/* search for longest match, in accord with POSIX regexp */
#define RE_OPTION_LONGEST    (RE_OPTION_SINGLELINE<<1)

#define RE_MAY_IGNORECASE    (RE_OPTION_LONGEST<<1)
#define RE_OPTIMIZE_ANCHOR   (RE_MAY_IGNORECASE<<1)
#define RE_OPTIMIZE_EXACTN   (RE_OPTIMIZE_ANCHOR<<1)
#define RE_OPTIMIZE_NO_BM    (RE_OPTIMIZE_EXACTN<<1)
#define RE_OPTIMIZE_BMATCH   (RE_OPTIMIZE_NO_BM<<1)

/* For multi-byte char support */
#define MBCTYPE_ASCII 0
#define MBCTYPE_EUC 1
#define MBCTYPE_SJIS 2
#define MBCTYPE_UTF8 3

extern
#if defined _WIN32 && !defined __GNUC__ && !defined RUBY_EXPORT
__declspec(dllimport)
# endif
const unsigned char *re_mbctab;
#if defined(__STDC__)
void re_mbcinit (int);
#else
void re_mbcinit ();
#endif

#undef ismbchar
#define ismbchar(c) re_mbctab[(unsigned char)(c)]
#define mbclen(c)   (re_mbctab[(unsigned char)(c)]+1)

/* Structure used in re_match() */

typedef union
{
  unsigned char *word;
  struct {
    unsigned is_active : 1;
    unsigned matched_something : 1;
  } bits;
} register_info_type;

/* This data structure is used to represent a compiled pattern.  */

struct re_pattern_buffer
  {
    char *buffer;	/* Space holding the compiled pattern commands.  */
    int allocated;	/* Size of space that `buffer' points to. */
    int used;		/* Length of portion of buffer actually occupied  */
    char *fastmap;	/* Pointer to fastmap, if any, or zero if none.  */
			/* re_search uses the fastmap, if there is one,
			   to skip over totally implausible characters.  */
    char *must;	        /* Pointer to exact pattern which strings should have
			   to be matched.  */
    int *must_skip;     /* Pointer to exact pattern skip table for bm_search */
    long options;	/* Flags for options such as extended_pattern. */
    long re_nsub;	/* Number of subexpressions found by the compiler. */
    char fastmap_accurate;
			/* Set to zero when a new pattern is stored,
			   set to one when the fastmap is updated from it.  */
    char can_be_null;   /* Set to one by compiling fastmap
			   if this pattern might match the null string.
			   It does not necessarily match the null string
			   in that case, but if this is zero, it cannot.
			   2 as value means can match null string
			   but at end of range or before a character
			   listed in the fastmap.  */

    /* stack & working area for re_match() */
    unsigned char **regstart;
    unsigned char **regend;
    unsigned char **old_regstart;
    unsigned char **old_regend;
    register_info_type *reg_info;
    unsigned char **best_regstart;
    unsigned char **best_regend;
  };

typedef struct re_pattern_buffer regex_t;

/* Structure to store register contents data in.

   Pass the address of such a structure as an argument to re_match, etc.,
   if you want this information back.

   For i from 1 to RE_NREGS - 1, start[i] records the starting index in
   the string of where the ith subexpression matched, and end[i] records
   one after the ending index.  start[0] and end[0] are analogous, for
   the entire pattern.  */

struct re_registers
  {
    int allocated;
    int num_regs;
    int *beg;
    int *end;
  };

/* Type for byte offsets within the string.  POSIX mandates this.  */
typedef size_t regoff_t;

/* POSIX specification for registers.  Aside from the different names than
   `re_registers', POSIX uses an array of structures, instead of a
   structure of arrays.  */
typedef struct
{
  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */
  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */
} regmatch_t;

#ifdef __STDC__

extern const char *re_compile_pattern (const char *, int, struct re_pattern_buffer *);
void re_free_pattern (struct re_pattern_buffer *);
/* Is this really advertised?  */
extern int re_adjust_startpos (struct re_pattern_buffer *, const char*, int, int, int);
extern void re_compile_fastmap (struct re_pattern_buffer *);
extern int re_search (struct re_pattern_buffer *, const char*, int, int, int,
		      struct re_registers *);
extern int re_match (struct re_pattern_buffer *, const char *, int, int,
		     struct re_registers *);
extern void re_set_casetable (const char *table);
extern void re_copy_registers (struct re_registers*, struct re_registers*);
extern void re_free_registers (struct re_registers*);

#ifndef RUBY
/* 4.2 bsd compatibility.  */
extern char *re_comp (const char *);
extern int re_exec (const char *);
#endif

#else /* !__STDC__ */

extern const char *re_compile_pattern ();
void re_free_regexp ();
/* Is this really advertised? */
extern int re_adjust_startpos ();
extern void re_compile_fastmap ();
extern int re_search ();
extern int re_match ();
extern void re_set_casetable ();
extern void re_copy_registers ();
extern void re_free_registers ();

#endif /* __STDC__ */

#endif /* !REGEX_H */
PK     Y\8      observer.rbnu [        #
# observer.rb implements the _Observer_ object-oriented design pattern.  The
# following documentation is copied, with modifications, from "Programming
# Ruby", by Hunt and Thomas; http://www.rubycentral.com/book/lib_patterns.html.
#
# == About
#
# The Observer pattern, also known as Publish/Subscribe, provides a simple
# mechanism for one object to inform a set of interested third-party objects
# when its state changes. 
#
# == Mechanism
#
# In the Ruby implementation, the notifying class mixes in the +Observable+
# module, which provides the methods for managing the associated observer
# objects.
#
# The observers must implement the +update+ method to receive notifications.
#
# The observable object must:
# * assert that it has +changed+
# * call +notify_observers+
#
# == Example
#
# The following example demonstrates this nicely.  A +Ticker+, when run,
# continually receives the stock +Price+ for its +@symbol+.  A +Warner+ is a
# general observer of the price, and two warners are demonstrated, a +WarnLow+
# and a +WarnHigh+, which print a warning if the price is below or above their
# set limits, respectively.
#
# The +update+ callback allows the warners to run without being explicitly
# called.  The system is set up with the +Ticker+ and several observers, and the
# observers do their duty without the top-level code having to interfere.
#
# Note that the contract between publisher and subscriber (observable and
# observer) is not declared or enforced.  The +Ticker+ publishes a time and a
# price, and the warners receive that.  But if you don't ensure that your
# contracts are correct, nothing else can warn you.
#
#   require "observer"
#   
#   class Ticker          ### Periodically fetch a stock price.
#     include Observable
#   
#     def initialize(symbol)
#       @symbol = symbol
#     end
#   
#     def run
#       lastPrice = nil
#       loop do
#         price = Price.fetch(@symbol)
#         print "Current price: #{price}\n"
#         if price != lastPrice
#           changed                 # notify observers
#           lastPrice = price
#           notify_observers(Time.now, price)
#         end
#         sleep 1
#       end
#     end
#   end
#
#   class Price           ### A mock class to fetch a stock price (60 - 140).
#     def Price.fetch(symbol)
#       60 + rand(80)
#     end
#   end
#   
#   class Warner          ### An abstract observer of Ticker objects.
#     def initialize(ticker, limit)
#       @limit = limit
#       ticker.add_observer(self)
#     end
#   end
#   
#   class WarnLow < Warner
#     def update(time, price)       # callback for observer
#       if price < @limit
#         print "--- #{time.to_s}: Price below #@limit: #{price}\n"
#       end
#     end
#   end
#   
#   class WarnHigh < Warner
#     def update(time, price)       # callback for observer
#       if price > @limit
#         print "+++ #{time.to_s}: Price above #@limit: #{price}\n"
#       end
#     end
#   end
#
#   ticker = Ticker.new("MSFT")
#   WarnLow.new(ticker, 80)
#   WarnHigh.new(ticker, 120)
#   ticker.run
#
# Produces:
#
#   Current price: 83
#   Current price: 75
#   --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 75
#   Current price: 90
#   Current price: 134
#   +++ Sun Jun 09 00:10:25 CDT 2002: Price above 120: 134
#   Current price: 134
#   Current price: 112
#   Current price: 79
#   --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 79


#
# Implements the Observable design pattern as a mixin so that other objects can
# be notified of changes in state.  See observer.rb for details and an example.
#
module Observable

  #
  # Add +observer+ as an observer on this object. +observer+ will now receive
  # notifications.
  #
  def add_observer(observer)
    @observer_peers = [] unless defined? @observer_peers
    unless observer.respond_to? :update
      raise NoMethodError, "observer needs to respond to `update'" 
    end
    @observer_peers.push observer
  end

  #
  # Delete +observer+ as an observer on this object. It will no longer receive
  # notifications.
  #
  def delete_observer(observer)
    @observer_peers.delete observer if defined? @observer_peers
  end

  #
  # Delete all observers associated with this object.
  #
  def delete_observers
    @observer_peers.clear if defined? @observer_peers
  end

  #
  # Return the number of observers associated with this object.
  #
  def count_observers
    if defined? @observer_peers
      @observer_peers.size
    else
      0
    end
  end

  #
  # Set the changed state of this object.  Notifications will be sent only if
  # the changed +state+ is +true+.
  #
  def changed(state=true)
    @observer_state = state
  end

  #
  # Query the changed state of this object.
  #
  def changed?
    if defined? @observer_state and @observer_state
      true
    else
      false
    end
  end

  #
  # If this object's changed state is +true+, invoke the update method in each
  # currently associated observer in turn, passing it the given arguments. The
  # changed state is then set to +false+.
  #
  def notify_observers(*arg)
    if defined? @observer_state and @observer_state
      if defined? @observer_peers
	for i in @observer_peers.dup
	  i.update(*arg)
	end
      end
      @observer_state = false
    end
  end

end
PK     Y\aW  W  	  ipaddr.rbnu [        #
# ipaddr.rb - A class to manipulate an IP address
#
# Copyright (c) 2002 Hajimu UMEMOTO <ume@mahoroba.org>.
# Copyright (c) 2007 Akinori MUSHA <knu@iDaemons.org>.
# All rights reserved.
#
# You can redistribute and/or modify it under the same terms as Ruby.
#
# $Id: ipaddr.rb 18049 2008-07-12 15:08:29Z shyouhei $
#
# Contact:
#   - Akinori MUSHA <knu@iDaemons.org> (current maintainer)
#
# TODO:
#   - scope_id support
#
require 'socket'

unless Socket.const_defined? "AF_INET6"
  class Socket
    AF_INET6 = Object.new
  end

  class << IPSocket
    def valid_v4?(addr)
      if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ addr
        return $~.captures.all? {|i| i.to_i < 256}
      end
      return false
    end

    def valid_v6?(addr)
      # IPv6 (normal)
      return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*\Z/ =~ addr
      return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr
      return true if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr
      # IPv6 (IPv4 compat)
      return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:/ =~ addr && valid_v4?($')
      return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr && valid_v4?($')
      return true if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr && valid_v4?($')

      false
    end

    def valid?(addr)
      valid_v4?(addr) || valid_v6?(addr)
    end

    alias getaddress_orig getaddress
    def getaddress(s)
      if valid?(s)
        s
      elsif /\A[-A-Za-z\d.]+\Z/ =~ s
        getaddress_orig(s)
      else
        raise ArgumentError, "invalid address"
      end
    end
  end
end

# IPAddr provides a set of methods to manipulate an IP address.  Both IPv4 and
# IPv6 are supported.
#
# == Example
#
#   require 'ipaddr'
#   
#   ipaddr1 = IPAddr.new "3ffe:505:2::1"
#   
#   p ipaddr1			#=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>
#   
#   p ipaddr1.to_s		#=> "3ffe:505:2::1"
#   
#   ipaddr2 = ipaddr1.mask(48)	#=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>
#   
#   p ipaddr2.to_s		#=> "3ffe:505:2::"
#   
#   ipaddr3 = IPAddr.new "192.168.2.0/24"
#   
#   p ipaddr3			#=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>

class IPAddr

  IN4MASK = 0xffffffff
  IN6MASK = 0xffffffffffffffffffffffffffffffff
  IN6FORMAT = (["%.4x"] * 8).join(':')

  # Returns the address family of this IP address.
  attr :family

  # Creates a new ipaddr containing the given network byte ordered
  # string form of an IP address.
  def IPAddr::new_ntoh(addr)
    return IPAddr.new(IPAddr::ntop(addr))
  end

  # Convert a network byte ordered string form of an IP address into
  # human readable form.
  def IPAddr::ntop(addr)
    case addr.size
    when 4
      s = addr.unpack('C4').join('.')
    when 16
      s = IN6FORMAT % addr.unpack('n8')
    else
      raise ArgumentError, "unsupported address family"
    end
    return s
  end

  # Returns a new ipaddr built by bitwise AND.
  def &(other)
    return self.clone.set(@addr & coerce_other(other).to_i)
  end

  # Returns a new ipaddr built by bitwise OR.
  def |(other)
    return self.clone.set(@addr | coerce_other(other).to_i)
  end

  # Returns a new ipaddr built by bitwise right-shift.
  def >>(num)
    return self.clone.set(@addr >> num)
  end

  # Returns a new ipaddr built by bitwise left shift.
  def <<(num)
    return self.clone.set(addr_mask(@addr << num))
  end

  # Returns a new ipaddr built by bitwise negation.
  def ~
    return self.clone.set(addr_mask(~@addr))
  end

  # Returns true if two ipaddrs are equal.
  def ==(other)
    other = coerce_other(other)
    return @family == other.family && @addr == other.to_i
  end

  # Returns a new ipaddr built by masking IP address with the given
  # prefixlen/netmask. (e.g. 8, 64, "255.255.255.0", etc.)
  def mask(prefixlen)
    return self.clone.mask!(prefixlen)
  end

  # Returns true if the given ipaddr is in the range.
  #
  # e.g.:
  #   require 'ipaddr'
  #   net1 = IPAddr.new("192.168.2.0/24")
  #   net2 = IPAddr.new("192.168.2.100")
  #   net3 = IPAddr.new("192.168.3.0")
  #   p net1.include?(net2)	#=> true
  #   p net1.include?(net3)	#=> false
  def include?(other)
    other = coerce_other(other)
    if ipv4_mapped?
      if (@mask_addr >> 32) != 0xffffffffffffffffffffffff
	return false
      end
      mask_addr = (@mask_addr & IN4MASK)
      addr = (@addr & IN4MASK)
      family = Socket::AF_INET
    else
      mask_addr = @mask_addr
      addr = @addr
      family = @family
    end
    if other.ipv4_mapped?
      other_addr = (other.to_i & IN4MASK)
      other_family = Socket::AF_INET
    else
      other_addr = other.to_i
      other_family = other.family
    end

    if family != other_family
      return false
    end
    return ((addr & mask_addr) == (other_addr & mask_addr))
  end
  alias === include?

  # Returns the integer representation of the ipaddr.
  def to_i
    return @addr
  end

  # Returns a string containing the IP address representation.
  def to_s
    str = to_string
    return str if ipv4?

    str.gsub!(/\b0{1,3}([\da-f]+)\b/i, '\1')
    loop do
      break if str.sub!(/\A0:0:0:0:0:0:0:0\Z/, '::')
      break if str.sub!(/\b0:0:0:0:0:0:0\b/, ':')
      break if str.sub!(/\b0:0:0:0:0:0\b/, ':')
      break if str.sub!(/\b0:0:0:0:0\b/, ':')
      break if str.sub!(/\b0:0:0:0\b/, ':')
      break if str.sub!(/\b0:0:0\b/, ':')
      break if str.sub!(/\b0:0\b/, ':')
      break
    end
    str.sub!(/:{3,}/, '::')

    if /\A::(ffff:)?([\da-f]{1,4}):([\da-f]{1,4})\Z/i =~ str
      str = sprintf('::%s%d.%d.%d.%d', $1, $2.hex / 256, $2.hex % 256, $3.hex / 256, $3.hex % 256)
    end

    str
  end

  # Returns a string containing the IP address representation in
  # canonical form.
  def to_string
    return _to_string(@addr)
  end

  # Returns a network byte ordered string form of the IP address.
  def hton
    case @family
    when Socket::AF_INET
      return [@addr].pack('N')
    when Socket::AF_INET6
      return (0..7).map { |i|
	(@addr >> (112 - 16 * i)) & 0xffff
      }.pack('n8')
    else
      raise "unsupported address family"
    end
  end

  # Returns true if the ipaddr is an IPv4 address.
  def ipv4?
    return @family == Socket::AF_INET
  end

  # Returns true if the ipaddr is an IPv6 address.
  def ipv6?
    return @family == Socket::AF_INET6
  end

  # Returns true if the ipaddr is an IPv4-mapped IPv6 address.
  def ipv4_mapped?
    return ipv6? && (@addr >> 32) == 0xffff
  end

  # Returns true if the ipaddr is an IPv4-compatible IPv6 address.
  def ipv4_compat?
    if !ipv6? || (@addr >> 32) != 0
      return false
    end
    a = (@addr & IN4MASK)
    return a != 0 && a != 1
  end

  # Returns a new ipaddr built by converting the native IPv4 address
  # into an IPv4-mapped IPv6 address.
  def ipv4_mapped
    if !ipv4?
      raise ArgumentError, "not an IPv4 address"
    end
    return self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
  end

  # Returns a new ipaddr built by converting the native IPv4 address
  # into an IPv4-compatible IPv6 address.
  def ipv4_compat
    if !ipv4?
      raise ArgumentError, "not an IPv4 address"
    end
    return self.clone.set(@addr, Socket::AF_INET6)
  end

  # Returns a new ipaddr built by converting the IPv6 address into a
  # native IPv4 address.  If the IP address is not an IPv4-mapped or
  # IPv4-compatible IPv6 address, returns self.
  def native
    if !ipv4_mapped? && !ipv4_compat?
      return self
    end
    return self.clone.set(@addr & IN4MASK, Socket::AF_INET)
  end

  # Returns a string for DNS reverse lookup.  It returns a string in
  # RFC3172 form for an IPv6 address.
  def reverse
    case @family
    when Socket::AF_INET
      return _reverse + ".in-addr.arpa"
    when Socket::AF_INET6
      return ip6_arpa
    else
      raise "unsupported address family"
    end
  end

  # Returns a string for DNS reverse lookup compatible with RFC3172.
  def ip6_arpa
    if !ipv6?
      raise ArgumentError, "not an IPv6 address"
    end
    return _reverse + ".ip6.arpa"
  end

  # Returns a string for DNS reverse lookup compatible with RFC1886.
  def ip6_int
    if !ipv6?
      raise ArgumentError, "not an IPv6 address"
    end
    return _reverse + ".ip6.int"
  end

  # Returns the successor to the ipaddr.
  def succ
    return self.clone.set(@addr + 1, @family)
  end

  # Compares the ipaddr with another.
  def <=>(other)
    other = coerce_other(other)

    return nil if other.family != @family

    return @addr <=> other.to_i
  end
  include Comparable

  # Creates a Range object for the network address.
  def to_range
    begin_addr = (@addr & @mask_addr)

    case @family
    when Socket::AF_INET
      end_addr = (@addr | (IN4MASK ^ @mask_addr))
    when Socket::AF_INET6
      end_addr = (@addr | (IN6MASK ^ @mask_addr))
    else
      raise "unsupported address family"
    end

    return clone.set(begin_addr, @family)..clone.set(end_addr, @family)
  end

  # Returns a string containing a human-readable representation of the
  # ipaddr. ("#<IPAddr: family:address/mask>")
  def inspect
    case @family
    when Socket::AF_INET
      af = "IPv4"
    when Socket::AF_INET6
      af = "IPv6"
    else
      raise "unsupported address family"
    end
    return sprintf("#<%s: %s:%s/%s>", self.class.name,
		   af, _to_string(@addr), _to_string(@mask_addr))
  end

  protected

  def set(addr, *family)
    case family[0] ? family[0] : @family
    when Socket::AF_INET
      if addr < 0 || addr > IN4MASK
	raise ArgumentError, "invalid address"
      end
    when Socket::AF_INET6
      if addr < 0 || addr > IN6MASK
	raise ArgumentError, "invalid address"
      end
    else
      raise ArgumentError, "unsupported address family"
    end
    @addr = addr
    if family[0]
      @family = family[0]
    end
    return self
  end

  def mask!(mask)
    if mask.kind_of?(String)
      if mask =~ /^\d+$/
	prefixlen = mask.to_i
      else
	m = IPAddr.new(mask)
	if m.family != @family
	  raise ArgumentError, "address family is not same"
	end
	@mask_addr = m.to_i
	@addr &= @mask_addr
	return self
      end
    else
      prefixlen = mask
    end
    case @family
    when Socket::AF_INET
      if prefixlen < 0 || prefixlen > 32
	raise ArgumentError, "invalid length"
      end
      masklen = 32 - prefixlen
      @mask_addr = ((IN4MASK >> masklen) << masklen)
    when Socket::AF_INET6
      if prefixlen < 0 || prefixlen > 128
	raise ArgumentError, "invalid length"
      end
      masklen = 128 - prefixlen
      @mask_addr = ((IN6MASK >> masklen) << masklen)
    else
      raise "unsupported address family"
    end
    @addr = ((@addr >> masklen) << masklen)
    return self
  end

  private

  # Creates a new ipaddr object either from a human readable IP
  # address representation in string, or from a packed in_addr value
  # followed by an address family.
  # 
  # In the former case, the following are the valid formats that will
  # be recognized: "address", "address/prefixlen" and "address/mask",
  # where IPv6 address may be enclosed in square brackets (`[' and
  # `]').  If a prefixlen or a mask is specified, it returns a masked
  # IP address.  Although the address family is determined
  # automatically from a specified string, you can specify one
  # explicitly by the optional second argument.
  # 
  # Otherwise an IP addess is generated from a packed in_addr value
  # and an address family.
  #
  # The IPAddr class defines many methods and operators, and some of
  # those, such as &, |, include? and ==, accept a string, or a packed
  # in_addr value instead of an IPAddr object.
  def initialize(addr = '::', family = Socket::AF_UNSPEC)
    if !addr.kind_of?(String)
      case family
      when Socket::AF_INET, Socket::AF_INET6
        set(addr.to_i, family)
        @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
        return
      when Socket::AF_UNSPEC
	raise ArgumentError, "address family must be specified"
      else
	raise ArgumentError, "unsupported address family: #{family}"
      end
    end
    prefix, prefixlen = addr.split('/')
    if prefix =~ /^\[(.*)\]$/i
      prefix = $1
      family = Socket::AF_INET6
    end
    # It seems AI_NUMERICHOST doesn't do the job.
    #Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,
    #		       Socket::AI_NUMERICHOST)
    begin
      IPSocket.getaddress(prefix)		# test if address is vaild
    rescue
      raise ArgumentError, "invalid address"
    end
    @addr = @family = nil
    if family == Socket::AF_UNSPEC || family == Socket::AF_INET
      @addr = in_addr(prefix)
      if @addr
	@family = Socket::AF_INET
      end
    end
    if !@addr && (family == Socket::AF_UNSPEC || family == Socket::AF_INET6)
      @addr = in6_addr(prefix)
      @family = Socket::AF_INET6
    end
    if family != Socket::AF_UNSPEC && @family != family
      raise ArgumentError, "address family mismatch"
    end
    if prefixlen
      mask!(prefixlen)
    else
      @mask_addr = (@family == Socket::AF_INET) ? IN4MASK : IN6MASK
    end
  end

  def coerce_other(other)
    case other
    when IPAddr
      other
    when String
      self.class.new(other)
    else
      self.class.new(other, @family)
    end
  end

  def in_addr(addr)
    if addr =~ /^\d+\.\d+\.\d+\.\d+$/
      return addr.split('.').inject(0) { |i, s|
        i << 8 | s.to_i
      }
    end
    return nil
  end

  def in6_addr(left)
    case left
    when /^::ffff:(\d+\.\d+\.\d+\.\d+)$/i
      return in_addr($1) + 0xffff00000000
    when /^::(\d+\.\d+\.\d+\.\d+)$/i
      return in_addr($1)
    when /[^0-9a-f:]/i
      raise ArgumentError, "invalid address"
    when /^(.*)::(.*)$/
      left, right = $1, $2
    else
      right = ''
    end
    l = left.split(':')
    r = right.split(':')
    rest = 8 - l.size - r.size
    if rest < 0
      return nil
    end
    return (l + Array.new(rest, '0') + r).inject(0) { |i, s|
      i << 16 | s.hex
    }
  end

  def addr_mask(addr)
    case @family
    when Socket::AF_INET
      return addr & IN4MASK
    when Socket::AF_INET6
      return addr & IN6MASK
    else
      raise "unsupported address family"
    end
  end

  def _reverse
    case @family
    when Socket::AF_INET
      return (0..3).map { |i|
	(@addr >> (8 * i)) & 0xff
      }.join('.')
    when Socket::AF_INET6
      return ("%.32x" % @addr).reverse!.gsub!(/.(?!$)/, '\&.')
    else
      raise "unsupported address family"
    end
  end

  def _to_string(addr)
    case @family
    when Socket::AF_INET
      return (0..3).map { |i|
	(addr >> (24 - 8 * i)) & 0xff
      }.join('.')
    when Socket::AF_INET6
      return (("%.32x" % addr).gsub!(/.{4}(?!$)/, '\&:'))
    else
      raise "unsupported address family"
    end
  end

end

if $0 == __FILE__
  eval DATA.read, nil, $0, __LINE__+4
end

__END__

require 'test/unit'
require 'test/unit/ui/console/testrunner'

class TC_IPAddr < Test::Unit::TestCase
  def test_s_new
    assert_nothing_raised {
      IPAddr.new("3FFE:505:ffff::/48")
      IPAddr.new("0:0:0:1::")
      IPAddr.new("2001:200:300::/48")
    }

    a = IPAddr.new
    assert_equal("::", a.to_s)
    assert_equal("0000:0000:0000:0000:0000:0000:0000:0000", a.to_string)
    assert_equal(Socket::AF_INET6, a.family)

    a = IPAddr.new("0123:4567:89ab:cdef:0ABC:DEF0:1234:5678")
    assert_equal("123:4567:89ab:cdef:abc:def0:1234:5678", a.to_s)
    assert_equal("0123:4567:89ab:cdef:0abc:def0:1234:5678", a.to_string)
    assert_equal(Socket::AF_INET6, a.family)

    a = IPAddr.new("3ffe:505:2::/48")
    assert_equal("3ffe:505:2::", a.to_s)
    assert_equal("3ffe:0505:0002:0000:0000:0000:0000:0000", a.to_string)
    assert_equal(Socket::AF_INET6, a.family)
    assert_equal(false, a.ipv4?)
    assert_equal(true, a.ipv6?)
    assert_equal("#<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>", a.inspect)

    a = IPAddr.new("3ffe:505:2::/ffff:ffff:ffff::")
    assert_equal("3ffe:505:2::", a.to_s)
    assert_equal("3ffe:0505:0002:0000:0000:0000:0000:0000", a.to_string)
    assert_equal(Socket::AF_INET6, a.family)

    a = IPAddr.new("0.0.0.0")
    assert_equal("0.0.0.0", a.to_s)
    assert_equal("0.0.0.0", a.to_string)
    assert_equal(Socket::AF_INET, a.family)

    a = IPAddr.new("192.168.1.2")
    assert_equal("192.168.1.2", a.to_s)
    assert_equal("192.168.1.2", a.to_string)
    assert_equal(Socket::AF_INET, a.family)
    assert_equal(true, a.ipv4?)
    assert_equal(false, a.ipv6?)

    a = IPAddr.new("192.168.1.2/24")
    assert_equal("192.168.1.0", a.to_s)
    assert_equal("192.168.1.0", a.to_string)
    assert_equal(Socket::AF_INET, a.family)
    assert_equal("#<IPAddr: IPv4:192.168.1.0/255.255.255.0>", a.inspect)

    a = IPAddr.new("192.168.1.2/255.255.255.0")
    assert_equal("192.168.1.0", a.to_s)
    assert_equal("192.168.1.0", a.to_string)
    assert_equal(Socket::AF_INET, a.family)

    assert_equal("0:0:0:1::", IPAddr.new("0:0:0:1::").to_s)
    assert_equal("2001:200:300::", IPAddr.new("2001:200:300::/48").to_s)

    assert_equal("2001:200:300::", IPAddr.new("[2001:200:300::]/48").to_s)

    [
      ["fe80::1%fxp0"],
      ["::1/255.255.255.0"],
      ["::1:192.168.1.2/120"],
      [IPAddr.new("::1").to_i],
      ["::ffff:192.168.1.2/120", Socket::AF_INET],
      ["[192.168.1.2]/120"],
    ].each { |args|
      assert_raises(ArgumentError) {
	IPAddr.new(*args)
      }
    }
  end

  def test_s_new_ntoh
    addr = ''
    IPAddr.new("1234:5678:9abc:def0:1234:5678:9abc:def0").hton.each_byte { |c|
      addr += sprintf("%02x", c)
    }
    assert_equal("123456789abcdef0123456789abcdef0", addr)
    addr = ''
    IPAddr.new("123.45.67.89").hton.each_byte { |c|
      addr += sprintf("%02x", c)
    }
    assert_equal(sprintf("%02x%02x%02x%02x", 123, 45, 67, 89), addr)
    a = IPAddr.new("3ffe:505:2::")
    assert_equal("3ffe:505:2::", IPAddr.new_ntoh(a.hton).to_s)
    a = IPAddr.new("192.168.2.1")
    assert_equal("192.168.2.1", IPAddr.new_ntoh(a.hton).to_s)
  end

  def test_ipv4_compat
    a = IPAddr.new("::192.168.1.2")
    assert_equal("::192.168.1.2", a.to_s)
    assert_equal("0000:0000:0000:0000:0000:0000:c0a8:0102", a.to_string)
    assert_equal(Socket::AF_INET6, a.family)
    assert_equal(true, a.ipv4_compat?)
    b = a.native
    assert_equal("192.168.1.2", b.to_s)
    assert_equal(Socket::AF_INET, b.family)
    assert_equal(false, b.ipv4_compat?)

    a = IPAddr.new("192.168.1.2")
    b = a.ipv4_compat
    assert_equal("::192.168.1.2", b.to_s)
    assert_equal(Socket::AF_INET6, b.family)
  end

  def test_ipv4_mapped
    a = IPAddr.new("::ffff:192.168.1.2")
    assert_equal("::ffff:192.168.1.2", a.to_s)
    assert_equal("0000:0000:0000:0000:0000:ffff:c0a8:0102", a.to_string)
    assert_equal(Socket::AF_INET6, a.family)
    assert_equal(true, a.ipv4_mapped?)
    b = a.native
    assert_equal("192.168.1.2", b.to_s)
    assert_equal(Socket::AF_INET, b.family)
    assert_equal(false, b.ipv4_mapped?)

    a = IPAddr.new("192.168.1.2")
    b = a.ipv4_mapped
    assert_equal("::ffff:192.168.1.2", b.to_s)
    assert_equal(Socket::AF_INET6, b.family)
  end

  def test_reverse
    assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa", IPAddr.new("3ffe:505:2::f").reverse)
    assert_equal("1.2.168.192.in-addr.arpa", IPAddr.new("192.168.2.1").reverse)
  end

  def test_ip6_arpa
    assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa", IPAddr.new("3ffe:505:2::f").ip6_arpa)
    assert_raises(ArgumentError) {
      IPAddr.new("192.168.2.1").ip6_arpa
    }
  end

  def test_ip6_int
    assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.int", IPAddr.new("3ffe:505:2::f").ip6_int)
    assert_raises(ArgumentError) {
      IPAddr.new("192.168.2.1").ip6_int
    }
  end

  def test_to_s
    assert_equal("3ffe:0505:0002:0000:0000:0000:0000:0001", IPAddr.new("3ffe:505:2::1").to_string)
    assert_equal("3ffe:505:2::1", IPAddr.new("3ffe:505:2::1").to_s)
  end
end

class TC_Operator < Test::Unit::TestCase

  IN6MASK32  = "ffff:ffff::"
  IN6MASK128 = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"

  def setup
    @in6_addr_any = IPAddr.new()
    @a = IPAddr.new("3ffe:505:2::/48")
    @b = IPAddr.new("0:0:0:1::")
    @c = IPAddr.new(IN6MASK32)
  end
  alias set_up setup

  def test_or
    assert_equal("3ffe:505:2:1::", (@a | @b).to_s)
    a = @a
    a |= @b
    assert_equal("3ffe:505:2:1::", a.to_s)
    assert_equal("3ffe:505:2::", @a.to_s)
    assert_equal("3ffe:505:2:1::",
		 (@a | 0x00000000000000010000000000000000).to_s)
  end

  def test_and
    assert_equal("3ffe:505::", (@a & @c).to_s)
    a = @a
    a &= @c
    assert_equal("3ffe:505::", a.to_s)
    assert_equal("3ffe:505:2::", @a.to_s)
    assert_equal("3ffe:505::", (@a & 0xffffffff000000000000000000000000).to_s)
  end

  def test_shift_right
    assert_equal("0:3ffe:505:2::", (@a >> 16).to_s)
    a = @a
    a >>= 16
    assert_equal("0:3ffe:505:2::", a.to_s)
    assert_equal("3ffe:505:2::", @a.to_s)
  end

  def test_shift_left
    assert_equal("505:2::", (@a << 16).to_s)
    a = @a
    a <<= 16
    assert_equal("505:2::", a.to_s)
    assert_equal("3ffe:505:2::", @a.to_s)
  end

  def test_carrot
    a = ~@in6_addr_any
    assert_equal(IN6MASK128, a.to_s)
    assert_equal("::", @in6_addr_any.to_s)
  end

  def test_equal
    assert_equal(true, @a == IPAddr.new("3ffe:505:2::"))
    assert_equal(false, @a == IPAddr.new("3ffe:505:3::"))
    assert_equal(true, @a != IPAddr.new("3ffe:505:3::"))
    assert_equal(false, @a != IPAddr.new("3ffe:505:2::"))
  end

  def test_mask
    a = @a.mask(32)
    assert_equal("3ffe:505::", a.to_s)
    assert_equal("3ffe:505:2::", @a.to_s)
  end

  def test_include?
    assert_equal(true, @a.include?(IPAddr.new("3ffe:505:2::")))
    assert_equal(true, @a.include?(IPAddr.new("3ffe:505:2::1")))
    assert_equal(false, @a.include?(IPAddr.new("3ffe:505:3::")))
    net1 = IPAddr.new("192.168.2.0/24")
    assert_equal(true, net1.include?(IPAddr.new("192.168.2.0")))
    assert_equal(true, net1.include?(IPAddr.new("192.168.2.255")))
    assert_equal(false, net1.include?(IPAddr.new("192.168.3.0")))
    # test with integer parameter
    int = (192 << 24) + (168 << 16) + (2 << 8) + 13

    assert_equal(true, net1.include?(int))
    assert_equal(false, net1.include?(int+255))

  end

end
PK     Y\8  8    rinda/ring.rbnu [        #
# Note: Rinda::Ring API is unstable.
#
require 'drb/drb'
require 'rinda/rinda'
require 'thread'

module Rinda

  ##
  # The default port Ring discovery will use.

  Ring_PORT = 7647

  ##
  # A RingServer allows a Rinda::TupleSpace to be located via UDP broadcasts.
  # Service location uses the following steps:
  #
  # 1. A RingServer begins listening on the broadcast UDP address.
  # 2. A RingFinger sends a UDP packet containing the DRb URI where it will
  #    listen for a reply.
  # 3. The RingServer receives the UDP packet and connects back to the
  #    provided DRb URI with the DRb service.

  class RingServer

    include DRbUndumped

    ##
    # Advertises +ts+ on the UDP broadcast address at +port+.

    def initialize(ts, port=Ring_PORT)
      @ts = ts
      @soc = UDPSocket.open
      @soc.bind('', port)
      @w_service = write_service
      @r_service = reply_service
    end

    ##
    # Creates a thread that picks up UDP packets and passes them to do_write
    # for decoding.

    def write_service
      Thread.new do
	loop do
	  msg = @soc.recv(1024)
	  do_write(msg)
	end
      end
    end
  
    ##
    # Extracts the response URI from +msg+ and adds it to TupleSpace where it
    # will be picked up by +reply_service+ for notification.

    def do_write(msg)
      Thread.new do
	begin
	  tuple, sec = Marshal.load(msg)
	  @ts.write(tuple, sec)
	rescue
	end
      end
    end

    ##
    # Creates a thread that notifies waiting clients from the TupleSpace.

    def reply_service
      Thread.new do
	loop do
	  do_reply
	end
      end
    end
    
    ##
    # Pulls lookup tuples out of the TupleSpace and sends their DRb object the
    # address of the local TupleSpace.

    def do_reply
      tuple = @ts.take([:lookup_ring, nil])
      Thread.new { tuple[1].call(@ts) rescue nil}
    rescue
    end

  end

  ##
  # RingFinger is used by RingServer clients to discover the RingServer's
  # TupleSpace.  Typically, all a client needs to do is call
  # RingFinger.primary to retrieve the remote TupleSpace, which it can then
  # begin using.

  class RingFinger

    @@broadcast_list = ['<broadcast>', 'localhost']

    @@finger = nil

    ##
    # Creates a singleton RingFinger and looks for a RingServer.  Returns the
    # created RingFinger.

    def self.finger
      unless @@finger 
	@@finger = self.new
	@@finger.lookup_ring_any
      end
      @@finger
    end

    ##
    # Returns the first advertised TupleSpace.

    def self.primary
      finger.primary
    end

    ##
    # Contains all discovered TupleSpaces except for the primary.

    def self.to_a
      finger.to_a
    end

    ##
    # The list of addresses where RingFinger will send query packets.

    attr_accessor :broadcast_list

    ##
    # The port that RingFinger will send query packets to.

    attr_accessor :port

    ##
    # Contain the first advertised TupleSpace after lookup_ring_any is called.

    attr_accessor :primary

    ##
    # Creates a new RingFinger that will look for RingServers at +port+ on
    # the addresses in +broadcast_list+.

    def initialize(broadcast_list=@@broadcast_list, port=Ring_PORT)
      @broadcast_list = broadcast_list || ['localhost']
      @port = port
      @primary = nil
      @rings = []
    end

    ##
    # Contains all discovered TupleSpaces except for the primary.

    def to_a
      @rings
    end

    ##
    # Iterates over all discovered TupleSpaces starting with the primary.

    def each
      lookup_ring_any unless @primary
      return unless @primary
      yield(@primary)
      @rings.each { |x| yield(x) }
    end

    ##
    # Looks up RingServers waiting +timeout+ seconds.  RingServers will be
    # given +block+ as a callback, which will be called with the remote
    # TupleSpace.

    def lookup_ring(timeout=5, &block)
      return lookup_ring_any(timeout) unless block_given?

      msg = Marshal.dump([[:lookup_ring, DRbObject.new(block)], timeout])
      @broadcast_list.each do |it|
	soc = UDPSocket.open
	begin
	  soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
	  soc.send(msg, 0, it, @port)
	rescue
	  nil
	ensure
	  soc.close
	end
      end
      sleep(timeout)
    end

    ##
    # Returns the first found remote TupleSpace.  Any further recovered
    # TupleSpaces can be found by calling +to_a+.

    def lookup_ring_any(timeout=5)
      queue = Queue.new

      th = Thread.new do
	self.lookup_ring(timeout) do |ts|
	  queue.push(ts)
	end
	queue.push(nil)
	while it = queue.pop
	  @rings.push(it)
	end
      end
      
      @primary = queue.pop
      raise('RingNotFound') if @primary.nil?
      @primary
    end

  end

  ##
  # RingProvider uses a RingServer advertised TupleSpace as a name service.
  # TupleSpace clients can register themselves with the remote TupleSpace and
  # look up other provided services via the remote TupleSpace.
  #
  # Services are registered with a tuple of the format [:name, klass,
  # DRbObject, description].

  class RingProvider

    ##
    # Creates a RingProvider that will provide a +klass+ service running on
    # +front+, with a +description+.  +renewer+ is optional.

    def initialize(klass, front, desc, renewer = nil)
      @tuple = [:name, klass, front, desc]
      @renewer = renewer || Rinda::SimpleRenewer.new
    end

    ##
    # Advertises this service on the primary remote TupleSpace.

    def provide
      ts = Rinda::RingFinger.primary
      ts.write(@tuple, @renewer)
    end

  end

end

if __FILE__ == $0
  DRb.start_service
  case ARGV.shift
  when 's'
    require 'rinda/tuplespace'
    ts = Rinda::TupleSpace.new
    place = Rinda::RingServer.new(ts)
    $stdin.gets
  when 'w'
    finger = Rinda::RingFinger.new(nil)
    finger.lookup_ring do |ts|
      p ts
      ts.write([:hello, :world])
    end
  when 'r'
    finger = Rinda::RingFinger.new(nil)
    finger.lookup_ring do |ts|
      p ts
      p ts.take([nil, nil])
    end
  end
end

PK     Y\zn@?  ?    rinda/rinda.rbnu [        require 'drb/drb'
require 'thread'

##
# A module to implement the Linda distributed computing paradigm in Ruby.
#
# Rinda is part of DRb (dRuby).
#
# == Example(s)
#
# See the sample/drb/ directory in the Ruby distribution, from 1.8.2 onwards.
#
#--
# TODO
# == Introduction to Linda/rinda?
#
# == Why is this library separate from DRb?

module Rinda

  ##
  # Rinda error base class

  class RindaError < RuntimeError; end

  ##
  # Raised when a hash-based tuple has an invalid key.

  class InvalidHashTupleKey < RindaError; end

  ##
  # Raised when trying to use a canceled tuple.

  class RequestCanceledError < ThreadError; end

  ##
  # Raised when trying to use an expired tuple.

  class RequestExpiredError < ThreadError; end

  ##
  # A tuple is the elementary object in Rinda programming.
  # Tuples may be matched against templates if the tuple and
  # the template are the same size.

  class Tuple

    ##
    # Creates a new Tuple from +ary_or_hash+ which must be an Array or Hash.

    def initialize(ary_or_hash)
      if hash?(ary_or_hash)
        init_with_hash(ary_or_hash)
      else
        init_with_ary(ary_or_hash)
      end
    end

    ##
    # The number of elements in the tuple.
    
    def size
      @tuple.size
    end

    ##
    # Accessor method for elements of the tuple.

    def [](k)
      @tuple[k]
    end

    ##
    # Fetches item +k+ from the tuple.

    def fetch(k)
      @tuple.fetch(k)
    end

    ##
    # Iterate through the tuple, yielding the index or key, and the
    # value, thus ensuring arrays are iterated similarly to hashes.

    def each # FIXME
      if Hash === @tuple
        @tuple.each { |k, v| yield(k, v) }
      else
        @tuple.each_with_index { |v, k| yield(k, v) }
      end
    end

    ##
    # Return the tuple itself
    def value
      @tuple
    end

    private

    def hash?(ary_or_hash)
      ary_or_hash.respond_to?(:keys)
    end

    ##
    # Munges +ary+ into a valid Tuple.

    def init_with_ary(ary)
      @tuple = Array.new(ary.size)
      @tuple.size.times do |i|
        @tuple[i] = ary[i]
      end
    end

    ##
    # Ensures +hash+ is a valid Tuple.

    def init_with_hash(hash)
      @tuple = Hash.new
      hash.each do |k, v|
        raise InvalidHashTupleKey unless String === k
        @tuple[k] = v
      end
    end

  end

  ##
  # Templates are used to match tuples in Rinda.

  class Template < Tuple

    ##
    # Matches this template against +tuple+.  The +tuple+ must be the same
    # size as the template.  An element with a +nil+ value in a template acts
    # as a wildcard, matching any value in the corresponding position in the
    # tuple.  Elements of the template match the +tuple+ if the are #== or
    # #===.
    #
    #   Template.new([:foo, 5]).match   Tuple.new([:foo, 5]) # => true
    #   Template.new([:foo, nil]).match Tuple.new([:foo, 5]) # => true
    #   Template.new([String]).match    Tuple.new(['hello']) # => true
    #
    #   Template.new([:foo]).match      Tuple.new([:foo, 5]) # => false
    #   Template.new([:foo, 6]).match   Tuple.new([:foo, 5]) # => false
    #   Template.new([:foo, nil]).match Tuple.new([:foo])    # => false
    #   Template.new([:foo, 6]).match   Tuple.new([:foo])    # => false

    def match(tuple)
      return false unless tuple.respond_to?(:size)
      return false unless tuple.respond_to?(:fetch)
      return false unless self.size == tuple.size
      each do |k, v|
        begin
          it = tuple.fetch(k)
        rescue
          return false
        end
        next if v.nil?
        next if v == it
        next if v === it
        return false
      end
      return true
    end
    
    ##
    # Alias for #match.

    def ===(tuple)
      match(tuple)
    end

  end
  
  ##
  # <i>Documentation?</i>

  class DRbObjectTemplate

    ##
    # Creates a new DRbObjectTemplate that will match against +uri+ and +ref+.

    def initialize(uri=nil, ref=nil)
      @drb_uri = uri
      @drb_ref = ref
    end
    
    ##
    # This DRbObjectTemplate matches +ro+ if the remote object's drburi and
    # drbref are the same.  +nil+ is used as a wildcard.

    def ===(ro)
      return true if super(ro)
      unless @drb_uri.nil?
        return false unless (@drb_uri === ro.__drburi rescue false)
      end
      unless @drb_ref.nil?
        return false unless (@drb_ref === ro.__drbref rescue false)
      end
      true
    end

  end

  ##
  # TupleSpaceProxy allows a remote Tuplespace to appear as local.

  class TupleSpaceProxy

    ##
    # Creates a new TupleSpaceProxy to wrap +ts+.

    def initialize(ts)
      @ts = ts
    end
    
    ##
    # Adds +tuple+ to the proxied TupleSpace.  See TupleSpace#write.

    def write(tuple, sec=nil)
      @ts.write(tuple, sec)
    end
    
    ##
    # Takes +tuple+ from the proxied TupleSpace.  See TupleSpace#take.

    def take(tuple, sec=nil, &block)
      port = []
      @ts.move(DRbObject.new(port), tuple, sec, &block)
      port[0]
    end
    
    ##
    # Reads +tuple+ from the proxied TupleSpace.  See TupleSpace#read.

    def read(tuple, sec=nil, &block)
      @ts.read(tuple, sec, &block)
    end
    
    ##
    # Reads all tuples matching +tuple+ from the proxied TupleSpace.  See
    # TupleSpace#read_all.

    def read_all(tuple)
      @ts.read_all(tuple)
    end
    
    ##
    # Registers for notifications of event +ev+ on the proxied TupleSpace.
    # See TupleSpace#notify

    def notify(ev, tuple, sec=nil)
      @ts.notify(ev, tuple, sec)
    end

  end

  ##
  # An SimpleRenewer allows a TupleSpace to check if a TupleEntry is still
  # alive.

  class SimpleRenewer

    include DRbUndumped

    ##
    # Creates a new SimpleRenewer that keeps an object alive for another +sec+
    # seconds.

    def initialize(sec=180)
      @sec = sec
    end

    ##
    # Called by the TupleSpace to check if the object is still alive.

    def renew
      @sec
    end
  end

end

PK     Y\гJ7  7    rinda/tuplespace.rbnu [        require 'monitor'
require 'thread'
require 'drb/drb'
require 'rinda/rinda'
require 'enumerator'
require 'forwardable'

module Rinda

  ##
  # A TupleEntry is a Tuple (i.e. a possible entry in some Tuplespace)
  # together with expiry and cancellation data.

  class TupleEntry

    include DRbUndumped

    attr_accessor :expires

    ##
    # Creates a TupleEntry based on +ary+ with an optional renewer or expiry
    # time +sec+.
    #
    # A renewer must implement the +renew+ method which returns a Numeric,
    # nil, or true to indicate when the tuple has expired.

    def initialize(ary, sec=nil)
      @cancel = false
      @expires = nil
      @tuple = make_tuple(ary)
      @renewer = nil
      renew(sec)
    end

    ##
    # Marks this TupleEntry as canceled.

    def cancel
      @cancel = true
    end

    ##
    # A TupleEntry is dead when it is canceled or expired.

    def alive?
      !canceled? && !expired?
    end

    ##
    # Return the object which makes up the tuple itself: the Array
    # or Hash.

    def value; @tuple.value; end

    ##
    # Returns the canceled status.

    def canceled?; @cancel; end

    ##
    # Has this tuple expired? (true/false).
    #
    # A tuple has expired when its expiry timer based on the +sec+ argument to
    # #initialize runs out.

    def expired?
      return true unless @expires
      return false if @expires > Time.now
      return true if @renewer.nil?
      renew(@renewer)
      return true unless @expires
      return @expires < Time.now
    end

    ##
    # Reset the expiry time according to +sec_or_renewer+.  
    #
    # +nil+::    it is set to expire in the far future.
    # +false+::  it has expired.
    # Numeric::  it will expire in that many seconds.
    #
    # Otherwise the argument refers to some kind of renewer object
    # which will reset its expiry time. 

    def renew(sec_or_renewer)
      sec, @renewer = get_renewer(sec_or_renewer)
      @expires = make_expires(sec)
    end

    ##
    # Returns an expiry Time based on +sec+ which can be one of:
    # Numeric:: +sec+ seconds into the future
    # +true+::  the expiry time is the start of 1970 (i.e. expired)
    # +nil+::   it is  Tue Jan 19 03:14:07 GMT Standard Time 2038 (i.e. when
    #           UNIX clocks will die)

    def make_expires(sec=nil)
      case sec
      when Numeric
        Time.now + sec
      when true
        Time.at(1)
      when nil
        Time.at(2**31-1)
      end
    end

    ##
    # Retrieves +key+ from the tuple.

    def [](key)
      @tuple[key]
    end

    ##
    # Fetches +key+ from the tuple.

    def fetch(key)
      @tuple.fetch(key)
    end

    ##
    # The size of the tuple.

    def size
      @tuple.size
    end

    ##
    # Creates a Rinda::Tuple for +ary+.

    def make_tuple(ary)
      Rinda::Tuple.new(ary)
    end

    private

    ##
    # Returns a valid argument to make_expires and the renewer or nil.
    #
    # Given +true+, +nil+, or Numeric, returns that value and +nil+ (no actual
    # renewer).  Otherwise it returns an expiry value from calling +it.renew+
    # and the renewer.

    def get_renewer(it)
      case it
      when Numeric, true, nil
        return it, nil
      else
        begin
          return it.renew, it
        rescue Exception
          return it, nil
        end
      end
    end

  end

  ##
  # A TemplateEntry is a Template together with expiry and cancellation data.

  class TemplateEntry < TupleEntry
    ##
    # Matches this TemplateEntry against +tuple+.  See Template#match for
    # details on how a Template matches a Tuple.

    def match(tuple)
      @tuple.match(tuple)
    end
    
    alias === match

    def make_tuple(ary) # :nodoc:
      Rinda::Template.new(ary)
    end

  end

  ##
  # <i>Documentation?</i>

  class WaitTemplateEntry < TemplateEntry

    attr_reader :found

    def initialize(place, ary, expires=nil)
      super(ary, expires)
      @place = place
      @cond = place.new_cond
      @found = nil
    end

    def cancel
      super
      signal
    end

    def wait
      @cond.wait
    end

    def read(tuple)
      @found = tuple
      signal
    end

    def signal
      @place.synchronize do
        @cond.signal
      end
    end

  end

  ##
  # A NotifyTemplateEntry is returned by TupleSpace#notify and is notified of
  # TupleSpace changes.  You may receive either your subscribed event or the
  # 'close' event when iterating over notifications.
  #
  # See TupleSpace#notify_event for valid notification types.
  #
  # == Example
  #
  #   ts = Rinda::TupleSpace.new
  #   observer = ts.notify 'write', [nil]
  #   
  #   Thread.start do
  #     observer.each { |t| p t }
  #   end
  #   
  #   3.times { |i| ts.write [i] }
  #
  # Outputs:
  #
  #   ['write', [0]]
  #   ['write', [1]]
  #   ['write', [2]]

  class NotifyTemplateEntry < TemplateEntry

    ##
    # Creates a new NotifyTemplateEntry that watches +place+ for +event+s that
    # match +tuple+.

    def initialize(place, event, tuple, expires=nil)
      ary = [event, Rinda::Template.new(tuple)]
      super(ary, expires)
      @queue = Queue.new
      @done = false
    end

    ##
    # Called by TupleSpace to notify this NotifyTemplateEntry of a new event.

    def notify(ev)
      @queue.push(ev)
    end

    ##
    # Retrieves a notification.  Raises RequestExpiredError when this
    # NotifyTemplateEntry expires.

    def pop
      raise RequestExpiredError if @done
      it = @queue.pop
      @done = true if it[0] == 'close'
      return it
    end

    ##
    # Yields event/tuple pairs until this NotifyTemplateEntry expires.

    def each # :yields: event, tuple
      while !@done
        it = pop
        yield(it)
      end
    rescue 
    ensure
      cancel
    end

  end

  ##
  # TupleBag is an unordered collection of tuples. It is the basis
  # of Tuplespace.

  class TupleBag
    class TupleBin
      extend Forwardable
      def_delegators '@bin', :find_all, :delete_if, :each, :empty?

      def initialize
        @bin = []
      end
      
      def add(tuple)
        @bin.push(tuple)
      end
      
      def delete(tuple)
        idx = @bin.rindex(tuple)
        @bin.delete_at(idx) if idx
      end
      
      def find(&blk)
        @bin.reverse_each do |x|
          return x if yield(x)
        end
        nil
      end
    end

    def initialize # :nodoc:
      @hash = {}
      @enum = Enumerable::Enumerator.new(self, :each_entry)
    end

    ##
    # +true+ if the TupleBag to see if it has any expired entries.

    def has_expires?
      @enum.find do |tuple|
        tuple.expires
      end
    end

    ##
    # Add +tuple+ to the TupleBag.

    def push(tuple)
      key = bin_key(tuple)
      @hash[key] ||= TupleBin.new
      @hash[key].add(tuple)
    end

    ##
    # Removes +tuple+ from the TupleBag.

    def delete(tuple)
      key = bin_key(tuple)
      bin = @hash[key]
      return nil unless bin
      bin.delete(tuple)
      @hash.delete(key) if bin.empty?
      tuple
    end

    ##
    # Finds all live tuples that match +template+.
    def find_all(template)
      bin_for_find(template).find_all do |tuple|
        tuple.alive? && template.match(tuple)
      end
    end

    ##
    # Finds a live tuple that matches +template+.

    def find(template)
      bin_for_find(template).find do |tuple|
        tuple.alive? && template.match(tuple)
      end
    end

    ##
    # Finds all tuples in the TupleBag which when treated as templates, match
    # +tuple+ and are alive.

    def find_all_template(tuple)
      @enum.find_all do |template|
        template.alive? && template.match(tuple)
      end
    end

    ##
    # Delete tuples which dead tuples from the TupleBag, returning the deleted
    # tuples.

    def delete_unless_alive
      deleted = []
      @hash.each do |key, bin|
        bin.delete_if do |tuple|
          if tuple.alive?
            false
          else
            deleted.push(tuple)
            true
          end
        end
      end
      deleted
    end

    private
    def each_entry(&blk)
      @hash.each do |k, v|
        v.each(&blk)
      end
    end

    def bin_key(tuple)
      head = tuple[0]
      if head.class == Symbol
        return head
      else
        false
      end
    end

    def bin_for_find(template)
      key = bin_key(template)
      key ? @hash.fetch(key, []) : @enum
    end
  end

  ##
  # The Tuplespace manages access to the tuples it contains,
  # ensuring mutual exclusion requirements are met.
  #
  # The +sec+ option for the write, take, move, read and notify methods may
  # either be a number of seconds or a Renewer object.

  class TupleSpace

    include DRbUndumped
    include MonitorMixin

    ##
    # Creates a new TupleSpace.  +period+ is used to control how often to look
    # for dead tuples after modifications to the TupleSpace.
    #
    # If no dead tuples are found +period+ seconds after the last
    # modification, the TupleSpace will stop looking for dead tuples.

    def initialize(period=60)
      super()
      @bag = TupleBag.new
      @read_waiter = TupleBag.new
      @take_waiter = TupleBag.new
      @notify_waiter = TupleBag.new
      @period = period
      @keeper = nil
    end

    ##
    # Adds +tuple+

    def write(tuple, sec=nil)
      entry = create_entry(tuple, sec)
      synchronize do
        if entry.expired?
          @read_waiter.find_all_template(entry).each do |template|
            template.read(tuple)
          end
          notify_event('write', entry.value)
          notify_event('delete', entry.value)
        else
          @bag.push(entry)
          start_keeper if entry.expires
          @read_waiter.find_all_template(entry).each do |template|
            template.read(tuple)
          end
          @take_waiter.find_all_template(entry).each do |template|
            template.signal
          end
          notify_event('write', entry.value)
        end
      end
      entry
    end

    ##
    # Removes +tuple+

    def take(tuple, sec=nil, &block)
      move(nil, tuple, sec, &block)
    end

    ##
    # Moves +tuple+ to +port+.

    def move(port, tuple, sec=nil)
      template = WaitTemplateEntry.new(self, tuple, sec)
      yield(template) if block_given?
      synchronize do
        entry = @bag.find(template)
        if entry
          port.push(entry.value) if port
          @bag.delete(entry)
          notify_event('take', entry.value)
          return entry.value
        end
        raise RequestExpiredError if template.expired?

        begin
          @take_waiter.push(template)
          start_keeper if template.expires
          while true
            raise RequestCanceledError if template.canceled?
            raise RequestExpiredError if template.expired?
            entry = @bag.find(template)
            if entry
              port.push(entry.value) if port
              @bag.delete(entry)
              notify_event('take', entry.value)
              return entry.value
            end
            template.wait
          end
        ensure
          @take_waiter.delete(template)
        end
      end
    end

    ##
    # Reads +tuple+, but does not remove it.

    def read(tuple, sec=nil)
      template = WaitTemplateEntry.new(self, tuple, sec)
      yield(template) if block_given?
      synchronize do
        entry = @bag.find(template)
        return entry.value if entry
        raise RequestExpiredError if template.expired?

        begin
          @read_waiter.push(template)
          start_keeper if template.expires
          template.wait
          raise RequestCanceledError if template.canceled?
          raise RequestExpiredError if template.expired?
          return template.found
        ensure
          @read_waiter.delete(template)
        end
      end
    end

    ##
    # Returns all tuples matching +tuple+.  Does not remove the found tuples.

    def read_all(tuple)
      template = WaitTemplateEntry.new(self, tuple, nil)
      synchronize do
        entry = @bag.find_all(template)
        entry.collect do |e|
          e.value
        end
      end
    end

    ##
    # Registers for notifications of +event+.  Returns a NotifyTemplateEntry.
    # See NotifyTemplateEntry for examples of how to listen for notifications.
    #
    # +event+ can be:
    # 'write'::  A tuple was added
    # 'take'::   A tuple was taken or moved
    # 'delete':: A tuple was lost after being overwritten or expiring
    #
    # The TupleSpace will also notify you of the 'close' event when the
    # NotifyTemplateEntry has expired.

    def notify(event, tuple, sec=nil)
      template = NotifyTemplateEntry.new(self, event, tuple, sec)
      synchronize do
        @notify_waiter.push(template)
      end
      template
    end

    private

    def create_entry(tuple, sec)
      TupleEntry.new(tuple, sec)
    end

    ##
    # Removes dead tuples.

    def keep_clean
      synchronize do
        @read_waiter.delete_unless_alive.each do |e|
          e.signal
        end
        @take_waiter.delete_unless_alive.each do |e|
          e.signal
        end
        @notify_waiter.delete_unless_alive.each do |e|
          e.notify(['close'])
        end
        @bag.delete_unless_alive.each do |e|
          notify_event('delete', e.value)
        end
      end
    end

    ##
    # Notifies all registered listeners for +event+ of a status change of
    # +tuple+.

    def notify_event(event, tuple)
      ev = [event, tuple]
      @notify_waiter.find_all_template(ev).each do |template|
        template.notify(ev)
      end
    end

    ##
    # Creates a thread that scans the tuplespace for expired tuples.

    def start_keeper
      return if @keeper && @keeper.alive?
      @keeper = Thread.new do
        while true
          sleep(@period)
          synchronize do
            break unless need_keeper?
            keep_clean
          end
        end
      end
    end

    ##
    # Checks the tuplespace to see if it needs cleaning.

    def need_keeper?
      return true if @bag.has_expires?
      return true if @read_waiter.has_expires?
      return true if @take_waiter.has_expires?
      return true if @notify_waiter.has_expires?
    end

  end

end

PK     Y\̛& &   cgi.rbnu [        # 
# cgi.rb - cgi support library
# 
# Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
# 
# Copyright (C) 2000  Information-technology Promotion Agency, Japan
#
# Author: Wakou Aoyama <wakou@ruby-lang.org>
#
# Documentation: Wakou Aoyama (RDoc'd and embellished by William Webber) 
# 
# == Overview
#
# The Common Gateway Interface (CGI) is a simple protocol
# for passing an HTTP request from a web server to a
# standalone program, and returning the output to the web
# browser.  Basically, a CGI program is called with the
# parameters of the request passed in either in the
# environment (GET) or via $stdin (POST), and everything
# it prints to $stdout is returned to the client.
# 
# This file holds the +CGI+ class.  This class provides
# functionality for retrieving HTTP request parameters,
# managing cookies, and generating HTML output.  See the
# class documentation for more details and examples of use.
#
# The file cgi/session.rb provides session management
# functionality; see that file for more details.
#
# See http://www.w3.org/CGI/ for more information on the CGI
# protocol.

raise "Please, use ruby 1.5.4 or later." if RUBY_VERSION < "1.5.4"

require 'English'

# CGI class.  See documentation for the file cgi.rb for an overview
# of the CGI protocol.
#
# == Introduction
#
# CGI is a large class, providing several categories of methods, many of which
# are mixed in from other modules.  Some of the documentation is in this class,
# some in the modules CGI::QueryExtension and CGI::HtmlExtension.  See
# CGI::Cookie for specific information on handling cookies, and cgi/session.rb
# (CGI::Session) for information on sessions.
#
# For queries, CGI provides methods to get at environmental variables,
# parameters, cookies, and multipart request data.  For responses, CGI provides
# methods for writing output and generating HTML.
#
# Read on for more details.  Examples are provided at the bottom.
#
# == Queries
#
# The CGI class dynamically mixes in parameter and cookie-parsing
# functionality,  environmental variable access, and support for
# parsing multipart requests (including uploaded files) from the
# CGI::QueryExtension module.
#
# === Environmental Variables
#
# The standard CGI environmental variables are available as read-only
# attributes of a CGI object.  The following is a list of these variables:
#
#
#   AUTH_TYPE               HTTP_HOST          REMOTE_IDENT
#   CONTENT_LENGTH          HTTP_NEGOTIATE     REMOTE_USER
#   CONTENT_TYPE            HTTP_PRAGMA        REQUEST_METHOD
#   GATEWAY_INTERFACE       HTTP_REFERER       SCRIPT_NAME
#   HTTP_ACCEPT             HTTP_USER_AGENT    SERVER_NAME
#   HTTP_ACCEPT_CHARSET     PATH_INFO          SERVER_PORT
#   HTTP_ACCEPT_ENCODING    PATH_TRANSLATED    SERVER_PROTOCOL
#   HTTP_ACCEPT_LANGUAGE    QUERY_STRING       SERVER_SOFTWARE
#   HTTP_CACHE_CONTROL      REMOTE_ADDR
#   HTTP_FROM               REMOTE_HOST
#
#
# For each of these variables, there is a corresponding attribute with the
# same name, except all lower case and without a preceding HTTP_.  
# +content_length+ and +server_port+ are integers; the rest are strings.
#
# === Parameters
#
# The method #params() returns a hash of all parameters in the request as
# name/value-list pairs, where the value-list is an Array of one or more
# values.  The CGI object itself also behaves as a hash of parameter names 
# to values, but only returns a single value (as a String) for each 
# parameter name.
#
# For instance, suppose the request contains the parameter 
# "favourite_colours" with the multiple values "blue" and "green".  The
# following behaviour would occur:
#
#   cgi.params["favourite_colours"]  # => ["blue", "green"]
#   cgi["favourite_colours"]         # => "blue"
#
# If a parameter does not exist, the former method will return an empty
# array, the latter an empty string.  The simplest way to test for existence
# of a parameter is by the #has_key? method.
#
# === Cookies
#
# HTTP Cookies are automatically parsed from the request.  They are available
# from the #cookies() accessor, which returns a hash from cookie name to
# CGI::Cookie object.
#
# === Multipart requests
#
# If a request's method is POST and its content type is multipart/form-data, 
# then it may contain uploaded files.  These are stored by the QueryExtension
# module in the parameters of the request.  The parameter name is the name
# attribute of the file input field, as usual.  However, the value is not
# a string, but an IO object, either an IOString for small files, or a
# Tempfile for larger ones.  This object also has the additional singleton
# methods:
#
# #local_path():: the path of the uploaded file on the local filesystem
# #original_filename():: the name of the file on the client computer
# #content_type():: the content type of the file
#
# == Responses
#
# The CGI class provides methods for sending header and content output to
# the HTTP client, and mixes in methods for programmatic HTML generation
# from CGI::HtmlExtension and CGI::TagMaker modules.  The precise version of HTML
# to use for HTML generation is specified at object creation time.
#
# === Writing output
#
# The simplest way to send output to the HTTP client is using the #out() method.
# This takes the HTTP headers as a hash parameter, and the body content
# via a block.  The headers can be generated as a string using the #header()
# method.  The output stream can be written directly to using the #print()
# method.
#
# === Generating HTML
#
# Each HTML element has a corresponding method for generating that
# element as a String.  The name of this method is the same as that
# of the element, all lowercase.  The attributes of the element are 
# passed in as a hash, and the body as a no-argument block that evaluates
# to a String.  The HTML generation module knows which elements are
# always empty, and silently drops any passed-in body.  It also knows
# which elements require matching closing tags and which don't.  However,
# it does not know what attributes are legal for which elements.
#
# There are also some additional HTML generation methods mixed in from
# the CGI::HtmlExtension module.  These include individual methods for the
# different types of form inputs, and methods for elements that commonly
# take particular attributes where the attributes can be directly specified
# as arguments, rather than via a hash.
#
# == Examples of use
# 
# === Get form values
# 
#   require "cgi"
#   cgi = CGI.new
#   value = cgi['field_name']   # <== value string for 'field_name'
#     # if not 'field_name' included, then return "".
#   fields = cgi.keys            # <== array of field names
# 
#   # returns true if form has 'field_name'
#   cgi.has_key?('field_name')
#   cgi.has_key?('field_name')
#   cgi.include?('field_name')
# 
# CAUTION! cgi['field_name'] returned an Array with the old 
# cgi.rb(included in ruby 1.6)
# 
# === Get form values as hash
# 
#   require "cgi"
#   cgi = CGI.new
#   params = cgi.params
# 
# cgi.params is a hash.
# 
#   cgi.params['new_field_name'] = ["value"]  # add new param
#   cgi.params['field_name'] = ["new_value"]  # change value
#   cgi.params.delete('field_name')           # delete param
#   cgi.params.clear                          # delete all params
# 
# 
# === Save form values to file
# 
#   require "pstore"
#   db = PStore.new("query.db")
#   db.transaction do
#     db["params"] = cgi.params
#   end
# 
# 
# === Restore form values from file
# 
#   require "pstore"
#   db = PStore.new("query.db")
#   db.transaction do
#     cgi.params = db["params"]
#   end
# 
# 
# === Get multipart form values
# 
#   require "cgi"
#   cgi = CGI.new
#   value = cgi['field_name']   # <== value string for 'field_name'
#   value.read                  # <== body of value
#   value.local_path            # <== path to local file of value
#   value.original_filename     # <== original filename of value
#   value.content_type          # <== content_type of value
# 
# and value has StringIO or Tempfile class methods.
# 
# === Get cookie values
# 
#   require "cgi"
#   cgi = CGI.new
#   values = cgi.cookies['name']  # <== array of 'name'
#     # if not 'name' included, then return [].
#   names = cgi.cookies.keys      # <== array of cookie names
# 
# and cgi.cookies is a hash.
# 
# === Get cookie objects
# 
#   require "cgi"
#   cgi = CGI.new
#   for name, cookie in cgi.cookies
#     cookie.expires = Time.now + 30
#   end
#   cgi.out("cookie" => cgi.cookies) {"string"}
# 
#   cgi.cookies # { "name1" => cookie1, "name2" => cookie2, ... }
# 
#   require "cgi"
#   cgi = CGI.new
#   cgi.cookies['name'].expires = Time.now + 30
#   cgi.out("cookie" => cgi.cookies['name']) {"string"}
# 
# === Print http header and html string to $DEFAULT_OUTPUT ($>)
# 
#   require "cgi"
#   cgi = CGI.new("html3")  # add HTML generation methods
#   cgi.out() do
#     cgi.html() do
#       cgi.head{ cgi.title{"TITLE"} } +
#       cgi.body() do
#         cgi.form() do
#           cgi.textarea("get_text") +
#           cgi.br +
#           cgi.submit
#         end +
#         cgi.pre() do
#           CGI::escapeHTML(
#             "params: " + cgi.params.inspect + "\n" +
#             "cookies: " + cgi.cookies.inspect + "\n" +
#             ENV.collect() do |key, value|
#               key + " --> " + value + "\n"
#             end.join("")
#           )
#         end
#       end
#     end
#   end
# 
#   # add HTML generation methods
#   CGI.new("html3")    # html3.2
#   CGI.new("html4")    # html4.01 (Strict)
#   CGI.new("html4Tr")  # html4.01 Transitional
#   CGI.new("html4Fr")  # html4.01 Frameset
#
class CGI

  # :stopdoc:

  # String for carriage return
  CR  = "\015"

  # String for linefeed
  LF  = "\012"

  # Standard internet newline sequence
  EOL = CR + LF

  REVISION = '$Id: cgi.rb 26086 2009-12-14 02:40:07Z shyouhei $' #:nodoc:

  NEEDS_BINMODE = true if /WIN/ni.match(RUBY_PLATFORM) 

  # Path separators in different environments.
  PATH_SEPARATOR = {'UNIX'=>'/', 'WINDOWS'=>'\\', 'MACINTOSH'=>':'}

  # HTTP status codes.
  HTTP_STATUS = {
    "OK"                  => "200 OK",
    "PARTIAL_CONTENT"     => "206 Partial Content",
    "MULTIPLE_CHOICES"    => "300 Multiple Choices",
    "MOVED"               => "301 Moved Permanently",
    "REDIRECT"            => "302 Found",
    "NOT_MODIFIED"        => "304 Not Modified",
    "BAD_REQUEST"         => "400 Bad Request",
    "AUTH_REQUIRED"       => "401 Authorization Required",
    "FORBIDDEN"           => "403 Forbidden",
    "NOT_FOUND"           => "404 Not Found",
    "METHOD_NOT_ALLOWED"  => "405 Method Not Allowed",
    "NOT_ACCEPTABLE"      => "406 Not Acceptable",
    "LENGTH_REQUIRED"     => "411 Length Required",
    "PRECONDITION_FAILED" => "412 Precondition Failed",
    "SERVER_ERROR"        => "500 Internal Server Error",
    "NOT_IMPLEMENTED"     => "501 Method Not Implemented",
    "BAD_GATEWAY"         => "502 Bad Gateway",
    "VARIANT_ALSO_VARIES" => "506 Variant Also Negotiates"
  }

  # Abbreviated day-of-week names specified by RFC 822
  RFC822_DAYS = %w[ Sun Mon Tue Wed Thu Fri Sat ]

  # Abbreviated month names specified by RFC 822
  RFC822_MONTHS = %w[ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ]

  # :startdoc:

  def env_table 
    ENV
  end

  def stdinput
    $stdin
  end

  def stdoutput
    $DEFAULT_OUTPUT
  end

  private :env_table, :stdinput, :stdoutput

  # URL-encode a string.
  #   url_encoded_string = CGI::escape("'Stop!' said Fred")
  #      # => "%27Stop%21%27+said+Fred"
  def CGI::escape(string)
    string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do
      '%' + $1.unpack('H2' * $1.size).join('%').upcase
    end.tr(' ', '+')
  end


  # URL-decode a string.
  #   string = CGI::unescape("%27Stop%21%27+said+Fred")
  #      # => "'Stop!' said Fred"
  def CGI::unescape(string)
    string.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n) do
      [$1.delete('%')].pack('H*')
    end
  end


  # Escape special characters in HTML, namely &\"<>
  #   CGI::escapeHTML('Usage: foo "bar" <baz>')
  #      # => "Usage: foo &quot;bar&quot; &lt;baz&gt;"
  def CGI::escapeHTML(string)
    string.gsub(/&/n, '&amp;').gsub(/\"/n, '&quot;').gsub(/>/n, '&gt;').gsub(/</n, '&lt;')
  end


  # Unescape a string that has been HTML-escaped
  #   CGI::unescapeHTML("Usage: foo &quot;bar&quot; &lt;baz&gt;")
  #      # => "Usage: foo \"bar\" <baz>"
  def CGI::unescapeHTML(string)
    string.gsub(/&(amp|quot|gt|lt|\#[0-9]+|\#x[0-9A-Fa-f]+);/n) do
      match = $1.dup
      case match
      when 'amp'                 then '&'
      when 'quot'                then '"'
      when 'gt'                  then '>'
      when 'lt'                  then '<'
      when /\A#0*(\d+)\z/n       then
        if Integer($1) < 256
          Integer($1).chr
        else
          if Integer($1) < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U)
            [Integer($1)].pack("U")
          else
            "&##{$1};"
          end
        end
      when /\A#x([0-9a-f]+)\z/ni then
        if $1.hex < 128
          $1.hex.chr
        else
          if $1.hex < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U)
            [$1.hex].pack("U")
          else
            "&#x#{$1};"
          end
        end
      else
        "&#{match};"
      end
    end
  end


  # Escape only the tags of certain HTML elements in +string+.
  #
  # Takes an element or elements or array of elements.  Each element
  # is specified by the name of the element, without angle brackets.
  # This matches both the start and the end tag of that element.
  # The attribute list of the open tag will also be escaped (for
  # instance, the double-quotes surrounding attribute values).
  #
  #   print CGI::escapeElement('<BR><A HREF="url"></A>', "A", "IMG")
  #     # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
  #
  #   print CGI::escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])
  #     # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
  def CGI::escapeElement(string, *elements)
    elements = elements[0] if elements[0].kind_of?(Array)
    unless elements.empty?
      string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/ni) do
        CGI::escapeHTML($&)
      end
    else
      string
    end
  end


  # Undo escaping such as that done by CGI::escapeElement()
  #
  #   print CGI::unescapeElement(
  #           CGI::escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG")
  #     # "&lt;BR&gt;<A HREF="url"></A>"
  # 
  #   print CGI::unescapeElement(
  #           CGI::escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"])
  #     # "&lt;BR&gt;<A HREF="url"></A>"
  def CGI::unescapeElement(string, *elements)
    elements = elements[0] if elements[0].kind_of?(Array)
    unless elements.empty?
      string.gsub(/&lt;\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?&gt;/ni) do
        CGI::unescapeHTML($&)
      end
    else
      string
    end
  end


  # Format a +Time+ object as a String using the format specified by RFC 1123.
  #
  #   CGI::rfc1123_date(Time.now)
  #     # Sat, 01 Jan 2000 00:00:00 GMT
  def CGI::rfc1123_date(time)
    t = time.clone.gmtime
    return format("%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
                RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year,
                t.hour, t.min, t.sec)
  end


  # Create an HTTP header block as a string.
  #
  # Includes the empty line that ends the header block.
  #
  # +options+ can be a string specifying the Content-Type (defaults
  # to text/html), or a hash of header key/value pairs.  The following
  # header keys are recognized:
  #
  # type:: the Content-Type header.  Defaults to "text/html"
  # charset:: the charset of the body, appended to the Content-Type header.
  # nph:: a boolean value.  If true, prepend protocol string and status code, and
  #       date; and sets default values for "server" and "connection" if not
  #       explicitly set.
  # status:: the HTTP status code, returned as the Status header.  See the
  #          list of available status codes below.
  # server:: the server software, returned as the Server header.
  # connection:: the connection type, returned as the Connection header (for 
  #              instance, "close".
  # length:: the length of the content that will be sent, returned as the
  #          Content-Length header.
  # language:: the language of the content, returned as the Content-Language
  #            header.
  # expires:: the time on which the current content expires, as a +Time+
  #           object, returned as the Expires header.
  # cookie:: a cookie or cookies, returned as one or more Set-Cookie headers.
  #          The value can be the literal string of the cookie; a CGI::Cookie
  #          object; an Array of literal cookie strings or Cookie objects; or a 
  #          hash all of whose values are literal cookie strings or Cookie objects.
  #          These cookies are in addition to the cookies held in the
  #          @output_cookies field.
  #
  # Other header lines can also be set; they are appended as key: value.
  # 
  #   header
  #     # Content-Type: text/html
  # 
  #   header("text/plain")
  #     # Content-Type: text/plain
  # 
  #   header("nph"        => true,
  #          "status"     => "OK",  # == "200 OK"
  #            # "status"     => "200 GOOD",
  #          "server"     => ENV['SERVER_SOFTWARE'],
  #          "connection" => "close",
  #          "type"       => "text/html",
  #          "charset"    => "iso-2022-jp",
  #            # Content-Type: text/html; charset=iso-2022-jp
  #          "length"     => 103,
  #          "language"   => "ja",
  #          "expires"    => Time.now + 30,
  #          "cookie"     => [cookie1, cookie2],
  #          "my_header1" => "my_value"
  #          "my_header2" => "my_value")
  # 
  # The status codes are:
  # 
  #   "OK"                  --> "200 OK"
  #   "PARTIAL_CONTENT"     --> "206 Partial Content"
  #   "MULTIPLE_CHOICES"    --> "300 Multiple Choices"
  #   "MOVED"               --> "301 Moved Permanently"
  #   "REDIRECT"            --> "302 Found"
  #   "NOT_MODIFIED"        --> "304 Not Modified"
  #   "BAD_REQUEST"         --> "400 Bad Request"
  #   "AUTH_REQUIRED"       --> "401 Authorization Required"
  #   "FORBIDDEN"           --> "403 Forbidden"
  #   "NOT_FOUND"           --> "404 Not Found"
  #   "METHOD_NOT_ALLOWED"  --> "405 Method Not Allowed"
  #   "NOT_ACCEPTABLE"      --> "406 Not Acceptable"
  #   "LENGTH_REQUIRED"     --> "411 Length Required"
  #   "PRECONDITION_FAILED" --> "412 Precondition Failed"
  #   "SERVER_ERROR"        --> "500 Internal Server Error"
  #   "NOT_IMPLEMENTED"     --> "501 Method Not Implemented"
  #   "BAD_GATEWAY"         --> "502 Bad Gateway"
  #   "VARIANT_ALSO_VARIES" --> "506 Variant Also Negotiates"
  # 
  # This method does not perform charset conversion. 
  #
  def header(options = "text/html")

    buf = ""

    case options
    when String
      options = { "type" => options }
    when Hash
      options = options.dup
    end

    unless options.has_key?("type")
      options["type"] = "text/html"
    end

    if options.has_key?("charset")
      options["type"] += "; charset=" + options.delete("charset")
    end

    options.delete("nph") if defined?(MOD_RUBY)
    if options.delete("nph") or
        (/IIS\/(\d+)/n.match(env_table['SERVER_SOFTWARE']) and $1.to_i < 5)
      buf += (env_table["SERVER_PROTOCOL"] or "HTTP/1.0")  + " " +
             (HTTP_STATUS[options["status"]] or options["status"] or "200 OK") +
             EOL +
             "Date: " + CGI::rfc1123_date(Time.now) + EOL

      unless options.has_key?("server")
        options["server"] = (env_table['SERVER_SOFTWARE'] or "")
      end

      unless options.has_key?("connection")
        options["connection"] = "close"
      end

      options.delete("status")
    end

    if options.has_key?("status")
      buf += "Status: " +
             (HTTP_STATUS[options["status"]] or options["status"]) + EOL
      options.delete("status")
    end

    if options.has_key?("server")
      buf += "Server: " + options.delete("server") + EOL
    end

    if options.has_key?("connection")
      buf += "Connection: " + options.delete("connection") + EOL
    end

    buf += "Content-Type: " + options.delete("type") + EOL

    if options.has_key?("length")
      buf += "Content-Length: " + options.delete("length").to_s + EOL
    end

    if options.has_key?("language")
      buf += "Content-Language: " + options.delete("language") + EOL
    end

    if options.has_key?("expires")
      buf += "Expires: " + CGI::rfc1123_date( options.delete("expires") ) + EOL
    end

    if options.has_key?("cookie")
      if options["cookie"].kind_of?(String) or
           options["cookie"].kind_of?(Cookie)
        buf += "Set-Cookie: " + options.delete("cookie").to_s + EOL
      elsif options["cookie"].kind_of?(Array)
        options.delete("cookie").each{|cookie|
          buf += "Set-Cookie: " + cookie.to_s + EOL
        }
      elsif options["cookie"].kind_of?(Hash)
        options.delete("cookie").each_value{|cookie|
          buf += "Set-Cookie: " + cookie.to_s + EOL
        }
      end
    end
    if @output_cookies
      for cookie in @output_cookies
        buf += "Set-Cookie: " + cookie.to_s + EOL
      end
    end

    options.each{|key, value|
      buf += key + ": " + value.to_s + EOL
    }

    if defined?(MOD_RUBY)
      table = Apache::request.headers_out
      buf.scan(/([^:]+): (.+)#{EOL}/n){ |name, value|
        warn sprintf("name:%s value:%s\n", name, value) if $DEBUG
        case name
        when 'Set-Cookie'
          table.add(name, value)
        when /^status$/ni
          Apache::request.status_line = value
          Apache::request.status = value.to_i
        when /^content-type$/ni
          Apache::request.content_type = value
        when /^content-encoding$/ni
          Apache::request.content_encoding = value
        when /^location$/ni
	  if Apache::request.status == 200
	    Apache::request.status = 302
	  end
          Apache::request.headers_out[name] = value
        else
          Apache::request.headers_out[name] = value
        end
      }
      Apache::request.send_http_header
      ''
    else
      buf + EOL
    end

  end # header()


  # Print an HTTP header and body to $DEFAULT_OUTPUT ($>)
  #
  # The header is provided by +options+, as for #header().
  # The body of the document is that returned by the passed-
  # in block.  This block takes no arguments.  It is required.
  #
  #   cgi = CGI.new
  #   cgi.out{ "string" }
  #     # Content-Type: text/html
  #     # Content-Length: 6
  #     #
  #     # string
  # 
  #   cgi.out("text/plain") { "string" }
  #     # Content-Type: text/plain
  #     # Content-Length: 6
  #     #
  #     # string
  # 
  #   cgi.out("nph"        => true,
  #           "status"     => "OK",  # == "200 OK"
  #           "server"     => ENV['SERVER_SOFTWARE'],
  #           "connection" => "close",
  #           "type"       => "text/html",
  #           "charset"    => "iso-2022-jp",
  #             # Content-Type: text/html; charset=iso-2022-jp
  #           "language"   => "ja",
  #           "expires"    => Time.now + (3600 * 24 * 30),
  #           "cookie"     => [cookie1, cookie2],
  #           "my_header1" => "my_value",
  #           "my_header2" => "my_value") { "string" }
  # 
  # Content-Length is automatically calculated from the size of
  # the String returned by the content block.
  #
  # If ENV['REQUEST_METHOD'] == "HEAD", then only the header
  # is outputted (the content block is still required, but it
  # is ignored).
  # 
  # If the charset is "iso-2022-jp" or "euc-jp" or "shift_jis" then
  # the content is converted to this charset, and the language is set 
  # to "ja".
  def out(options = "text/html") # :yield:

    options = { "type" => options } if options.kind_of?(String)
    content = yield

    if options.has_key?("charset")
      require "nkf"
      case options["charset"]
      when /iso-2022-jp/ni
        content = NKF::nkf('-m0 -x -j', content)
        options["language"] = "ja" unless options.has_key?("language")
      when /euc-jp/ni
        content = NKF::nkf('-m0 -x -e', content)
        options["language"] = "ja" unless options.has_key?("language")
      when /shift_jis/ni
        content = NKF::nkf('-m0 -x -s', content)
        options["language"] = "ja" unless options.has_key?("language")
      end
    end

    options["length"] = content.length.to_s
    output = stdoutput
    output.binmode if defined? output.binmode
    output.print header(options)
    output.print content unless "HEAD" == env_table['REQUEST_METHOD']
  end


  # Print an argument or list of arguments to the default output stream
  #
  #   cgi = CGI.new
  #   cgi.print    # default:  cgi.print == $DEFAULT_OUTPUT.print
  def print(*options)
    stdoutput.print(*options)
  end

  require "delegate"

  # Class representing an HTTP cookie.
  #
  # In addition to its specific fields and methods, a Cookie instance
  # is a delegator to the array of its values.
  #
  # See RFC 2965.
  #
  # == Examples of use
  #   cookie1 = CGI::Cookie::new("name", "value1", "value2", ...)
  #   cookie1 = CGI::Cookie::new("name" => "name", "value" => "value")
  #   cookie1 = CGI::Cookie::new('name'    => 'name',
  #                              'value'   => ['value1', 'value2', ...],
  #                              'path'    => 'path',   # optional
  #                              'domain'  => 'domain', # optional
  #                              'expires' => Time.now, # optional
  #                              'secure'  => true      # optional
  #                             )
  # 
  #   cgi.out("cookie" => [cookie1, cookie2]) { "string" }
  # 
  #   name    = cookie1.name
  #   values  = cookie1.value
  #   path    = cookie1.path
  #   domain  = cookie1.domain
  #   expires = cookie1.expires
  #   secure  = cookie1.secure
  # 
  #   cookie1.name    = 'name'
  #   cookie1.value   = ['value1', 'value2', ...]
  #   cookie1.path    = 'path'
  #   cookie1.domain  = 'domain'
  #   cookie1.expires = Time.now + 30
  #   cookie1.secure  = true
  class Cookie < DelegateClass(Array)

    # Create a new CGI::Cookie object.
    #
    # The contents of the cookie can be specified as a +name+ and one
    # or more +value+ arguments.  Alternatively, the contents can
    # be specified as a single hash argument.  The possible keywords of
    # this hash are as follows:
    #
    # name:: the name of the cookie.  Required.
    # value:: the cookie's value or list of values.
    # path:: the path for which this cookie applies.  Defaults to the
    #        base directory of the CGI script.
    # domain:: the domain for which this cookie applies.
    # expires:: the time at which this cookie expires, as a +Time+ object.
    # secure:: whether this cookie is a secure cookie or not (default to
    #          false).  Secure cookies are only transmitted to HTTPS 
    #          servers.
    #
    # These keywords correspond to attributes of the cookie object.
    def initialize(name = "", *value)
      if name.kind_of?(String)
        @name = name
        @value = value
        %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
        @path = ($1 or "")
        @secure = false
        return super(@value)
      end

      options = name
      unless options.has_key?("name")
        raise ArgumentError, "`name' required"
      end

      @name = options["name"]
      @value = Array(options["value"])
      # simple support for IE
      if options["path"]
        @path = options["path"]
      else
        %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
        @path = ($1 or "")
      end
      @domain = options["domain"]
      @expires = options["expires"]
      @secure = options["secure"] == true ? true : false

      super(@value)
    end

    attr_accessor("name", "path", "domain", "expires")
    attr_reader("secure", "value")

    # Set whether the Cookie is a secure cookie or not.
    #
    # +val+ must be a boolean.
    def secure=(val)
      @secure = val if val == true or val == false
      @secure
    end

    def value=(val)
      @value.replace(Array(val))
    end

    # Convert the Cookie to its string representation.
    def to_s
      buf = ""
      buf += @name + '='

      buf += @value.map { |v| CGI::escape(v) }.join("&")

      if @domain
        buf += '; domain=' + @domain
      end

      if @path
        buf += '; path=' + @path
      end

      if @expires
        buf += '; expires=' + CGI::rfc1123_date(@expires)
      end

      if @secure == true
        buf += '; secure'
      end

      buf
    end

  end # class Cookie


  # Parse a raw cookie string into a hash of cookie-name=>Cookie
  # pairs.
  #
  #   cookies = CGI::Cookie::parse("raw_cookie_string")
  #     # { "name1" => cookie1, "name2" => cookie2, ... }
  #
  def Cookie::parse(raw_cookie)
    cookies = Hash.new([])
    return cookies unless raw_cookie

    raw_cookie.split(/[;,]\s?/).each do |pairs|
      name, values = pairs.split('=',2)
      next unless name and values
      name = CGI::unescape(name)
      values ||= ""
      values = values.split('&').collect{|v| CGI::unescape(v) }
      if cookies.has_key?(name)
        values = cookies[name].value + values
      end
      cookies[name] = Cookie::new(name, *values)
    end

    cookies
  end

  # Parse an HTTP query string into a hash of key=>value pairs.
  #
  #   params = CGI::parse("query_string")
  #     # {"name1" => ["value1", "value2", ...],
  #     #  "name2" => ["value1", "value2", ...], ... }
  #
  def CGI::parse(query)
    params = Hash.new([].freeze)

    query.split(/[&;]/n).each do |pairs|
      key, value = pairs.split('=',2).collect{|v| CGI::unescape(v) }
      if params.has_key?(key)
        params[key].push(value)
      else
        params[key] = [value]
      end
    end

    params
  end

  # Mixin module. It provides the follow functionality groups:
  #
  # 1. Access to CGI environment variables as methods.  See 
  #    documentation to the CGI class for a list of these variables.
  #
  # 2. Access to cookies, including the cookies attribute.
  #
  # 3. Access to parameters, including the params attribute, and overloading
  #    [] to perform parameter value lookup by key.
  #
  # 4. The initialize_query method, for initialising the above
  #    mechanisms, handling multipart forms, and allowing the
  #    class to be used in "offline" mode.
  #
  module QueryExtension

    %w[ CONTENT_LENGTH SERVER_PORT ].each do |env|
      define_method(env.sub(/^HTTP_/n, '').downcase) do
        (val = env_table[env]) && Integer(val)
      end
    end

    %w[ AUTH_TYPE CONTENT_TYPE GATEWAY_INTERFACE PATH_INFO
        PATH_TRANSLATED QUERY_STRING REMOTE_ADDR REMOTE_HOST
        REMOTE_IDENT REMOTE_USER REQUEST_METHOD SCRIPT_NAME
        SERVER_NAME SERVER_PROTOCOL SERVER_SOFTWARE

        HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
        HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM HTTP_HOST
        HTTP_NEGOTIATE HTTP_PRAGMA HTTP_REFERER HTTP_USER_AGENT ].each do |env|
      define_method(env.sub(/^HTTP_/n, '').downcase) do
        env_table[env]
      end
    end

    # Get the raw cookies as a string.
    def raw_cookie
      env_table["HTTP_COOKIE"]
    end

    # Get the raw RFC2965 cookies as a string.
    def raw_cookie2
      env_table["HTTP_COOKIE2"]
    end

    # Get the cookies as a hash of cookie-name=>Cookie pairs.
    attr_accessor("cookies")

    # Get the parameters as a hash of name=>values pairs, where
    # values is an Array.
    attr("params")

    # Set all the parameters.
    def params=(hash)
      @params.clear
      @params.update(hash)
    end

    def read_multipart(boundary, content_length)
      params = Hash.new([])
      boundary = "--" + boundary
      quoted_boundary = Regexp.quote(boundary, "n")
      buf = ""
      bufsize = 10 * 1024
      boundary_end=""

      # start multipart/form-data
      stdinput.binmode if defined? stdinput.binmode
      boundary_size = boundary.size + EOL.size
      content_length -= boundary_size
      status = stdinput.read(boundary_size)
      if nil == status
        raise EOFError, "no content body"
      elsif boundary + EOL != status
        raise EOFError, "bad content body"
      end

      loop do
        head = nil
        if 10240 < content_length
          require "tempfile"
          body = Tempfile.new("CGI")
        else
          begin
            require "stringio"
            body = StringIO.new
          rescue LoadError
            require "tempfile"
            body = Tempfile.new("CGI")
          end
        end
        body.binmode if defined? body.binmode

        until head and /#{quoted_boundary}(?:#{EOL}|--)/n.match(buf)

          if (not head) and /#{EOL}#{EOL}/n.match(buf)
            buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
              head = $1.dup
              ""
            end
            next
          end

          if head and ( (EOL + boundary + EOL).size < buf.size )
            body.print buf[0 ... (buf.size - (EOL + boundary + EOL).size)]
            buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = ""
          end

          c = if bufsize < content_length
                stdinput.read(bufsize)
              else
                stdinput.read(content_length)
              end
          if c.nil? || c.empty?
            raise EOFError, "bad content body"
          end
          buf.concat(c)
          content_length -= c.size
        end

        buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/n) do
          body.print $1
          if "--" == $2
            content_length = -1
          end
          boundary_end = $2.dup
          ""
        end

        body.rewind

        /Content-Disposition:.* filename=(?:"((?:\\.|[^\"])*)"|([^;\s]*))/ni.match(head)
	filename = ($1 or $2 or "")
	if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and
	    /Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and
	    (not /MSIE/ni.match(env_table['HTTP_USER_AGENT']))
	  filename = CGI::unescape(filename)
	end
        
        /Content-Type: ([^\s]*)/ni.match(head)
        content_type = ($1 or "")

        (class << body; self; end).class_eval do
          alias local_path path
          define_method(:original_filename) {filename.dup.taint}
          define_method(:content_type) {content_type.dup.taint}
        end

        /Content-Disposition:.* name="?([^\";\s]*)"?/ni.match(head)
        name = $1.dup

        if params.has_key?(name)
          params[name].push(body)
        else
          params[name] = [body]
        end
        break if buf.size == 0
        break if content_length == -1
      end
      raise EOFError, "bad boundary end of body part" unless boundary_end=~/--/

      params
    end # read_multipart
    private :read_multipart

    # offline mode. read name=value pairs on standard input.
    def read_from_cmdline
      require "shellwords"

      string = unless ARGV.empty?
        ARGV.join(' ')
      else
        if STDIN.tty?
          STDERR.print(
            %|(offline mode: enter name=value pairs on standard input)\n|
          )
        end
        array = readlines rescue nil
        if not array.nil?
          array.join(' ').gsub(/\n/n, '')
        else
          ""
        end
      end.gsub(/\\=/n, '%3D').gsub(/\\&/n, '%26')

      words = Shellwords.shellwords(string)

      if words.find{|x| /=/n.match(x) }
        words.join('&')
      else
        words.join('+')
      end
    end
    private :read_from_cmdline

    # Initialize the data from the query.
    #
    # Handles multipart forms (in particular, forms that involve file uploads).
    # Reads query parameters in the @params field, and cookies into @cookies.
    def initialize_query()
      if ("POST" == env_table['REQUEST_METHOD']) and
         %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n.match(env_table['CONTENT_TYPE'])
        boundary = $1.dup
        @multipart = true
        @params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH']))
      else
        @multipart = false
        @params = CGI::parse(
                    case env_table['REQUEST_METHOD']
                    when "GET", "HEAD"
                      if defined?(MOD_RUBY)
                        Apache::request.args or ""
                      else
                        env_table['QUERY_STRING'] or ""
                      end
                    when "POST"
                      stdinput.binmode if defined? stdinput.binmode
                      stdinput.read(Integer(env_table['CONTENT_LENGTH'])) or ''
                    else
                      read_from_cmdline
                    end
                  )
      end

      @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] or env_table['COOKIE']))
    end
    private :initialize_query

    def multipart?
      @multipart
    end

    module Value    # :nodoc:
      def set_params(params)
        @params = params
      end
      def [](idx, *args)
        if args.size == 0
          warn "#{caller(1)[0]}:CAUTION! cgi['key'] == cgi.params['key'][0]; if want Array, use cgi.params['key']"
          @params[idx]
        else
          super[idx,*args]
        end
      end
      def first
        warn "#{caller(1)[0]}:CAUTION! cgi['key'] == cgi.params['key'][0]; if want Array, use cgi.params['key']"
        self
      end
      alias last first
      def to_a
        @params || [self]
      end
      alias to_ary to_a   	# to be rhs of multiple assignment
    end

    # Get the value for the parameter with a given key.
    #
    # If the parameter has multiple values, only the first will be 
    # retrieved; use #params() to get the array of values.
    def [](key)
      params = @params[key]
      return '' unless params
      value = params[0]
      if @multipart
        if value
          return value
        elsif defined? StringIO
          StringIO.new("")
        else
          Tempfile.new("CGI")
        end
      else
        str = if value then value.dup else "" end
        str.extend(Value)
        str.set_params(params)
        str
      end
    end

    # Return all parameter keys as an array.
    def keys(*args)
      @params.keys(*args)
    end

    # Returns true if a given parameter key exists in the query.
    def has_key?(*args)
      @params.has_key?(*args)
    end
    alias key? has_key?
    alias include? has_key?

  end # QueryExtension


  # Prettify (indent) an HTML string.
  #
  # +string+ is the HTML string to indent.  +shift+ is the indentation
  # unit to use; it defaults to two spaces.
  #
  #   print CGI::pretty("<HTML><BODY></BODY></HTML>")
  #     # <HTML>
  #     #   <BODY>
  #     #   </BODY>
  #     # </HTML>
  # 
  #   print CGI::pretty("<HTML><BODY></BODY></HTML>", "\t")
  #     # <HTML>
  #     #         <BODY>
  #     #         </BODY>
  #     # </HTML>
  #
  def CGI::pretty(string, shift = "  ")
    lines = string.gsub(/(?!\A)<(?:.|\n)*?>/n, "\n\\0").gsub(/<(?:.|\n)*?>(?!\n)/n, "\\0\n")
    end_pos = 0
    while end_pos = lines.index(/^<\/(\w+)/n, end_pos)
      element = $1.dup
      start_pos = lines.rindex(/^\s*<#{element}/ni, end_pos)
      lines[start_pos ... end_pos] = "__" + lines[start_pos ... end_pos].gsub(/\n(?!\z)/n, "\n" + shift) + "__"
    end
    lines.gsub(/^((?:#{Regexp::quote(shift)})*)__(?=<\/?\w)/n, '\1')
  end


  # Base module for HTML-generation mixins.
  #
  # Provides methods for code generation for tags following
  # the various DTD element types.
  module TagMaker # :nodoc:

    # Generate code for an element with required start and end tags.
    #
    #   - -
    def nn_element_def(element)
      nOE_element_def(element, <<-END)
          if block_given?
            yield.to_s
          else
            ""
          end +
          "</#{element.upcase}>"
      END
    end

    # Generate code for an empty element.
    #
    #   - O EMPTY
    def nOE_element_def(element, append = nil)
      s = <<-END
          "<#{element.upcase}" + attributes.collect{|name, value|
            next unless value
            " " + CGI::escapeHTML(name) +
            if true == value
              ""
            else
              '="' + CGI::escapeHTML(value) + '"'
            end
          }.to_s + ">"
      END
      s.sub!(/\Z/, " +") << append if append
      s
    end

    # Generate code for an element for which the end (and possibly the
    # start) tag is optional.
    #
    #   O O or - O
    def nO_element_def(element)
      nOE_element_def(element, <<-END)
          if block_given?
            yield.to_s + "</#{element.upcase}>"
          else
            ""
          end
      END
    end

  end # TagMaker


  #
  # Mixin module providing HTML generation methods.
  #
  # For example,
  #   cgi.a("http://www.example.com") { "Example" }
  #     # => "<A HREF=\"http://www.example.com\">Example</A>"
  #
  # Modules Http3, Http4, etc., contain more basic HTML-generation methods
  # (:title, :center, etc.).
  #
  # See class CGI for a detailed example. 
  #
  module HtmlExtension


    # Generate an Anchor element as a string.
    #
    # +href+ can either be a string, giving the URL
    # for the HREF attribute, or it can be a hash of
    # the element's attributes.
    #
    # The body of the element is the string returned by the no-argument
    # block passed in.
    #
    #   a("http://www.example.com") { "Example" }
    #     # => "<A HREF=\"http://www.example.com\">Example</A>"
    #
    #   a("HREF" => "http://www.example.com", "TARGET" => "_top") { "Example" }
    #     # => "<A HREF=\"http://www.example.com\" TARGET=\"_top\">Example</A>"
    #
    def a(href = "") # :yield:
      attributes = if href.kind_of?(String)
                     { "HREF" => href }
                   else
                     href
                   end
      if block_given?
        super(attributes){ yield }
      else
        super(attributes)
      end
    end

    # Generate a Document Base URI element as a String. 
    #
    # +href+ can either by a string, giving the base URL for the HREF
    # attribute, or it can be a has of the element's attributes.
    #
    # The passed-in no-argument block is ignored.
    #
    #   base("http://www.example.com/cgi")
    #     # => "<BASE HREF=\"http://www.example.com/cgi\">"
    def base(href = "") # :yield:
      attributes = if href.kind_of?(String)
                     { "HREF" => href }
                   else
                     href
                   end
      if block_given?
        super(attributes){ yield }
      else
        super(attributes)
      end
    end

    # Generate a BlockQuote element as a string.
    #
    # +cite+ can either be a string, give the URI for the source of
    # the quoted text, or a hash, giving all attributes of the element,
    # or it can be omitted, in which case the element has no attributes.
    #
    # The body is provided by the passed-in no-argument block
    #
    #   blockquote("http://www.example.com/quotes/foo.html") { "Foo!" }
    #     #=> "<BLOCKQUOTE CITE=\"http://www.example.com/quotes/foo.html\">Foo!</BLOCKQUOTE>
    def blockquote(cite = nil)  # :yield:
      attributes = if cite.kind_of?(String)
                     { "CITE" => cite }
                   else
                     cite or ""
                   end
      if block_given?
        super(attributes){ yield }
      else
        super(attributes)
      end
    end


    # Generate a Table Caption element as a string.
    #
    # +align+ can be a string, giving the alignment of the caption
    # (one of top, bottom, left, or right).  It can be a hash of
    # all the attributes of the element.  Or it can be omitted.
    #
    # The body of the element is provided by the passed-in no-argument block.
    #
    #   caption("left") { "Capital Cities" }
    #     # => <CAPTION ALIGN=\"left\">Capital Cities</CAPTION>
    def caption(align = nil) # :yield:
      attributes = if align.kind_of?(String)
                     { "ALIGN" => align }
                   else
                     align or ""
                   end
      if block_given?
        super(attributes){ yield }
      else
        super(attributes)
      end
    end


    # Generate a Checkbox Input element as a string.
    #
    # The attributes of the element can be specified as three arguments,
    # +name+, +value+, and +checked+.  +checked+ is a boolean value;
    # if true, the CHECKED attribute will be included in the element.
    #
    # Alternatively, the attributes can be specified as a hash.
    #
    #   checkbox("name")
    #     # = checkbox("NAME" => "name")
    # 
    #   checkbox("name", "value")
    #     # = checkbox("NAME" => "name", "VALUE" => "value")
    # 
    #   checkbox("name", "value", true)
    #     # = checkbox("NAME" => "name", "VALUE" => "value", "CHECKED" => true)
    def checkbox(name = "", value = nil, checked = nil)
      attributes = if name.kind_of?(String)
                     { "TYPE" => "checkbox", "NAME" => name,
                       "VALUE" => value, "CHECKED" => checked }
                   else
                     name["TYPE"] = "checkbox"
                     name
                   end
      input(attributes)
    end

    # Generate a sequence of checkbox elements, as a String.
    #
    # The checkboxes will all have the same +name+ attribute.
    # Each checkbox is followed by a label.
    # There will be one checkbox for each value.  Each value
    # can be specified as a String, which will be used both
    # as the value of the VALUE attribute and as the label
    # for that checkbox.  A single-element array has the
    # same effect.
    #
    # Each value can also be specified as a three-element array.
    # The first element is the VALUE attribute; the second is the
    # label; and the third is a boolean specifying whether this
    # checkbox is CHECKED.
    #
    # Each value can also be specified as a two-element
    # array, by omitting either the value element (defaults
    # to the same as the label), or the boolean checked element
    # (defaults to false).
    #
    #   checkbox_group("name", "foo", "bar", "baz")
    #     # <INPUT TYPE="checkbox" NAME="name" VALUE="foo">foo
    #     # <INPUT TYPE="checkbox" NAME="name" VALUE="bar">bar
    #     # <INPUT TYPE="checkbox" NAME="name" VALUE="baz">baz
    # 
    #   checkbox_group("name", ["foo"], ["bar", true], "baz")
    #     # <INPUT TYPE="checkbox" NAME="name" VALUE="foo">foo
    #     # <INPUT TYPE="checkbox" CHECKED NAME="name" VALUE="bar">bar
    #     # <INPUT TYPE="checkbox" NAME="name" VALUE="baz">baz
    # 
    #   checkbox_group("name", ["1", "Foo"], ["2", "Bar", true], "Baz")
    #     # <INPUT TYPE="checkbox" NAME="name" VALUE="1">Foo
    #     # <INPUT TYPE="checkbox" CHECKED NAME="name" VALUE="2">Bar
    #     # <INPUT TYPE="checkbox" NAME="name" VALUE="Baz">Baz
    # 
    #   checkbox_group("NAME" => "name",
    #                    "VALUES" => ["foo", "bar", "baz"])
    # 
    #   checkbox_group("NAME" => "name",
    #                    "VALUES" => [["foo"], ["bar", true], "baz"])
    # 
    #   checkbox_group("NAME" => "name",
    #                    "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"])
    def checkbox_group(name = "", *values)
      if name.kind_of?(Hash)
        values = name["VALUES"]
        name = name["NAME"]
      end
      values.collect{|value|
        if value.kind_of?(String)
          checkbox(name, value) + value
        else
          if value[value.size - 1] == true
            checkbox(name, value[0], true) +
            value[value.size - 2]
          else
            checkbox(name, value[0]) +
            value[value.size - 1]
          end
        end
      }.to_s
    end


    # Generate an File Upload Input element as a string.
    #
    # The attributes of the element can be specified as three arguments,
    # +name+, +size+, and +maxlength+.  +maxlength+ is the maximum length
    # of the file's _name_, not of the file's _contents_.
    #
    # Alternatively, the attributes can be specified as a hash.
    #
    # See #multipart_form() for forms that include file uploads.
    #
    #   file_field("name")
    #     # <INPUT TYPE="file" NAME="name" SIZE="20">
    # 
    #   file_field("name", 40)
    #     # <INPUT TYPE="file" NAME="name" SIZE="40">
    # 
    #   file_field("name", 40, 100)
    #     # <INPUT TYPE="file" NAME="name" SIZE="40" MAXLENGTH="100">
    # 
    #   file_field("NAME" => "name", "SIZE" => 40)
    #     # <INPUT TYPE="file" NAME="name" SIZE="40">
    def file_field(name = "", size = 20, maxlength = nil)
      attributes = if name.kind_of?(String)
                     { "TYPE" => "file", "NAME" => name,
                       "SIZE" => size.to_s }
                   else
                     name["TYPE"] = "file"
                     name
                   end
      attributes["MAXLENGTH"] = maxlength.to_s if maxlength
      input(attributes)
    end


    # Generate a Form element as a string.
    #
    # +method+ should be either "get" or "post", and defaults to the latter.
    # +action+ defaults to the current CGI script name.  +enctype+
    # defaults to "application/x-www-form-urlencoded".  
    #
    # Alternatively, the attributes can be specified as a hash.
    #
    # See also #multipart_form() for forms that include file uploads.
    #
    #   form{ "string" }
    #     # <FORM METHOD="post" ENCTYPE="application/x-www-form-urlencoded">string</FORM>
    # 
    #   form("get") { "string" }
    #     # <FORM METHOD="get" ENCTYPE="application/x-www-form-urlencoded">string</FORM>
    # 
    #   form("get", "url") { "string" }
    #     # <FORM METHOD="get" ACTION="url" ENCTYPE="application/x-www-form-urlencoded">string</FORM>
    # 
    #   form("METHOD" => "post", "ENCTYPE" => "enctype") { "string" }
    #     # <FORM METHOD="post" ENCTYPE="enctype">string</FORM>
    def form(method = "post", action = script_name, enctype = "application/x-www-form-urlencoded")
      attributes = if method.kind_of?(String)
                     { "METHOD" => method, "ACTION" => action,
                       "ENCTYPE" => enctype } 
                   else
                     unless method.has_key?("METHOD")
                       method["METHOD"] = "post"
                     end
                     unless method.has_key?("ENCTYPE")
                       method["ENCTYPE"] = enctype
                     end
                     method
                   end
      if block_given?
        body = yield
      else
        body = ""
      end
      if @output_hidden
        body += @output_hidden.collect{|k,v|
          "<INPUT TYPE=\"HIDDEN\" NAME=\"#{k}\" VALUE=\"#{v}\">"
        }.to_s
      end
      super(attributes){body}
    end

    # Generate a Hidden Input element as a string.
    #
    # The attributes of the element can be specified as two arguments,
    # +name+ and +value+.
    #
    # Alternatively, the attributes can be specified as a hash.
    #
    #   hidden("name")
    #     # <INPUT TYPE="hidden" NAME="name">
    # 
    #   hidden("name", "value")
    #     # <INPUT TYPE="hidden" NAME="name" VALUE="value">
    # 
    #   hidden("NAME" => "name", "VALUE" => "reset", "ID" => "foo")
    #     # <INPUT TYPE="hidden" NAME="name" VALUE="value" ID="foo">
    def hidden(name = "", value = nil)
      attributes = if name.kind_of?(String)
                     { "TYPE" => "hidden", "NAME" => name, "VALUE" => value }
                   else
                     name["TYPE"] = "hidden"
                     name
                   end
      input(attributes)
    end

    # Generate a top-level HTML element as a string.
    #
    # The attributes of the element are specified as a hash.  The
    # pseudo-attribute "PRETTY" can be used to specify that the generated
    # HTML string should be indented.  "PRETTY" can also be specified as
    # a string as the sole argument to this method.  The pseudo-attribute
    # "DOCTYPE", if given, is used as the leading DOCTYPE SGML tag; it
    # should include the entire text of this tag, including angle brackets.
    #
    # The body of the html element is supplied as a block.
    # 
    #   html{ "string" }
    #     # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML>string</HTML>
    # 
    #   html("LANG" => "ja") { "string" }
    #     # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML LANG="ja">string</HTML>
    # 
    #   html("DOCTYPE" => false) { "string" }
    #     # <HTML>string</HTML>
    # 
    #   html("DOCTYPE" => '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">') { "string" }
    #     # <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><HTML>string</HTML>
    # 
    #   html("PRETTY" => "  ") { "<BODY></BODY>" }
    #     # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
    #     # <HTML>
    #     #   <BODY>
    #     #   </BODY>
    #     # </HTML>
    # 
    #   html("PRETTY" => "\t") { "<BODY></BODY>" }
    #     # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
    #     # <HTML>
    #     #         <BODY>
    #     #         </BODY>
    #     # </HTML>
    # 
    #   html("PRETTY") { "<BODY></BODY>" }
    #     # = html("PRETTY" => "  ") { "<BODY></BODY>" }
    # 
    #   html(if $VERBOSE then "PRETTY" end) { "HTML string" }
    #
    def html(attributes = {}) # :yield:
      if nil == attributes
        attributes = {}
      elsif "PRETTY" == attributes
        attributes = { "PRETTY" => true }
      end
      pretty = attributes.delete("PRETTY")
      pretty = "  " if true == pretty
      buf = ""

      if attributes.has_key?("DOCTYPE")
        if attributes["DOCTYPE"]
          buf += attributes.delete("DOCTYPE")
        else
          attributes.delete("DOCTYPE")
        end
      else
        buf += doctype
      end

      if block_given?
        buf += super(attributes){ yield }
      else
        buf += super(attributes)
      end

      if pretty
        CGI::pretty(buf, pretty)
      else
        buf
      end

    end

    # Generate an Image Button Input element as a string.
    #
    # +src+ is the URL of the image to use for the button.  +name+ 
    # is the input name.  +alt+ is the alternative text for the image.
    #
    # Alternatively, the attributes can be specified as a hash.
    # 
    #   image_button("url")
    #     # <INPUT TYPE="image" SRC="url">
    # 
    #   image_button("url", "name", "string")
    #     # <INPUT TYPE="image" SRC="url" NAME="name" ALT="string">
    # 
    #   image_button("SRC" => "url", "ATL" => "strng")
    #     # <INPUT TYPE="image" SRC="url" ALT="string">
    def image_button(src = "", name = nil, alt = nil)
      attributes = if src.kind_of?(String)
                     { "TYPE" => "image", "SRC" => src, "NAME" => name,
                       "ALT" => alt }
                   else
                     src["TYPE"] = "image"
                     src["SRC"] ||= ""
                     src
                   end
      input(attributes)
    end


    # Generate an Image element as a string.
    #
    # +src+ is the URL of the image.  +alt+ is the alternative text for
    # the image.  +width+ is the width of the image, and +height+ is
    # its height.
    #
    # Alternatively, the attributes can be specified as a hash.
    #
    #   img("src", "alt", 100, 50)
    #     # <IMG SRC="src" ALT="alt" WIDTH="100" HEIGHT="50">
    # 
    #   img("SRC" => "src", "ALT" => "alt", "WIDTH" => 100, "HEIGHT" => 50)
    #     # <IMG SRC="src" ALT="alt" WIDTH="100" HEIGHT="50">
    def img(src = "", alt = "", width = nil, height = nil)
      attributes = if src.kind_of?(String)
                     { "SRC" => src, "ALT" => alt }
                   else
                     src
                   end
      attributes["WIDTH"] = width.to_s if width
      attributes["HEIGHT"] = height.to_s if height
      super(attributes)
    end


    # Generate a Form element with multipart encoding as a String.
    #
    # Multipart encoding is used for forms that include file uploads.
    #
    # +action+ is the action to perform.  +enctype+ is the encoding
    # type, which defaults to "multipart/form-data".
    #
    # Alternatively, the attributes can be specified as a hash.
    #
    #   multipart_form{ "string" }
    #     # <FORM METHOD="post" ENCTYPE="multipart/form-data">string</FORM>
    # 
    #   multipart_form("url") { "string" }
    #     # <FORM METHOD="post" ACTION="url" ENCTYPE="multipart/form-data">string</FORM>
    def multipart_form(action = nil, enctype = "multipart/form-data")
      attributes = if action == nil
                     { "METHOD" => "post", "ENCTYPE" => enctype } 
                   elsif action.kind_of?(String)
                     { "METHOD" => "post", "ACTION" => action,
                       "ENCTYPE" => enctype } 
                   else
                     unless action.has_key?("METHOD")
                       action["METHOD"] = "post"
                     end
                     unless action.has_key?("ENCTYPE")
                       action["ENCTYPE"] = enctype
                     end
                     action
                   end
      if block_given?
        form(attributes){ yield }
      else
        form(attributes)
      end
    end


    # Generate a Password Input element as a string.
    #
    # +name+ is the name of the input field.  +value+ is its default
    # value.  +size+ is the size of the input field display.  +maxlength+
    # is the maximum length of the inputted password.
    #
    # Alternatively, attributes can be specified as a hash.
    #
    #   password_field("name")
    #     # <INPUT TYPE="password" NAME="name" SIZE="40">
    # 
    #   password_field("name", "value")
    #     # <INPUT TYPE="password" NAME="name" VALUE="value" SIZE="40">
    # 
    #   password_field("password", "value", 80, 200)
    #     # <INPUT TYPE="password" NAME="name" VALUE="value" SIZE="80" MAXLENGTH="200">
    # 
    #   password_field("NAME" => "name", "VALUE" => "value")
    #     # <INPUT TYPE="password" NAME="name" VALUE="value">
    def password_field(name = "", value = nil, size = 40, maxlength = nil)
      attributes = if name.kind_of?(String)
                     { "TYPE" => "password", "NAME" => name,
                       "VALUE" => value, "SIZE" => size.to_s }
                   else
                     name["TYPE"] = "password"
                     name
                   end
      attributes["MAXLENGTH"] = maxlength.to_s if maxlength
      input(attributes)
    end

    # Generate a Select element as a string.
    #
    # +name+ is the name of the element.  The +values+ are the options that
    # can be selected from the Select menu.  Each value can be a String or
    # a one, two, or three-element Array.  If a String or a one-element
    # Array, this is both the value of that option and the text displayed for
    # it.  If a three-element Array, the elements are the option value, displayed
    # text, and a boolean value specifying whether this option starts as selected.
    # The two-element version omits either the option value (defaults to the same
    # as the display text) or the boolean selected specifier (defaults to false).
    #
    # The attributes and options can also be specified as a hash.  In this
    # case, options are specified as an array of values as described above,
    # with the hash key of "VALUES".
    #
    #   popup_menu("name", "foo", "bar", "baz")
    #     # <SELECT NAME="name">
    #     #   <OPTION VALUE="foo">foo</OPTION>
    #     #   <OPTION VALUE="bar">bar</OPTION>
    #     #   <OPTION VALUE="baz">baz</OPTION>
    #     # </SELECT>
    # 
    #   popup_menu("name", ["foo"], ["bar", true], "baz")
    #     # <SELECT NAME="name">
    #     #   <OPTION VALUE="foo">foo</OPTION>
    #     #   <OPTION VALUE="bar" SELECTED>bar</OPTION>
    #     #   <OPTION VALUE="baz">baz</OPTION>
    #     # </SELECT>
    # 
    #   popup_menu("name", ["1", "Foo"], ["2", "Bar", true], "Baz")
    #     # <SELECT NAME="name">
    #     #   <OPTION VALUE="1">Foo</OPTION>
    #     #   <OPTION SELECTED VALUE="2">Bar</OPTION>
    #     #   <OPTION VALUE="Baz">Baz</OPTION>
    #     # </SELECT>
    # 
    #   popup_menu("NAME" => "name", "SIZE" => 2, "MULTIPLE" => true,
    #               "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"])
    #     # <SELECT NAME="name" MULTIPLE SIZE="2">
    #     #   <OPTION VALUE="1">Foo</OPTION>
    #     #   <OPTION SELECTED VALUE="2">Bar</OPTION>
    #     #   <OPTION VALUE="Baz">Baz</OPTION>
    #     # </SELECT>
    def popup_menu(name = "", *values)

      if name.kind_of?(Hash)
        values   = name["VALUES"]
        size     = name["SIZE"].to_s if name["SIZE"]
        multiple = name["MULTIPLE"]
        name     = name["NAME"]
      else
        size = nil
        multiple = nil
      end

      select({ "NAME" => name, "SIZE" => size,
               "MULTIPLE" => multiple }){
        values.collect{|value|
          if value.kind_of?(String)
            option({ "VALUE" => value }){ value }
          else
            if value[value.size - 1] == true
              option({ "VALUE" => value[0], "SELECTED" => true }){
                value[value.size - 2]
              }
            else
              option({ "VALUE" => value[0] }){
                value[value.size - 1]
              }
            end
          end
        }.to_s
      }

    end

    # Generates a radio-button Input element.
    #
    # +name+ is the name of the input field.  +value+ is the value of
    # the field if checked.  +checked+ specifies whether the field
    # starts off checked.
    #
    # Alternatively, the attributes can be specified as a hash.
    #
    #   radio_button("name", "value")
    #     # <INPUT TYPE="radio" NAME="name" VALUE="value">
    # 
    #   radio_button("name", "value", true)
    #     # <INPUT TYPE="radio" NAME="name" VALUE="value" CHECKED>
    # 
    #   radio_button("NAME" => "name", "VALUE" => "value", "ID" => "foo")
    #     # <INPUT TYPE="radio" NAME="name" VALUE="value" ID="foo">
    def radio_button(name = "", value = nil, checked = nil)
      attributes = if name.kind_of?(String)
                     { "TYPE" => "radio", "NAME" => name,
                       "VALUE" => value, "CHECKED" => checked }
                   else
                     name["TYPE"] = "radio"
                     name
                   end
      input(attributes)
    end

    # Generate a sequence of radio button Input elements, as a String.
    #
    # This works the same as #checkbox_group().  However, it is not valid
    # to have more than one radiobutton in a group checked.
    # 
    #   radio_group("name", "foo", "bar", "baz")
    #     # <INPUT TYPE="radio" NAME="name" VALUE="foo">foo
    #     # <INPUT TYPE="radio" NAME="name" VALUE="bar">bar
    #     # <INPUT TYPE="radio" NAME="name" VALUE="baz">baz
    # 
    #   radio_group("name", ["foo"], ["bar", true], "baz")
    #     # <INPUT TYPE="radio" NAME="name" VALUE="foo">foo
    #     # <INPUT TYPE="radio" CHECKED NAME="name" VALUE="bar">bar
    #     # <INPUT TYPE="radio" NAME="name" VALUE="baz">baz
    # 
    #   radio_group("name", ["1", "Foo"], ["2", "Bar", true], "Baz")
    #     # <INPUT TYPE="radio" NAME="name" VALUE="1">Foo
    #     # <INPUT TYPE="radio" CHECKED NAME="name" VALUE="2">Bar
    #     # <INPUT TYPE="radio" NAME="name" VALUE="Baz">Baz
    # 
    #   radio_group("NAME" => "name",
    #                 "VALUES" => ["foo", "bar", "baz"])
    # 
    #   radio_group("NAME" => "name",
    #                 "VALUES" => [["foo"], ["bar", true], "baz"])
    # 
    #   radio_group("NAME" => "name",
    #                 "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"])
    def radio_group(name = "", *values)
      if name.kind_of?(Hash)
        values = name["VALUES"]
        name = name["NAME"]
      end
      values.collect{|value|
        if value.kind_of?(String)
          radio_button(name, value) + value
        else
          if value[value.size - 1] == true
            radio_button(name, value[0], true) +
            value[value.size - 2]
          else
            radio_button(name, value[0]) +
            value[value.size - 1]
          end
        end
      }.to_s
    end

    # Generate a reset button Input element, as a String.
    #
    # This resets the values on a form to their initial values.  +value+
    # is the text displayed on the button. +name+ is the name of this button.
    #
    # Alternatively, the attributes can be specified as a hash.
    #
    #   reset
    #     # <INPUT TYPE="reset">
    # 
    #   reset("reset")
    #     # <INPUT TYPE="reset" VALUE="reset">
    # 
    #   reset("VALUE" => "reset", "ID" => "foo")
    #     # <INPUT TYPE="reset" VALUE="reset" ID="foo">
    def reset(value = nil, name = nil)
      attributes = if (not value) or value.kind_of?(String)
                     { "TYPE" => "reset", "VALUE" => value, "NAME" => name }
                   else
                     value["TYPE"] = "reset"
                     value
                   end
      input(attributes)
    end

    alias scrolling_list popup_menu

    # Generate a submit button Input element, as a String.
    #
    # +value+ is the text to display on the button.  +name+ is the name
    # of the input.
    #
    # Alternatively, the attributes can be specified as a hash.
    #
    #   submit
    #     # <INPUT TYPE="submit">
    # 
    #   submit("ok")
    #     # <INPUT TYPE="submit" VALUE="ok">
    # 
    #   submit("ok", "button1")
    #     # <INPUT TYPE="submit" VALUE="ok" NAME="button1">
    # 
    #   submit("VALUE" => "ok", "NAME" => "button1", "ID" => "foo")
    #     # <INPUT TYPE="submit" VALUE="ok" NAME="button1" ID="foo">
    def submit(value = nil, name = nil)
      attributes = if (not value) or value.kind_of?(String)
                     { "TYPE" => "submit", "VALUE" => value, "NAME" => name }
                   else
                     value["TYPE"] = "submit"
                     value
                   end
      input(attributes)
    end

    # Generate a text field Input element, as a String.
    #
    # +name+ is the name of the input field.  +value+ is its initial
    # value.  +size+ is the size of the input area.  +maxlength+
    # is the maximum length of input accepted.
    #
    # Alternatively, the attributes can be specified as a hash.
    #
    #   text_field("name")
    #     # <INPUT TYPE="text" NAME="name" SIZE="40">
    # 
    #   text_field("name", "value")
    #     # <INPUT TYPE="text" NAME="name" VALUE="value" SIZE="40">
    # 
    #   text_field("name", "value", 80)
    #     # <INPUT TYPE="text" NAME="name" VALUE="value" SIZE="80">
    # 
    #   text_field("name", "value", 80, 200)
    #     # <INPUT TYPE="text" NAME="name" VALUE="value" SIZE="80" MAXLENGTH="200">
    # 
    #   text_field("NAME" => "name", "VALUE" => "value")
    #     # <INPUT TYPE="text" NAME="name" VALUE="value">
    def text_field(name = "", value = nil, size = 40, maxlength = nil)
      attributes = if name.kind_of?(String)
                     { "TYPE" => "text", "NAME" => name, "VALUE" => value,
                       "SIZE" => size.to_s }
                   else
                     name["TYPE"] = "text"
                     name
                   end
      attributes["MAXLENGTH"] = maxlength.to_s if maxlength
      input(attributes)
    end

    # Generate a TextArea element, as a String.
    #
    # +name+ is the name of the textarea.  +cols+ is the number of
    # columns and +rows+ is the number of rows in the display.
    #
    # Alternatively, the attributes can be specified as a hash.
    #
    # The body is provided by the passed-in no-argument block
    #
    #   textarea("name")
    #      # = textarea("NAME" => "name", "COLS" => 70, "ROWS" => 10)
    #
    #   textarea("name", 40, 5)
    #      # = textarea("NAME" => "name", "COLS" => 40, "ROWS" => 5)
    def textarea(name = "", cols = 70, rows = 10)  # :yield:
      attributes = if name.kind_of?(String)
                     { "NAME" => name, "COLS" => cols.to_s,
                       "ROWS" => rows.to_s }
                   else
                     name
                   end
      if block_given?
        super(attributes){ yield }
      else
        super(attributes)
      end
    end

  end # HtmlExtension


  # Mixin module for HTML version 3 generation methods.
  module Html3 # :nodoc:

    # The DOCTYPE declaration for this version of HTML
    def doctype
      %|<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">|
    end

    # Initialise the HTML generation methods for this version.
    def element_init
      extend TagMaker
      methods = ""
      # - -
      for element in %w[ A TT I B U STRIKE BIG SMALL SUB SUP EM STRONG
          DFN CODE SAMP KBD VAR CITE FONT ADDRESS DIV center MAP
          APPLET PRE XMP LISTING DL OL UL DIR MENU SELECT table TITLE
          STYLE SCRIPT H1 H2 H3 H4 H5 H6 TEXTAREA FORM BLOCKQUOTE
          CAPTION ]
        methods += <<-BEGIN + nn_element_def(element) + <<-END
          def #{element.downcase}(attributes = {})
        BEGIN
          end
        END
      end

      # - O EMPTY
      for element in %w[ IMG BASE BASEFONT BR AREA LINK PARAM HR INPUT
          ISINDEX META ]
        methods += <<-BEGIN + nOE_element_def(element) + <<-END
          def #{element.downcase}(attributes = {})
        BEGIN
          end
        END
      end

      # O O or - O
      for element in %w[ HTML HEAD BODY P PLAINTEXT DT DD LI OPTION tr
          th td ]
        methods += <<-BEGIN + nO_element_def(element) + <<-END
          def #{element.downcase}(attributes = {})
        BEGIN
          end
        END
      end
      eval(methods)
    end

  end # Html3


  # Mixin module for HTML version 4 generation methods.
  module Html4 # :nodoc:

    # The DOCTYPE declaration for this version of HTML
    def doctype
      %|<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">|
    end

    # Initialise the HTML generation methods for this version.
    def element_init
      extend TagMaker
      methods = ""
      # - -
      for element in %w[ TT I B BIG SMALL EM STRONG DFN CODE SAMP KBD
        VAR CITE ABBR ACRONYM SUB SUP SPAN BDO ADDRESS DIV MAP OBJECT
        H1 H2 H3 H4 H5 H6 PRE Q INS DEL DL OL UL LABEL SELECT OPTGROUP
        FIELDSET LEGEND BUTTON TABLE TITLE STYLE SCRIPT NOSCRIPT
        TEXTAREA FORM A BLOCKQUOTE CAPTION ]
        methods += <<-BEGIN + nn_element_def(element) + <<-END
          def #{element.downcase}(attributes = {})
        BEGIN
          end
        END
      end

      # - O EMPTY
      for element in %w[ IMG BASE BR AREA LINK PARAM HR INPUT COL META ]
        methods += <<-BEGIN + nOE_element_def(element) + <<-END
          def #{element.downcase}(attributes = {})
        BEGIN
          end
        END
      end

      # O O or - O
      for element in %w[ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY
          COLGROUP TR TH TD HEAD]
        methods += <<-BEGIN + nO_element_def(element) + <<-END
          def #{element.downcase}(attributes = {})
        BEGIN
          end
        END
      end
      eval(methods)
    end

  end # Html4


  # Mixin module for HTML version 4 transitional generation methods.
  module Html4Tr # :nodoc:

    # The DOCTYPE declaration for this version of HTML
    def doctype
      %|<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">|
    end

    # Initialise the HTML generation methods for this version.
    def element_init
      extend TagMaker
      methods = ""
      # - -
      for element in %w[ TT I B U S STRIKE BIG SMALL EM STRONG DFN
          CODE SAMP KBD VAR CITE ABBR ACRONYM FONT SUB SUP SPAN BDO
          ADDRESS DIV CENTER MAP OBJECT APPLET H1 H2 H3 H4 H5 H6 PRE Q
          INS DEL DL OL UL DIR MENU LABEL SELECT OPTGROUP FIELDSET
          LEGEND BUTTON TABLE IFRAME NOFRAMES TITLE STYLE SCRIPT
          NOSCRIPT TEXTAREA FORM A BLOCKQUOTE CAPTION ]
        methods += <<-BEGIN + nn_element_def(element) + <<-END
          def #{element.downcase}(attributes = {})
        BEGIN
          end
        END
      end

      # - O EMPTY
      for element in %w[ IMG BASE BASEFONT BR AREA LINK PARAM HR INPUT
          COL ISINDEX META ]
        methods += <<-BEGIN + nOE_element_def(element) + <<-END
          def #{element.downcase}(attributes = {})
        BEGIN
          end
        END
      end

      # O O or - O
      for element in %w[ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY
          COLGROUP TR TH TD HEAD ]
        methods += <<-BEGIN + nO_element_def(element) + <<-END
          def #{element.downcase}(attributes = {})
        BEGIN
          end
        END
      end
      eval(methods)
    end

  end # Html4Tr


  # Mixin module for generating HTML version 4 with framesets.
  module Html4Fr # :nodoc:

    # The DOCTYPE declaration for this version of HTML
    def doctype
      %|<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">|
    end

    # Initialise the HTML generation methods for this version.
    def element_init
      methods = ""
      # - -
      for element in %w[ FRAMESET ]
        methods += <<-BEGIN + nn_element_def(element) + <<-END
          def #{element.downcase}(attributes = {})
        BEGIN
          end
        END
      end

      # - O EMPTY
      for element in %w[ FRAME ]
        methods += <<-BEGIN + nOE_element_def(element) + <<-END
          def #{element.downcase}(attributes = {})
        BEGIN
          end
        END
      end
      eval(methods)
    end

  end # Html4Fr


  # Creates a new CGI instance.
  #
  # +type+ specifies which version of HTML to load the HTML generation
  # methods for.  The following versions of HTML are supported:
  #
  # html3:: HTML 3.x
  # html4:: HTML 4.0
  # html4Tr:: HTML 4.0 Transitional
  # html4Fr:: HTML 4.0 with Framesets
  #
  # If not specified, no HTML generation methods will be loaded.
  #
  # If the CGI object is not created in a standard CGI call environment
  # (that is, it can't locate REQUEST_METHOD in its environment), then
  # it will run in "offline" mode.  In this mode, it reads its parameters
  # from the command line or (failing that) from standard input.  Otherwise,
  # cookies and other parameters are parsed automatically from the standard
  # CGI locations, which varies according to the REQUEST_METHOD.
  def initialize(type = "query")
    if defined?(MOD_RUBY) && !ENV.key?("GATEWAY_INTERFACE")
      Apache.request.setup_cgi_env
    end

    extend QueryExtension
    @multipart = false
    if defined?(CGI_PARAMS)
      warn "do not use CGI_PARAMS and CGI_COOKIES"
      @params = CGI_PARAMS.dup
      @cookies = CGI_COOKIES.dup
    else
      initialize_query()  # set @params, @cookies
    end
    @output_cookies = nil
    @output_hidden = nil

    case type
    when "html3"
      extend Html3
      element_init()
      extend HtmlExtension
    when "html4"
      extend Html4
      element_init()
      extend HtmlExtension
    when "html4Tr"
      extend Html4Tr
      element_init()
      extend HtmlExtension
    when "html4Fr"
      extend Html4Tr
      element_init()
      extend Html4Fr
      element_init()
      extend HtmlExtension
    end
  end

end   # class CGI
PK     Y\0)  )    openssl/pkcs7.rbnu [        =begin
= $RCSfile$ -- PKCS7

= Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

= Version
  $Id: digest.rb 12148 2007-04-05 05:59:22Z technorama $
=end

module OpenSSL
  class PKCS7
    # This class is only provided for backwards compatibility.  Use OpenSSL::PKCS7 in the future.
    class PKCS7 < PKCS7
      def initialize(*args)
        super(*args)

        warn("Warning: OpenSSL::PKCS7::PKCS7 is deprecated after Ruby 1.9; use OpenSSL::PKCS7 instead")
      end
    end

  end # PKCS7
end # OpenSSL

PK     Y\
  
    openssl/x509-internal.rbnu [        =begin
= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for X509 and subclasses

= Info
  'OpenSSL for Ruby 2' project
  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>
  All rights reserved.

= Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

= Version
  $Id$
=end

module OpenSSL
  module X509
    class ExtensionFactory
      def create_extension(*arg)
        if arg.size > 1
          create_ext(*arg)
        else
          send("create_ext_from_"+arg[0].class.name.downcase, arg[0])
        end
      end

      def create_ext_from_array(ary)
        raise ExtensionError, "unexpected array form" if ary.size > 3
        create_ext(ary[0], ary[1], ary[2])
      end

      def create_ext_from_string(str) # "oid = critical, value"
        oid, value = str.split(/=/, 2)
        oid.strip!
        value.strip!
        create_ext(oid, value)
      end

      def create_ext_from_hash(hash)
        create_ext(hash["oid"], hash["value"], hash["critical"])
      end
    end

    class Extension
      def to_s # "oid = critical, value"
        str = self.oid
        str << " = "
        str << "critical, " if self.critical?
        str << self.value.gsub(/\n/, ", ")
      end

      def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false}
        {"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?}
      end

      def to_a
        [ self.oid, self.value, self.critical? ]
      end
    end

    class Name
      module RFC2253DN
        Special = ',=+<>#;'
        HexChar = /[0-9a-fA-F]/
        HexPair = /#{HexChar}#{HexChar}/
        HexString = /#{HexPair}+/
        Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/
        StringChar = /[^#{Special}\\"]/
        QuoteChar = /[^\\"]/
        AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/
        AttributeValue = /
          (?!["#])((?:#{StringChar}|#{Pair})*)|
          \#(#{HexString})|
          "((?:#{QuoteChar}|#{Pair})*)"
        /x
        TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/

        module_function

        def expand_pair(str)
          return nil unless str
          return str.gsub(Pair){
            pair = $&
            case pair.size
            when 2 then pair[1,1]
            when 3 then Integer("0x#{pair[1,2]}").chr
            else raise OpenSSL::X509::NameError, "invalid pair: #{str}"
            end
          }
        end

        def expand_hexstring(str)
          return nil unless str
          der = str.gsub(HexPair){$&.to_i(16).chr }
          a1 = OpenSSL::ASN1.decode(der)
          return a1.value, a1.tag
        end

        def expand_value(str1, str2, str3)
          value = expand_pair(str1)
          value, tag = expand_hexstring(str2) unless value
          value = expand_pair(str3) unless value
          return value, tag
        end

        def scan(dn)
          str = dn
          ary = []
          while true
            if md = TypeAndValue.match(str)
              matched = md.to_s
              remain = md.post_match
              type = md[1]
              value, tag = expand_value(md[2], md[3], md[4]) rescue nil
              if value
                type_and_value = [type, value]
                type_and_value.push(tag) if tag
                ary.unshift(type_and_value)
                if remain.length > 2 && remain[0] == ?,
                  str = remain[1..-1]
                  next
                elsif remain.length > 2 && remain[0] == ?+
                  raise OpenSSL::X509::NameError,
                    "multi-valued RDN is not supported: #{dn}"
                elsif remain.empty?
                  break
                end
              end
            end
            msg_dn = dn[0, dn.length - str.length] + " =>" + str
            raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}"
          end
          return ary
        end
      end

      class <<self
        def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
          ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
          self.new(ary, template)
        end

        def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
          ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
          self.new(ary, template)
        end

        alias parse parse_openssl
      end
    end
  end
end
PK     Y\`      openssl/cipher.rbnu [        =begin
= $RCSfile$ -- Ruby-space predefined Cipher subclasses

= Info
  'OpenSSL for Ruby 2' project
  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>
  All rights reserved.

= Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

= Version
  $Id: cipher.rb 12496 2007-06-08 15:02:04Z technorama $
=end

##
# Should we care what if somebody require this file directly?
#require 'openssl'

module OpenSSL
  class Cipher
    %w(AES CAST5 BF DES IDEA RC2 RC4 RC5).each{|name|
      klass = Class.new(Cipher){
        define_method(:initialize){|*args|
          cipher_name = args.inject(name){|n, arg| "#{n}-#{arg}" }
          super(cipher_name)
        }
      }
      const_set(name, klass)
    }

    %w(128 192 256).each{|keylen|
      klass = Class.new(Cipher){
        define_method(:initialize){|mode|
          mode ||= "CBC"
          cipher_name = "AES-#{keylen}-#{mode}"
          super(cipher_name)
        }
      }
      const_set("AES#{keylen}", klass)
    }

    # Generate, set, and return a random key.
    # You must call cipher.encrypt or cipher.decrypt before calling this method.
    def random_key
      str = OpenSSL::Random.random_bytes(self.key_len)
      self.key = str
      return str
    end

    # Generate, set, and return a random iv.
    # You must call cipher.encrypt or cipher.decrypt before calling this method.
    def random_iv
      str = OpenSSL::Random.random_bytes(self.iv_len)
      self.iv = str
      return str
    end

    # This class is only provided for backwards compatibility.  Use OpenSSL::Digest in the future.
    class Cipher < Cipher
      # add warning
    end
  end # Cipher
end # OpenSSL
PK     Y\z      openssl/bn.rbnu [        =begin
= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for BN

= Info
  'OpenSSL for Ruby 2' project
  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>
  All rights reserved.

= Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

= Version
  $Id: bn.rb 31657 2011-05-20 22:25:35Z shyouhei $
=end

##
# Should we care what if somebody require this file directly?
#require 'openssl'

module OpenSSL
  class BN
    include Comparable
  end # BN
end # OpenSSL

##
# Add double dispatch to Integer
#
class Integer
  def to_bn
    OpenSSL::BN::new(self.to_s(16), 16)
  end
end # Integer

PK     Y\p3`      openssl/buffering.rbnu [        =begin
= $RCSfile$ -- Buffering mix-in module.

= Info
  'OpenSSL for Ruby 2' project
  Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
  All rights reserved.

= Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

= Version
  $Id: buffering.rb 28004 2010-05-24 23:58:49Z shyouhei $
=end

module OpenSSL
module Buffering
  include Enumerable
  attr_accessor :sync
  BLOCK_SIZE = 1024*16

  def initialize(*args)
    @eof = false
    @rbuffer = ""
    @sync = @io.sync
  end

  #
  # for reading.
  #
  private

  def fill_rbuff
    begin
      @rbuffer << self.sysread(BLOCK_SIZE)
    rescue Errno::EAGAIN
      retry
    rescue EOFError
      @eof = true
    end
  end

  def consume_rbuff(size=nil)
    if @rbuffer.empty?
      nil
    else
      size = @rbuffer.size unless size
      ret = @rbuffer[0, size]
      @rbuffer[0, size] = ""
      ret
    end
  end

  public

  def read(size=nil, buf=nil)
    if size == 0
      if buf
        buf.clear
      else
        buf = ""
      end
      return @eof ? nil : buf
    end
    until @eof
      break if size && size <= @rbuffer.size
      fill_rbuff
    end
    ret = consume_rbuff(size) || ""
    if buf
      buf.replace(ret)
      ret = buf
    end
    (size && ret.empty?) ? nil : ret
  end

  def readpartial(maxlen, buf=nil)
    if maxlen == 0
      if buf
        buf.clear
      else
        buf = ""
      end
      return @eof ? nil : buf
    end
    if @rbuffer.empty?
      begin
        return sysread(maxlen, buf)
      rescue Errno::EAGAIN
        retry
      end
    end
    ret = consume_rbuff(maxlen)
    if buf
      buf.replace(ret)
      ret = buf
    end
    raise EOFError if ret.empty?
    ret
  end

  def gets(eol=$/)
    idx = @rbuffer.index(eol)
    until @eof
      break if idx
      fill_rbuff
      idx = @rbuffer.index(eol)
    end
    if eol.is_a?(Regexp)
      size = idx ? idx+$&.size : nil
    else
      size = idx ? idx+eol.size : nil
    end
    consume_rbuff(size)
  end

  def each(eol=$/)
    while line = self.gets(eol)
      yield line
    end
  end
  alias each_line each

  def readlines(eol=$/)
    ary = []
    while line = self.gets(eol)
      ary << line
    end
    ary
  end

  def readline(eol=$/)
    raise EOFError if eof?
    gets(eol)
  end

  def getc
    c = read(1)
    c ? c[0] : nil
  end

  def each_byte
    while c = getc
      yield(c)
    end
  end

  def readchar
    raise EOFError if eof?
    getc
  end

  def ungetc(c)
    @rbuffer[0,0] = c.chr
  end

  def eof?
    fill_rbuff if !@eof && @rbuffer.empty?
    @eof && @rbuffer.empty?
  end
  alias eof eof?

  #
  # for writing.
  #
  private

  def do_write(s)
    @wbuffer = "" unless defined? @wbuffer
    @wbuffer << s
    @sync ||= false
    if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/)
      remain = idx ? idx + $/.size : @wbuffer.length
      nwritten = 0
      while remain > 0
        str = @wbuffer[nwritten,remain]
        begin
          nwrote = syswrite(str)
        rescue Errno::EAGAIN
          retry
        end
        remain -= nwrote
        nwritten += nwrote
      end
      @wbuffer[0,nwritten] = ""
    end
  end

  public

  def write(s)
    do_write(s)
    s.length
  end

  def << (s)
    do_write(s)
    self
  end

  def puts(*args)
    s = ""
    if args.empty?
      s << "\n"
    end
    args.each{|arg|
      s << arg.to_s
      if $/ && /\n\z/ !~ s
        s << "\n"
      end
    }
    do_write(s)
    nil
  end

  def print(*args)
    s = ""
    args.each{ |arg| s << arg.to_s }
    do_write(s)
    nil
  end

  def printf(s, *args)
    do_write(s % args)
    nil
  end

  def flush
    osync = @sync
    @sync = true
    do_write ""
    @sync = osync
  end

  def close
    flush rescue nil
    sysclose
  end
end
end
PK     Y\)s        openssl/ssl.rbnu [        require 'openssl'
PK     Y\E=L  L    openssl/config.rbnu [        =begin
= Ruby-space definitions that completes C-space funcs for Config

= Info
  Copyright (C) 2010  Hiroshi Nakamura <nahi@ruby-lang.org>

= Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

=end

##
# Should we care what if somebody require this file directly?
#require 'openssl'
require 'stringio'

module OpenSSL
  class Config
    include Enumerable

    class << self
      def parse(str)
        c = new()
        parse_config(StringIO.new(str)).each do |section, hash|
          c[section] = hash
        end
        c
      end

      alias load new

      def parse_config(io)
        begin
          parse_config_lines(io)
        rescue ConfigError => e
          e.message.replace("error in line #{io.lineno}: " + e.message)
          raise
        end
      end

      def get_key_string(data, section, key) # :nodoc:
        if v = data[section] && data[section][key]
          return v
        elsif section == 'ENV'
          if v = ENV[key]
            return v
          end
        end
        if v = data['default'] && data['default'][key]
          return v
        end
      end

    private

      def parse_config_lines(io)
        section = 'default'
        data = {section => {}}
        while definition = get_definition(io)
          definition = clear_comments(definition)
          next if definition.empty?
          if definition[0] == ?[
            if /\[([^\]]*)\]/ =~ definition
              section = $1.strip
              data[section] ||= {}
            else
              raise ConfigError, "missing close square bracket"
            end
          else
            if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition
              if $2
                section = $1
                key = $2
              else
                key = $1
              end
              value = unescape_value(data, section, $3)
              (data[section] ||= {})[key] = value.strip
            else
              raise ConfigError, "missing equal sign"
            end
          end
        end
        data
      end

      # escape with backslash
      QUOTE_REGEXP_SQ = /\A([^'\\]*(?:\\.[^'\\]*)*)'/
      # escape with backslash and doubled dq
      QUOTE_REGEXP_DQ = /\A([^"\\]*(?:""[^"\\]*|\\.[^"\\]*)*)"/
      # escaped char map
      ESCAPE_MAP = {
        "r" => "\r",
        "n" => "\n",
        "b" => "\b",
        "t" => "\t",
      }

      def unescape_value(data, section, value)
        scanned = []
        while m = value.match(/['"\\$]/)
          scanned << m.pre_match
          c = m[0]
          value = m.post_match
          case c
          when "'"
            if m = value.match(QUOTE_REGEXP_SQ)
              scanned << m[1].gsub(/\\(.)/, '\\1')
              value = m.post_match
            else
              break
            end
          when '"'
            if m = value.match(QUOTE_REGEXP_DQ)
              scanned << m[1].gsub(/""/, '').gsub(/\\(.)/, '\\1')
              value = m.post_match
            else
              break
            end
          when "\\"
            c = value.slice!(0, 1)
            scanned << (ESCAPE_MAP[c] || c)
          when "$"
            ref, value = extract_reference(value)
            refsec = section
            if ref.index('::')
              refsec, ref = ref.split('::', 2)
            end
            if v = get_key_string(data, refsec, ref)
              scanned << v
            else
              raise ConfigError, "variable has no value"
            end
          else
            raise 'must not reaced'
          end
        end
        scanned << value
        scanned.join
      end

      def extract_reference(value)
        rest = ''
        if m = value.match(/\(([^)]*)\)|\{([^}]*)\}/)
          value = m[1] || m[2]
          rest = m.post_match
        elsif [?(, ?{].include?(value[0])
          raise ConfigError, "no close brace"
        end
        if m = value.match(/[a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]*)?/)
          return m[0], m.post_match + rest
        else
          raise
        end
      end

      def clear_comments(line)
        # FCOMMENT
        if m = line.match(/\A([\t\n\f ]*);.*\z/)
          return m[1]
        end
        # COMMENT
        scanned = []
        while m = line.match(/[#'"\\]/)
          scanned << m.pre_match
          c = m[0]
          line = m.post_match
          case c
          when '#'
            line = nil
            break
          when "'", '"'
            regexp = (c == "'") ? QUOTE_REGEXP_SQ : QUOTE_REGEXP_DQ
            scanned << c
            if m = line.match(regexp)
              scanned << m[0]
              line = m.post_match
            else
              scanned << line
              line = nil
              break
            end
          when "\\"
            scanned << c
            scanned << line.slice!(0, 1)
          else
            raise 'must not reaced'
          end
        end
        scanned << line
        scanned.join
      end

      def get_definition(io)
        if line = get_line(io)
          while /[^\\]\\\z/ =~ line
            if extra = get_line(io)
              line += extra
            else
              break
            end
          end
          return line.strip
        end
      end

      def get_line(io)
        if line = io.gets
          line.gsub(/[\r\n]*/, '')
        end
      end
    end

    def initialize(filename = nil)
      @data = {}
      if filename
        File.open(filename.to_s) do |file|
          Config.parse_config(file).each do |section, hash|
            self[section] = hash
          end
        end
      end
    end

    def get_value(section, key)
      if section.nil?
        raise TypeError.new('nil not allowed')
      end
      section = 'default' if section.empty?
      get_key_string(section, key)
    end

    def value(arg1, arg2 = nil)
      warn('Config#value is deprecated; use Config#get_value')
      if arg2.nil?
        section, key = 'default', arg1
      else
        section, key = arg1, arg2
      end
      section ||= 'default'
      section = 'default' if section.empty?
      get_key_string(section, key)
    end

    def add_value(section, key, value)
      check_modify
      (@data[section] ||= {})[key] = value
    end

    def [](section)
      @data[section] || {}
    end

    def section(name)
      warn('Config#section is deprecated; use Config#[]')
      @data[name] || {}
    end

    def []=(section, pairs)
      check_modify
      @data[section] ||= {}
      pairs.each do |key, value|
        self.add_value(section, key, value)
      end
    end

    def sections
      @data.keys
    end

    def to_s
      ary = []
      @data.keys.sort.each do |section|
        ary << "[ #{section} ]\n"
        @data[section].keys.each do |key|
          ary << "#{key}=#{@data[section][key]}\n"
        end
        ary << "\n"
      end
      ary.join
    end

    def each
      @data.each do |section, hash|
        hash.each do |key, value|
          yield(section, key, value)
        end
      end
    end

    def inspect
      "#<#{self.class.name} sections=#{sections.inspect}>"
    end

  protected

    def data
      @data
    end

  private

    def initialize_copy(other)
      @data = other.data.dup
    end

    def check_modify
      raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen?
    end

    def get_key_string(section, key)
      Config.get_key_string(@data, section, key)
    end
  end
end
PK     Y\=f      openssl/digest.rbnu [        =begin
= $RCSfile$ -- Ruby-space predefined Digest subclasses

= Info
  'OpenSSL for Ruby 2' project
  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>
  All rights reserved.

= Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

= Version
  $Id: digest.rb 28004 2010-05-24 23:58:49Z shyouhei $
=end

##
# Should we care what if somebody require this file directly?
#require 'openssl'

module OpenSSL
  class Digest

    alg = %w(DSS DSS1 MD2 MD4 MD5 MDC2 RIPEMD160 SHA SHA1)
    if OPENSSL_VERSION_NUMBER > 0x00908000
      alg += %w(SHA224 SHA256 SHA384 SHA512)
    end

    def self.digest(name, data)
        super(data, name)
    end

    alg.each{|name|
      klass = Class.new(Digest){
        define_method(:initialize){|*data|
          if data.length > 1
            raise ArgumentError,
              "wrong number of arguments (#{data.length} for 1)"
          end
          super(name, data.first)
        }
      }
      singleton = (class << klass; self; end)
      singleton.class_eval{
        define_method(:digest){|data| Digest.digest(name, data) }
        define_method(:hexdigest){|data| Digest.hexdigest(name, data) }
      }
      const_set(name, klass)
    }

    # This class is only provided for backwards compatibility.  Use OpenSSL::Digest in the future.
    class Digest < Digest
      def initialize(*args)
        # add warning
        super(*args)
      end
    end

  end # Digest
end # OpenSSL

PK     Y\8       openssl/ssl-internal.rbnu [        =begin
= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL

= Info
  'OpenSSL for Ruby 2' project
  Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
  All rights reserved.

= Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

= Version
  $Id$
=end

require "openssl/buffering"
require "fcntl"

module OpenSSL
  module SSL
    class SSLContext
      DEFAULT_PARAMS = {
        :ssl_version => "SSLv23",
        :verify_mode => OpenSSL::SSL::VERIFY_PEER,
        :ciphers => "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
        :options => OpenSSL::SSL::OP_ALL,
      }

      DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
      DEFAULT_CERT_STORE.set_default_paths
      if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL)
        DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
      end

      def set_params(params={})
        params = DEFAULT_PARAMS.merge(params)
        # ssl_version need to be set at first.
        self.ssl_version = params.delete(:ssl_version)
        params.each{|name, value| self.__send__("#{name}=", value) }
        if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
          unless self.ca_file or self.ca_path or self.cert_store
            self.cert_store = DEFAULT_CERT_STORE
          end
        end
        return params
      end
    end

    module SocketForwarder
      def addr
        to_io.addr
      end

      def peeraddr
        to_io.peeraddr
      end

      def setsockopt(level, optname, optval)
        to_io.setsockopt(level, optname, optval)
      end

      def getsockopt(level, optname)
        to_io.getsockopt(level, optname)
      end

      def fcntl(*args)
        to_io.fcntl(*args)
      end

      def closed?
        to_io.closed?
      end

      def do_not_reverse_lookup=(flag)
        to_io.do_not_reverse_lookup = flag
      end
    end

    module Nonblock
      def initialize(*args)
        flag = File::NONBLOCK
        flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL)
        @io.fcntl(Fcntl::F_SETFL, flag)
        super
      end
    end

    def verify_certificate_identity(cert, hostname)
      should_verify_common_name = true
      cert.extensions.each{|ext|
        next if ext.oid != "subjectAltName"
        id, ostr = OpenSSL::ASN1.decode(ext.to_der).value
        sequence = OpenSSL::ASN1.decode(ostr.value)
        sequence.value.each{|san|
          case san.tag
          when 2 # dNSName in GeneralName (RFC5280)
            should_verify_common_name = false
            reg = Regexp.escape(san.value).gsub(/\\\*/, "[^.]+")
            return true if /\A#{reg}\z/i =~ hostname
          when 7 # iPAddress in GeneralName (RFC5280)
            should_verify_common_name = false
            # follows GENERAL_NAME_print() in x509v3/v3_alt.c
            if san.value.size == 4
              return true if san.value.unpack('C*').join('.') == hostname
            elsif san.value.size == 16
              return true if san.value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname
            end
          end
        }
      }
      if should_verify_common_name
        cert.subject.to_a.each{|oid, value|
          if oid == "CN"
            reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
            return true if /\A#{reg}\z/i =~ hostname
          end
        }
      end
      return false
    end
    module_function :verify_certificate_identity

    class SSLSocket
      include Buffering
      include SocketForwarder
      include Nonblock

      def post_connection_check(hostname)
        unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
          raise SSLError, "hostname was not match with the server certificate"
        end
        return true
      end

      def session
        SSL::Session.new(self)
      rescue SSL::Session::SessionError
        nil
      end
    end

    class SSLServer
      include SocketForwarder
      attr_accessor :start_immediately

      def initialize(svr, ctx)
        @svr = svr
        @ctx = ctx
        unless ctx.session_id_context
          session_id = OpenSSL::Digest::MD5.hexdigest($0)
          @ctx.session_id_context = session_id
        end
        @start_immediately = true
      end

      def to_io
        @svr
      end

      def listen(backlog=5)
        @svr.listen(backlog)
      end

      def shutdown(how=Socket::SHUT_RDWR)
        @svr.shutdown(how)
      end

      def accept
        sock = @svr.accept
        begin
          ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
          ssl.sync_close = true
          ssl.accept if @start_immediately
          ssl
        rescue SSLError => ex
          sock.close
          raise ex
        end
      end

      def close
        @svr.close
      end
    end
  end
end
PK     Y\)s        openssl/x509.rbnu [        require 'openssl'
PK     Y\ھ      rexml/syncenumerator.rbnu [        module REXML
  class SyncEnumerator
    include Enumerable

    # Creates a new SyncEnumerator which enumerates rows of given
    # Enumerable objects.
    def initialize(*enums)
      @gens = enums
      @biggest = @gens[0]
      @gens.each {|x| @biggest = x if x.size > @biggest.size }
    end

    # Returns the number of enumerated Enumerable objects, i.e. the size
    # of each row.
    def size
      @gens.size
    end

    # Returns the number of enumerated Enumerable objects, i.e. the size
    # of each row.
    def length
      @gens.length
    end

    # Enumerates rows of the Enumerable objects.
    def each
      @biggest.zip( *@gens ) {|a|
        yield(*a[1..-1])
      }
      self
    end
  end
end
PK     Y\Bu      rexml/output.rbnu [        require 'rexml/encoding'

module REXML
	class Output
		include Encoding
    
    attr_reader :encoding

		def initialize real_IO, encd="iso-8859-1"
			@output = real_IO
			self.encoding = encd

			@to_utf = encd == UTF_8 ? false : true
		end

		def <<( content )
			@output << (@to_utf ? self.encode(content) : content)
		end

    def to_s
      "Output[#{encoding}]"
    end
	end
end
PK     Y\nFj  j    rexml/entity.rbnu [        require 'rexml/child'
require 'rexml/source'
require 'rexml/xmltokens'

module REXML
	# God, I hate DTDs.  I really do.  Why this idiot standard still
	# plagues us is beyond me.
	class Entity < Child
		include XMLTokens
		PUBIDCHAR = "\x20\x0D\x0Aa-zA-Z0-9\\-()+,./:=?;!*@$_%#"
		SYSTEMLITERAL = %Q{((?:"[^"]*")|(?:'[^']*'))}
		PUBIDLITERAL = %Q{("[#{PUBIDCHAR}']*"|'[#{PUBIDCHAR}]*')}
		EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))"
		NDATADECL = "\\s+NDATA\\s+#{NAME}"
		PEREFERENCE = "%#{NAME};"
		ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))}
		PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})"
		ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))"
		PEDECL = "<!ENTITY\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>"
		GEDECL = "<!ENTITY\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>"
		ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um

		attr_reader :name, :external, :ref, :ndata, :pubid

		# Create a new entity.  Simple entities can be constructed by passing a
		# name, value to the constructor; this creates a generic, plain entity
		# reference. For anything more complicated, you have to pass a Source to
		# the constructor with the entity definiton, or use the accessor methods.
		# +WARNING+: There is no validation of entity state except when the entity
		# is read from a stream.  If you start poking around with the accessors,
		# you can easily create a non-conformant Entity.  The best thing to do is
		# dump the stupid DTDs and use XMLSchema instead.
		# 
		#  e = Entity.new( 'amp', '&' )
		def initialize stream, value=nil, parent=nil, reference=false
			super(parent)
			@ndata = @pubid = @value = @external = nil
			if stream.kind_of? Array
				@name = stream[1]
				if stream[-1] == '%'
					@reference = true 
					stream.pop
				else
					@reference = false
				end
				if stream[2] =~ /SYSTEM|PUBLIC/
					@external = stream[2]
					if @external == 'SYSTEM'
						@ref = stream[3]
						@ndata = stream[4] if stream.size == 5
					else
						@pubid = stream[3]
						@ref = stream[4]
					end
				else
					@value = stream[2]
				end
			else
				@reference = reference
				@external = nil
				@name = stream
				@value = value
			end
		end

		# Evaluates whether the given string matchs an entity definition,
		# returning true if so, and false otherwise.
		def Entity::matches? string
			(ENTITYDECL =~ string) == 0
		end

		# Evaluates to the unnormalized value of this entity; that is, replacing
		# all entities -- both %ent; and &ent; entities.  This differs from
		# +value()+ in that +value+ only replaces %ent; entities.
		def unnormalized
                        document.record_entity_expansion unless document.nil?
			v = value()
			return nil if v.nil?
			@unnormalized = Text::unnormalize(v, parent)
			@unnormalized
		end

		#once :unnormalized

		# Returns the value of this entity unprocessed -- raw.  This is the
		# normalized value; that is, with all %ent; and &ent; entities intact
		def normalized
			@value
		end

		# Write out a fully formed, correct entity definition (assuming the Entity
		# object itself is valid.)
    #
    # out::
    #   An object implementing <TT>&lt;&lt;<TT> to which the entity will be
    #   output
    # indent::
    #   *DEPRECATED* and ignored
		def write out, indent=-1
			out << '<!ENTITY '
			out << '% ' if @reference
			out << @name
			out << ' '
			if @external
				out << @external << ' '
				if @pubid
					q = @pubid.include?('"')?"'":'"'
					out << q << @pubid << q << ' '
				end
				q = @ref.include?('"')?"'":'"'
				out << q << @ref << q
				out << ' NDATA ' << @ndata if @ndata
			else
				q = @value.include?('"')?"'":'"'
				out << q << @value << q
			end
			out << '>'
		end

		# Returns this entity as a string.  See write().
		def to_s
			rv = ''
			write rv
			rv
		end

		PEREFERENCE_RE = /#{PEREFERENCE}/um
		# Returns the value of this entity.  At the moment, only internal entities
		# are processed.  If the value contains internal references (IE,
		# %blah;), those are replaced with their values.  IE, if the doctype
		# contains:
		#  <!ENTITY % foo "bar">
		#  <!ENTITY yada "nanoo %foo; nanoo>
		# then:
		#  doctype.entity('yada').value   #-> "nanoo bar nanoo"
		def value
			if @value
				matches = @value.scan(PEREFERENCE_RE)
				rv = @value.clone
				if @parent
					matches.each do |entity_reference|
						entity_value = @parent.entity( entity_reference[0] )
						rv.gsub!( /%#{entity_reference};/um, entity_value )
					end
				end
				return rv
			end
			nil
		end
	end

	# This is a set of entity constants -- the ones defined in the XML
	# specification.  These are +gt+, +lt+, +amp+, +quot+ and +apos+.
	module EntityConst
		# +>+
		GT = Entity.new( 'gt', '>' )
		# +<+
		LT = Entity.new( 'lt', '<' )
		# +&+
		AMP = Entity.new( 'amp', '&' )
		# +"+
		QUOT = Entity.new( 'quot', '"' )
		# +'+
		APOS = Entity.new( 'apos', "'" )
	end
end
PK     Y\Fyk  k    rexml/dtd/dtd.rbnu [        require "rexml/dtd/elementdecl"
require "rexml/dtd/entitydecl"
require "rexml/comment"
require "rexml/dtd/notationdecl"
require "rexml/dtd/attlistdecl"
require "rexml/parent"

module REXML
	module DTD
		class Parser
			def Parser.parse( input )
				case input
				when String
					parse_helper input
				when File
					parse_helper input.read
				end
			end

			# Takes a String and parses it out
			def Parser.parse_helper( input )
				contents = Parent.new
				while input.size > 0
					case input
					when ElementDecl.PATTERN_RE
						match = $&
						source = $'
						contents << ElementDecl.new( match )
					when AttlistDecl.PATTERN_RE
						matchdata = $~
						source = $'
						contents << AttlistDecl.new( matchdata )
					when EntityDecl.PATTERN_RE
						matchdata = $~
						source = $'
						contents << EntityDecl.new( matchdata )
					when Comment.PATTERN_RE
						matchdata = $~
						source = $'
						contents << Comment.new( matchdata )
					when NotationDecl.PATTERN_RE
						matchdata = $~
						source = $'
						contents << NotationDecl.new( matchdata )
					end
				end
				contents
			end
		end
	end
end
PK     Y\|昶        rexml/dtd/attlistdecl.rbnu [        require "rexml/child"
module REXML
	module DTD
		class AttlistDecl < Child
			START = "<!ATTLIST"
			START_RE = /^\s*#{START}/um
			PATTERN_RE = /\s*(#{START}.*?>)/um
		end
	end
end
PK     Y\
_      rexml/dtd/elementdecl.rbnu [        require "rexml/child"
module REXML
	module DTD
		class ElementDecl < Child
			START = "<!ELEMENT"
			START_RE = /^\s*#{START}/um
			PATTERN_RE = /^\s*(#{START}.*?)>/um
			PATTERN_RE = /^\s*#{START}\s+((?:[:\w_][-\.\w_]*:)?[-!\*\.\w_]*)(.*?)>/
			#\s*((((["']).*?\5)|[^\/'">]*)*?)(\/)?>/um, true)

			def initialize match
				@name = match[1]
				@rest = match[2]
			end
		end
	end
end
PK     Y\kZ*      rexml/dtd/entitydecl.rbnu [        require "rexml/child"
module REXML
	module DTD
		class EntityDecl < Child
			START = "<!ENTITY"
			START_RE = /^\s*#{START}/um
			PUBLIC = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+PUBLIC\s+((["']).*?\3)\s+((["']).*?\5)\s*>/um
			SYSTEM = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+SYSTEM\s+((["']).*?\3)(?:\s+NDATA\s+\w+)?\s*>/um
			PLAIN = /^\s*#{START}\s+(\w+)\s+((["']).*?\3)\s*>/um
			PERCENT = /^\s*#{START}\s+%\s+(\w+)\s+((["']).*?\3)\s*>/um
			# <!ENTITY name SYSTEM "...">
			# <!ENTITY name "...">
			def initialize src
				super()
				md = nil
				if src.match( PUBLIC )
					md = src.match( PUBLIC, true )
					@middle = "PUBLIC"
					@content = "#{md[2]} #{md[4]}"
				elsif src.match( SYSTEM )
					md = src.match( SYSTEM, true )
					@middle = "SYSTEM"
					@content = md[2]
				elsif src.match( PLAIN )
					md = src.match( PLAIN, true )
					@middle = ""
					@content = md[2]
				elsif src.match( PERCENT )
					md = src.match( PERCENT, true )
					@middle = ""
					@content = md[2]
				end
				raise ParseException.new("failed Entity match", src) if md.nil?
				@name = md[1]
			end

			def to_s
				rv = "<!ENTITY #@name "
				rv << "#@middle " if @middle.size > 0
				rv << @content
				rv
			end

			def write( output, indent )
        indent( output, indent )
				output << to_s
			end

			def EntityDecl.parse_source source, listener
				md = source.match( PATTERN_RE, true )
				thing = md[0].squeeze(" \t\n\r")
				listener.send inspect.downcase, thing 
			end
		end
	end
end
PK     Y\ oa      rexml/dtd/notationdecl.rbnu [        require "rexml/child"
module REXML
	module DTD
		class NotationDecl < Child
			START = "<!NOTATION"
			START_RE = /^\s*#{START}/um
			PUBLIC = /^\s*#{START}\s+(\w[\w-]*)\s+(PUBLIC)\s+((["']).*?\4)\s*>/um
			SYSTEM = /^\s*#{START}\s+(\w[\w-]*)\s+(SYSTEM)\s+((["']).*?\4)\s*>/um
			def initialize src
				super()
				if src.match( PUBLIC )
					md = src.match( PUBLIC, true )
				elsif src.match( SYSTEM )
					md = src.match( SYSTEM, true )
				else
					raise ParseException.new( "error parsing notation: no matching pattern", src )
				end
				@name = md[1]
				@middle = md[2]
				@rest = md[3]
			end

			def to_s
				"<!NOTATION #@name #@middle #@rest>"
			end

			def write( output, indent )
        indent( output, indent )
				output << to_s
			end

			def NotationDecl.parse_source source, listener
				md = source.match( PATTERN_RE, true )
				thing = md[0].squeeze(" \t\n\r")
				listener.send inspect.downcase, thing 
			end
		end
	end
end
PK     Y\$돇      rexml/light/node.rbnu [        require 'rexml/xmltokens'
require 'rexml/light/node'

# [ :element, parent, name, attributes, children* ]
	# a = Node.new
	# a << "B"		# => <a>B</a>
	# a.b			# => <a>B<b/></a>
	# a.b[1]			# => <a>B<b/><b/><a>
	# a.b[1]["x"] = "y"	# => <a>B<b/><b x="y"/></a>
	# a.b[0].c		# => <a>B<b><c/></b><b x="y"/></a>
	# a.b.c << "D"		# => <a>B<b><c>D</c></b><b x="y"/></a>
module REXML
	module Light
		# Represents a tagged XML element.  Elements are characterized by
		# having children, attributes, and names, and can themselves be
		# children.
		class Node
			NAMESPLIT = /^(?:(#{XMLTokens::NCNAME_STR}):)?(#{XMLTokens::NCNAME_STR})/u
			PARENTS = [ :element, :document, :doctype ]
			# Create a new element.
			def initialize node=nil
				@node = node
				if node.kind_of? String
					node = [ :text, node ]
				elsif node.nil?
					node = [ :document, nil, nil ]
				elsif node[0] == :start_element
					node[0] = :element
				elsif node[0] == :start_doctype
					node[0] = :doctype
				elsif node[0] == :start_document
					node[0] = :document
				end
			end

			def size
				if PARENTS.include? @node[0]
					@node[-1].size
				else
					0
				end
			end

			def each( &block )
				size.times { |x| yield( at(x+4) ) }
			end

			def name
				at(2)
			end

			def name=( name_str, ns=nil )
				pfx = ''
				pfx = "#{prefix(ns)}:" if ns
				_old_put(2, "#{pfx}#{name_str}")
			end

			def parent=( node )
				_old_put(1,node)
			end

			def local_name
				namesplit
				@name
			end

			def local_name=( name_str )
				_old_put( 1, "#@prefix:#{name_str}" )
			end

			def prefix( namespace=nil )
				prefix_of( self, namespace )
			end

			def namespace( prefix=prefix() )
				namespace_of( self, prefix )
			end

			def namespace=( namespace )
				@prefix = prefix( namespace )
				pfx = ''
				pfx = "#@prefix:" if @prefix.size > 0
				_old_put(1, "#{pfx}#@name")
			end

			def []( reference, ns=nil )
				if reference.kind_of? String
					pfx = ''
					pfx = "#{prefix(ns)}:" if ns
					at(3)["#{pfx}#{reference}"]
				elsif reference.kind_of? Range
					_old_get( Range.new(4+reference.begin, reference.end, reference.exclude_end?) )
				else
					_old_get( 4+reference )
				end
			end

			def =~( path )
				XPath.match( self, path )
			end

			# Doesn't handle namespaces yet
			def []=( reference, ns, value=nil )
				if reference.kind_of? String
					value = ns unless value
					at( 3 )[reference] = value
				elsif reference.kind_of? Range
					_old_put( Range.new(3+reference.begin, reference.end, reference.exclude_end?), ns )
				else
					if value
						_old_put( 4+reference, ns, value )
					else
						_old_put( 4+reference, ns )
					end
				end
			end

			# Append a child to this element, optionally under a provided namespace.
			# The namespace argument is ignored if the element argument is an Element
			# object.  Otherwise, the element argument is a string, the namespace (if
			# provided) is the namespace the element is created in.
			def << element
				if node_type() == :text
					at(-1) << element
				else
					newnode = Node.new( element )
					newnode.parent = self
					self.push( newnode )
				end
				at(-1)
			end

			def node_type
				_old_get(0)
			end

			def text=( foo )
				replace = at(4).kind_of?(String)? 1 : 0
				self._old_put(4,replace, normalizefoo)
			end

			def root
				context = self
				context = context.at(1) while context.at(1)
			end

			def has_name?( name, namespace = '' )
				at(3) == name and namespace() == namespace
			end

			def children
				self
			end

			def parent
				at(1)
			end

			def to_s

			end

			private

			def namesplit
				return if @name.defined?
				at(2) =~ NAMESPLIT
				@prefix = '' || $1
				@name = $2
			end

			def namespace_of( node, prefix=nil )
				if not prefix
					name = at(2)
					name =~ NAMESPLIT
					prefix = $1
				end
				to_find = 'xmlns'
				to_find = "xmlns:#{prefix}" if not prefix.nil?
				ns = at(3)[ to_find ]
				ns ? ns : namespace_of( @node[0], prefix )
			end

			def prefix_of( node, namespace=nil )
				if not namespace
					name = node.name
					name =~ NAMESPLIT
					$1
				else
					ns = at(3).find { |k,v| v == namespace }
					ns ? ns : prefix_of( node.parent, namespace )
				end
			end
		end
	end
end
PK     Y\"2+  2+    rexml/functions.rbnu [        module REXML
  # If you add a method, keep in mind two things:
  # (1) the first argument will always be a list of nodes from which to
  # filter.  In the case of context methods (such as position), the function
  # should return an array with a value for each child in the array.
  # (2) all method calls from XML will have "-" replaced with "_".
  # Therefore, in XML, "local-name()" is identical (and actually becomes)
  # "local_name()"
  module Functions
    @@context = nil
    @@namespace_context = {}
    @@variables = {}

    def Functions::namespace_context=(x) ; @@namespace_context=x ; end
    def Functions::variables=(x) ; @@variables=x ; end
    def Functions::namespace_context ; @@namespace_context ; end
    def Functions::variables ; @@variables ; end

    def Functions::context=(value); @@context = value; end

    def Functions::text( )
      if @@context[:node].node_type == :element
        return @@context[:node].find_all{|n| n.node_type == :text}.collect{|n| n.value}
      elsif @@context[:node].node_type == :text
        return @@context[:node].value
      else
        return false
      end
    end

    def Functions::last( )
      @@context[:size]
    end

    def Functions::position( )
      @@context[:index]
    end

    def Functions::count( node_set )
      node_set.size
    end

    # Since REXML is non-validating, this method is not implemented as it
    # requires a DTD
    def Functions::id( object )
    end

    # UNTESTED
    def Functions::local_name( node_set=nil )
      get_namespace( node_set ) do |node|
        return node.local_name 
      end
    end

    def Functions::namespace_uri( node_set=nil )
      get_namespace( node_set ) {|node| node.namespace}
    end

    def Functions::name( node_set=nil )
      get_namespace( node_set ) do |node| 
        node.expanded_name
      end
    end

    # Helper method.
    def Functions::get_namespace( node_set = nil )
      if node_set == nil
        yield @@context[:node] if defined? @@context[:node].namespace
      else  
        if node_set.respond_to? :each
          node_set.each { |node| yield node if defined? node.namespace }
        elsif node_set.respond_to? :namespace
          yield node_set
        end
      end
    end

    # A node-set is converted to a string by returning the string-value of the
    # node in the node-set that is first in document order. If the node-set is
    # empty, an empty string is returned.
    #
    # A number is converted to a string as follows
    #
    # NaN is converted to the string NaN 
    #
    # positive zero is converted to the string 0 
    #
    # negative zero is converted to the string 0 
    #
    # positive infinity is converted to the string Infinity 
    #
    # negative infinity is converted to the string -Infinity 
    #
    # if the number is an integer, the number is represented in decimal form
    # as a Number with no decimal point and no leading zeros, preceded by a
    # minus sign (-) if the number is negative
    #
    # otherwise, the number is represented in decimal form as a Number
    # including a decimal point with at least one digit before the decimal
    # point and at least one digit after the decimal point, preceded by a
    # minus sign (-) if the number is negative; there must be no leading zeros
    # before the decimal point apart possibly from the one required digit
    # immediately before the decimal point; beyond the one required digit
    # after the decimal point there must be as many, but only as many, more
    # digits as are needed to uniquely distinguish the number from all other
    # IEEE 754 numeric values.
    #
    # The boolean false value is converted to the string false. The boolean
    # true value is converted to the string true.
    #
    # An object of a type other than the four basic types is converted to a
    # string in a way that is dependent on that type.
    def Functions::string( object=nil )
      #object = @context unless object
      if object.instance_of? Array
        string( object[0] )
      elsif defined? object.node_type
        if object.node_type == :attribute
          object.value
        elsif object.node_type == :element || object.node_type == :document
          string_value(object)
        else
          object.to_s
        end
      elsif object.nil?
        return ""
      else
        object.to_s
      end
    end

    def Functions::string_value( o )
      rv = ""
      o.children.each { |e|
        if e.node_type == :text
          rv << e.to_s
        elsif e.node_type == :element
          rv << string_value( e )
        end
      }
      rv
    end

    # UNTESTED
    def Functions::concat( *objects )
      objects.join
    end

    # Fixed by Mike Stok
    def Functions::starts_with( string, test )
      string(string).index(string(test)) == 0
    end

    # Fixed by Mike Stok
    def Functions::contains( string, test )
      string(string).include?(string(test))
    end

    # Kouhei fixed this 
    def Functions::substring_before( string, test )
      ruby_string = string(string)
      ruby_index = ruby_string.index(string(test))
      if ruby_index.nil?
        ""
      else
        ruby_string[ 0...ruby_index ]
      end
    end
 
    # Kouhei fixed this too
    def Functions::substring_after( string, test )
      ruby_string = string(string)
      test_string = string(test)
      return $1 if ruby_string =~ /#{test}(.*)/
      ""
    end

    # Take equal portions of Mike Stok and Sean Russell; mix 
    # vigorously, and pour into a tall, chilled glass.  Serves 10,000.
    def Functions::substring( string, start, length=nil )
      ruby_string = string(string)
      ruby_length = if length.nil? 
                      ruby_string.length.to_f
                    else
                      number(length)
                    end
      ruby_start = number(start)

      # Handle the special cases
      return '' if (
        ruby_length.nan? or 
        ruby_start.nan? or
        ruby_start.infinite?
      )

      infinite_length = ruby_length.infinite? == 1
      ruby_length = ruby_string.length if infinite_length
        
      # Now, get the bounds.  The XPath bounds are 1..length; the ruby bounds 
      # are 0..length.  Therefore, we have to offset the bounds by one.
      ruby_start = ruby_start.round - 1
      ruby_length = ruby_length.round

      if ruby_start < 0
       ruby_length += ruby_start unless infinite_length
       ruby_start = 0
      end
      return '' if ruby_length <= 0
      ruby_string[ruby_start,ruby_length]
    end

    # UNTESTED
    def Functions::string_length( string )
      string(string).length
    end

    # UNTESTED
    def Functions::normalize_space( string=nil )
      string = string(@@context[:node]) if string.nil?
      if string.kind_of? Array
        string.collect{|x| string.to_s.strip.gsub(/\s+/um, ' ') if string}
      else
        string.to_s.strip.gsub(/\s+/um, ' ')
      end
    end

    # This is entirely Mike Stok's beast
    def Functions::translate( string, tr1, tr2 )
      from = string(tr1)
      to = string(tr2)

      # the map is our translation table.
      #
      # if a character occurs more than once in the
      # from string then we ignore the second &
      # subsequent mappings
      #
      # if a character maps to nil then we delete it
      # in the output.  This happens if the from
      # string is longer than the to string
      #
      # there's nothing about - or ^ being special in
      # http://www.w3.org/TR/xpath#function-translate
      # so we don't build ranges or negated classes

      map = Hash.new
      0.upto(from.length - 1) { |pos|
        from_char = from[pos]
        unless map.has_key? from_char
          map[from_char] = 
          if pos < to.length
            to[pos]
          else
            nil
          end
        end
      }

      string(string).unpack('U*').collect { |c|
        if map.has_key? c then map[c] else c end
      }.compact.pack('U*')
    end

    # UNTESTED
    def Functions::boolean( object=nil )
      if object.kind_of? String
        if object =~ /\d+/u
          return object.to_f != 0
        else
          return object.size > 0
        end
      elsif object.kind_of? Array
        object = object.find{|x| x and true}
      end
      return object ? true : false
    end

    # UNTESTED
    def Functions::not( object )
      not boolean( object )
    end

    # UNTESTED
    def Functions::true( )
      true
    end

    # UNTESTED
    def Functions::false(  )
      false
    end

    # UNTESTED
    def Functions::lang( language )
      lang = false
      node = @@context[:node]
      attr = nil
      until node.nil?
        if node.node_type == :element
          attr = node.attributes["xml:lang"]
          unless attr.nil?
            lang = compare_language(string(language), attr)
            break
          else
          end
        end
        node = node.parent
      end
      lang
    end

    def Functions::compare_language lang1, lang2
      lang2.downcase.index(lang1.downcase) == 0
    end

    # a string that consists of optional whitespace followed by an optional
    # minus sign followed by a Number followed by whitespace is converted to
    # the IEEE 754 number that is nearest (according to the IEEE 754
    # round-to-nearest rule) to the mathematical value represented by the
    # string; any other string is converted to NaN
    #
    # boolean true is converted to 1; boolean false is converted to 0
    #
    # a node-set is first converted to a string as if by a call to the string
    # function and then converted in the same way as a string argument
    #
    # an object of a type other than the four basic types is converted to a
    # number in a way that is dependent on that type
    def Functions::number( object=nil )
      object = @@context[:node] unless object
      case object
      when true
        Float(1)
      when false
        Float(0)
      when Array
        number(string( object ))
      when Numeric
        object.to_f
      else
        str = string( object )
        # If XPath ever gets scientific notation...
        #if str =~ /^\s*-?(\d*\.?\d+|\d+\.)([Ee]\d*)?\s*$/
        if str =~ /^\s*-?(\d*\.?\d+|\d+\.)\s*$/
          str.to_f
        else
          (0.0 / 0.0)
        end
      end
    end

    def Functions::sum( nodes )
      nodes = [nodes] unless nodes.kind_of? Array
      nodes.inject(0) { |r,n| r += number(string(n)) }
    end
    
    def Functions::floor( number )
      number(number).floor
    end

    def Functions::ceiling( number )
      number(number).ceil
    end

    def Functions::round( number )
      begin
        number(number).round
      rescue FloatDomainError
        number(number)
      end
    end

    def Functions::processing_instruction( node )
      node.node_type == :processing_instruction
    end

    def Functions::method_missing( id )
      puts "METHOD MISSING #{id.id2name}"
      XPath.match( @@context[:node], id.id2name )
    end
  end
end
PK     Y\W
  
    rexml/formatters/default.rbnu [        module REXML
  module Formatters
    class Default
      # Prints out the XML document with no formatting -- except if id_hack is
      # set.
      #
      # ie_hack::
      #   If set to true, then inserts whitespace before the close of an empty
      #   tag, so that IE's bad XML parser doesn't choke.
      def initialize( ie_hack=false )
        @ie_hack = ie_hack
      end

      # Writes the node to some output.
      #
      # node::
      #   The node to write
      # output::
      #   A class implementing <TT>&lt;&lt;</TT>.  Pass in an Output object to
      #   change the output encoding.
      def write( node, output )
        case node

        when Document 
          if node.xml_decl.encoding != "UTF-8" && !output.kind_of?(Output)
            output = Output.new( output, node.xml_decl.encoding )
          end
          write_document( node, output )

        when Element
          write_element( node, output )

        when Declaration, ElementDecl, NotationDecl, ExternalEntity, Entity,
             Attribute, AttlistDecl
          node.write( output,-1 )

        when Instruction
          write_instruction( node, output )

        when DocType, XMLDecl
          node.write( output )

        when Comment
          write_comment( node, output )

        when CData
          write_cdata( node, output )

        when Text
          write_text( node, output )

        else
          raise Exception.new("XML FORMATTING ERROR")

        end
      end

      protected
      def write_document( node, output )
        node.children.each { |child| write( child, output ) }
      end

      def write_element( node, output )
        output << "<#{node.expanded_name}"

        node.attributes.each_attribute do |attr|
          output << " "
          attr.write( output )
        end unless node.attributes.empty?

        if node.children.empty?
          output << " " if @ie_hack
          output << "/" 
        else
          output << ">"
          node.children.each { |child|
            write( child, output )
          }
          output << "</#{node.expanded_name}"
        end
        output << ">"
      end

      def write_text( node, output )
        output << node.to_s()
      end

      def write_comment( node, output )
        output << Comment::START
        output << node.to_s
        output << Comment::STOP
      end

      def write_cdata( node, output )
        output << CData::START
        output << node.to_s
        output << CData::STOP
      end

      def write_instruction( node, output )
        output << Instruction::START.sub(/\\/u, '')
        output << node.target
        output << ' '
        output << node.content
        output << Instruction::STOP.sub(/\\/u, '')
      end
    end
  end
end
PK     Y\˂o-      rexml/formatters/transitive.rbnu [        require 'rexml/formatters/pretty'

module REXML
  module Formatters
    # The Transitive formatter writes an XML document that parses to an
    # identical document as the source document.  This means that no extra
    # whitespace nodes are inserted, and whitespace within text nodes is
    # preserved.  Within these constraints, the document is pretty-printed,
    # with whitespace inserted into the metadata to introduce formatting.
    #
    # Note that this is only useful if the original XML is not already
    # formatted.  Since this formatter does not alter whitespace nodes, the
    # results of formatting already formatted XML will be odd.
    class Transitive < Default
      def initialize( indentation=2 )
        @indentation = indentation
        @level = 0
      end

      protected
      def write_element( node, output )
        output << "<#{node.expanded_name}"

        node.attributes.each_attribute do |attr|
          output << " "
          attr.write( output )
        end unless node.attributes.empty?

        output << "\n"
        output << ' '*@level
        if node.children.empty?
          output << "/" 
        else
          output << ">"
          # If compact and all children are text, and if the formatted output
          # is less than the specified width, then try to print everything on
          # one line
          skip = false
          @level += @indentation
          node.children.each { |child|
            write( child, output )
          }
          @level -= @indentation
          output << "</#{node.expanded_name}"
          output << "\n"
          output << ' '*@level
        end
        output << ">"
      end

      def write_text( node, output )
        output << node.to_s()
      end
    end
  end
end
PK     Y\	S_  _    rexml/formatters/pretty.rbnu [        require 'rexml/formatters/default'

module REXML
  module Formatters
    # Pretty-prints an XML document.  This destroys whitespace in text nodes
    # and will insert carriage returns and indentations.
    #
    # TODO: Add an option to print attributes on new lines
    class Pretty < Default

      # If compact is set to true, then the formatter will attempt to use as
      # little space as possible
      attr_accessor :compact
      # The width of a page.  Used for formatting text
      attr_accessor :width

      # Create a new pretty printer.
      #
      # output::
      #   An object implementing '<<(String)', to which the output will be written.
      # indentation::
      #   An integer greater than 0.  The indentation of each level will be
      #   this number of spaces.  If this is < 1, the behavior of this object
      #   is undefined.  Defaults to 2.
      # ie_hack::
      #   If true, the printer will insert whitespace before closing empty
      #   tags, thereby allowing Internet Explorer's feeble XML parser to
      #   function. Defaults to false.
      def initialize( indentation=2, ie_hack=false )
        @indentation = indentation
        @level = 0
        @ie_hack = ie_hack
        @width = 80
      end

      protected
      def write_element(node, output)
        output << ' '*@level
        output << "<#{node.expanded_name}"

        node.attributes.each_attribute do |attr|
          output << " "
          attr.write( output )
        end unless node.attributes.empty?

        if node.children.empty?
          if @ie_hack
            output << " "
          end
          output << "/" 
        else
          output << ">"
          # If compact and all children are text, and if the formatted output
          # is less than the specified width, then try to print everything on
          # one line
          skip = false
          if compact
            if node.children.inject(true) {|s,c| s & c.kind_of?(Text)}
              string = ""
              old_level = @level
              @level = 0
              node.children.each { |child| write( child, string ) }
              @level = old_level
              if string.length < @width
                output << string
                skip = true
              end
            end
          end
          unless skip
            output << "\n"
            @level += @indentation
            node.children.each { |child|
              next if child.kind_of?(Text) and child.to_s.strip.length == 0
              write( child, output )
              output << "\n"
            }
            @level -= @indentation
            output << ' '*@level
          end
          output << "</#{node.expanded_name}"
        end
        output << ">"
      end

      def write_text( node, output )
        s = node.to_s()
        s.gsub!(/\s/,' ')
        s.squeeze!(" ")
        s = wrap(s, 80-@level)
        s = indent_text(s, @level, " ", true)
        output << (' '*@level + s)
      end

      def write_comment( node, output)
        output << ' ' * @level
        super
      end

      def write_cdata( node, output)
        output << ' ' * @level
        super
      end

      def write_document( node, output )
        # Ok, this is a bit odd.  All XML documents have an XML declaration,
        # but it may not write itself if the user didn't specifically add it,
        # either through the API or in the input document.  If it doesn't write
        # itself, then we don't need a carriage return... which makes this
        # logic more complex.
        node.children.each { |child|
          next if child == node.children[-1] and child.instance_of?(Text)
          unless child == node.children[0] or child.instance_of?(Text) or
            (child == node.children[1] and !node.children[0].writethis)
            output << "\n"
          end
          write( child, output )
        }
      end

      private
      def indent_text(string, level=1, style="\t", indentfirstline=true)
        return string if level < 0
        string.gsub(/\n/, "\n#{style*level}")
      end

      def wrap(string, width)
        # Recursively wrap string at width.
        return string if string.length <= width
        place = string.rindex(' ', width) # Position in string with last ' ' before cutoff
        return string if place.nil?
        return string[0,place] + "\n" + wrap(string[place+1..-1], width)
      end

    end
  end
end

PK     Y\9  9    rexml/source.rbnu [        require 'rexml/encoding'

module REXML
  # Generates Source-s.  USE THIS CLASS.
  class SourceFactory
    # Generates a Source object
    # @param arg Either a String, or an IO
    # @return a Source, or nil if a bad argument was given
    def SourceFactory::create_from(arg)
      if arg.kind_of? String
        Source.new(arg)
      elsif arg.respond_to? :read and
            arg.respond_to? :readline and
            arg.respond_to? :nil? and
            arg.respond_to? :eof?
        IOSource.new(arg)
      elsif arg.kind_of? Source
        arg
      else
        raise "#{arg.class} is not a valid input stream.  It must walk \n"+
          "like either a String, an IO, or a Source."
      end
    end
  end

  # A Source can be searched for patterns, and wraps buffers and other
  # objects and provides consumption of text
  class Source
    include Encoding
    # The current buffer (what we're going to read next)
    attr_reader :buffer
    # The line number of the last consumed text
    attr_reader :line
    attr_reader :encoding

    # Constructor
    # @param arg must be a String, and should be a valid XML document
    # @param encoding if non-null, sets the encoding of the source to this
    # value, overriding all encoding detection
    def initialize(arg, encoding=nil)
      @orig = @buffer = arg
      if encoding
        self.encoding = encoding
      else
        self.encoding = check_encoding( @buffer )
      end
      @line = 0
    end


    # Inherited from Encoding
    # Overridden to support optimized en/decoding
    def encoding=(enc)
      return unless super
      @line_break = encode( '>' )
      if enc != UTF_8
        @buffer = decode(@buffer)
        @to_utf = true
      else
        @to_utf = false
      end
    end

    # Scans the source for a given pattern.  Note, that this is not your
    # usual scan() method.  For one thing, the pattern argument has some
    # requirements; for another, the source can be consumed.  You can easily
    # confuse this method.  Originally, the patterns were easier
    # to construct and this method more robust, because this method 
    # generated search regexes on the fly; however, this was 
    # computationally expensive and slowed down the entire REXML package 
    # considerably, since this is by far the most commonly called method.
    # @param pattern must be a Regexp, and must be in the form of
    # /^\s*(#{your pattern, with no groups})(.*)/.  The first group
    # will be returned; the second group is used if the consume flag is
    # set.
    # @param consume if true, the pattern returned will be consumed, leaving
    # everything after it in the Source.
    # @return the pattern, if found, or nil if the Source is empty or the
    # pattern is not found.
    def scan(pattern, cons=false)
      return nil if @buffer.nil?
      rv = @buffer.scan(pattern)
      @buffer = $' if cons and rv.size>0
      rv
    end

    def read
    end

    def consume( pattern )
      @buffer = $' if pattern.match( @buffer )
    end

    def match_to( char, pattern )
      return pattern.match(@buffer)
    end

    def match_to_consume( char, pattern )
      md = pattern.match(@buffer)
      @buffer = $'
      return md
    end

    def match(pattern, cons=false)
      md = pattern.match(@buffer)
      @buffer = $' if cons and md
      return md
    end

    # @return true if the Source is exhausted
    def empty?
      @buffer == ""
    end

    def position
      @orig.index( @buffer )
    end

    # @return the current line in the source
    def current_line
      lines = @orig.split
      res = lines.grep @buffer[0..30]
      res = res[-1] if res.kind_of? Array
      lines.index( res ) if res
    end
  end

  # A Source that wraps an IO.  See the Source class for method
  # documentation
  class IOSource < Source
    #attr_reader :block_size

    # block_size has been deprecated
    def initialize(arg, block_size=500, encoding=nil)
      @er_source = @source = arg
      @to_utf = false

      # Determining the encoding is a deceptively difficult issue to resolve.
      # First, we check the first two bytes for UTF-16.  Then we
      # assume that the encoding is at least ASCII enough for the '>', and
      # we read until we get one of those.  This gives us the XML declaration,
      # if there is one.  If there isn't one, the file MUST be UTF-8, as per
      # the XML spec.  If there is one, we can determine the encoding from
      # it.
      @buffer = ""
      str = @source.read( 2 )
      if encoding
        self.encoding = encoding
      elsif 0xfe == str[0] && 0xff == str[1]
        @line_break = "\000>"
      elsif 0xff == str[0] && 0xfe == str[1]
        @line_break = ">\000"
      elsif 0xef == str[0] && 0xbb == str[1]
        str += @source.read(1)
        str = '' if (0xbf == str[2])
        @line_break = ">"
      else
        @line_break = ">"
      end
      super str+@source.readline( @line_break )
    end

    def scan(pattern, cons=false)
      rv = super
      # You'll notice that this next section is very similar to the same
      # section in match(), but just a liiittle different.  This is
      # because it is a touch faster to do it this way with scan()
      # than the way match() does it; enough faster to warrent duplicating
      # some code
      if rv.size == 0
        until @buffer =~ pattern or @source.nil?
          begin
            # READLINE OPT
            #str = @source.read(@block_size)
            str = @source.readline(@line_break)
            str = decode(str) if @to_utf and str
            @buffer << str
          rescue Iconv::IllegalSequence
            raise
          rescue
            @source = nil
          end
        end
        rv = super
      end
      rv.taint
      rv
    end

    def read
      begin
        str = @source.readline(@line_break)
        str = decode(str) if @to_utf and str 
        @buffer << str
      rescue Exception, NameError
        @source = nil
      end
    end

    def consume( pattern )
      match( pattern, true )
    end

    def match( pattern, cons=false )
      rv = pattern.match(@buffer)
      @buffer = $' if cons and rv
      while !rv and @source
        begin
          str = @source.readline(@line_break)
          str = decode(str) if @to_utf and str
          @buffer << str
          rv = pattern.match(@buffer)
          @buffer = $' if cons and rv
        rescue
          @source = nil
        end
      end
      rv.taint
      rv
    end
    
    def empty?
      super and ( @source.nil? || @source.eof? )
    end

    def position
      @er_source.stat.pipe? ? 0 : @er_source.pos
    end

    # @return the current line in the source
    def current_line
      begin
        pos = @er_source.pos        # The byte position in the source
        lineno = @er_source.lineno  # The XML < position in the source
        @er_source.rewind
        line = 0                    # The \r\n position in the source
        begin
          while @er_source.pos < pos
            @er_source.readline
            line += 1
          end
        rescue
        end
      rescue IOError
        pos = -1
        line = -1
      end
      [pos, lineno, line]
    end
  end
end
PK     Y\\
bI,  ,    rexml/text.rbnu [        require 'rexml/rexml'
require 'rexml/entity'
require 'rexml/doctype'
require 'rexml/child'
require 'rexml/doctype'
require 'rexml/parseexception'

module REXML
  # Represents text nodes in an XML document
  class Text < Child
    include Comparable
    # The order in which the substitutions occur
    SPECIALS = [ /&(?!#?[\w-]+;)/u, /</u, />/u, /"/u, /'/u, /\r/u ]
    SUBSTITUTES = ['&amp;', '&lt;', '&gt;', '&quot;', '&apos;', '&#13;']
    # Characters which are substituted in written strings
    SLAICEPS = [ '<', '>', '"', "'", '&' ]
    SETUTITSBUS = [ /&lt;/u, /&gt;/u, /&quot;/u, /&apos;/u, /&amp;/u ]

    # If +raw+ is true, then REXML leaves the value alone
    attr_accessor :raw

    ILLEGAL = /(<|&(?!(#{Entity::NAME})|(#0*((?:\d+)|(?:x[a-fA-F0-9]+)));))/um
    NUMERICENTITY = /&#0*((?:\d+)|(?:x[a-fA-F0-9]+));/ 

    # Constructor
    # +arg+ if a String, the content is set to the String.  If a Text,
    # the object is shallowly cloned.  
    #
    # +respect_whitespace+ (boolean, false) if true, whitespace is
    # respected
    #
    # +parent+ (nil) if this is a Parent object, the parent
    # will be set to this.  
    #
    # +raw+ (nil) This argument can be given three values.
    # If true, then the value of used to construct this object is expected to 
    # contain no unescaped XML markup, and REXML will not change the text. If 
    # this value is false, the string may contain any characters, and REXML will
    # escape any and all defined entities whose values are contained in the
    # text.  If this value is nil (the default), then the raw value of the 
    # parent will be used as the raw value for this node.  If there is no raw
    # value for the parent, and no value is supplied, the default is false.
    # Use this field if you have entities defined for some text, and you don't
    # want REXML to escape that text in output.
    #   Text.new( "<&", false, nil, false ) #-> "&lt;&amp;"
    #   Text.new( "&lt;&amp;", false, nil, false ) #-> "&amp;lt;&amp;amp;"
    #   Text.new( "<&", false, nil, true )  #-> Parse exception
    #   Text.new( "&lt;&amp;", false, nil, true )  #-> "&lt;&amp;"
    #   # Assume that the entity "s" is defined to be "sean"
    #   # and that the entity    "r" is defined to be "russell"
    #   Text.new( "sean russell" )          #-> "&s; &r;"
    #   Text.new( "sean russell", false, nil, true ) #-> "sean russell"
    #
    # +entity_filter+ (nil) This can be an array of entities to match in the
    # supplied text.  This argument is only useful if +raw+ is set to false.
    #   Text.new( "sean russell", false, nil, false, ["s"] ) #-> "&s; russell"
    #   Text.new( "sean russell", false, nil, true, ["s"] ) #-> "sean russell"
    # In the last example, the +entity_filter+ argument is ignored.
    #
    # +pattern+ INTERNAL USE ONLY
    def initialize(arg, respect_whitespace=false, parent=nil, raw=nil, 
      entity_filter=nil, illegal=ILLEGAL )

      @raw = false

      if parent
        super( parent )
        @raw = parent.raw 
      else
        @parent = nil
      end

      @raw = raw unless raw.nil?
      @entity_filter = entity_filter
      @normalized = @unnormalized = nil

      if arg.kind_of? String
        @string = arg.clone
        @string.squeeze!(" \n\t") unless respect_whitespace
      elsif arg.kind_of? Text
        @string = arg.to_s
        @raw = arg.raw
      elsif
        raise "Illegal argument of type #{arg.type} for Text constructor (#{arg})"
      end

      @string.gsub!( /\r\n?/, "\n" )

      # check for illegal characters
      if @raw
        if @string =~ illegal
          raise "Illegal character '#{$1}' in raw string \"#{@string}\""
        end
      end
    end

    def node_type
      :text
    end

    def empty?
      @string.size==0
    end


    def clone
      return Text.new(self)
    end


    # Appends text to this text node.  The text is appended in the +raw+ mode
    # of this text node.
    def <<( to_append )
      @string << to_append.gsub( /\r\n?/, "\n" )
    end


    # +other+ a String or a Text
    # +returns+ the result of (to_s <=> arg.to_s)
    def <=>( other )
      to_s() <=> other.to_s
    end

    REFERENCE = /#{Entity::REFERENCE}/
    # Returns the string value of this text node.  This string is always
    # escaped, meaning that it is a valid XML text node string, and all
    # entities that can be escaped, have been inserted.  This method respects
    # the entity filter set in the constructor.
    #   
    #   # Assume that the entity "s" is defined to be "sean", and that the 
    #   # entity "r" is defined to be "russell"
    #   t = Text.new( "< & sean russell", false, nil, false, ['s'] ) 
    #   t.to_s   #-> "&lt; &amp; &s; russell"
    #   t = Text.new( "< & &s; russell", false, nil, false ) 
    #   t.to_s   #-> "&lt; &amp; &s; russell"
    #   u = Text.new( "sean russell", false, nil, true )
    #   u.to_s   #-> "sean russell"
    def to_s
      return @string if @raw
      return @normalized if @normalized

      doctype = nil
      if @parent
        doc = @parent.document
        doctype = doc.doctype if doc
      end

      @normalized = Text::normalize( @string, doctype, @entity_filter )
    end

    def inspect
      @string.inspect
    end

    # Returns the string value of this text.  This is the text without
    # entities, as it might be used programmatically, or printed to the
    # console.  This ignores the 'raw' attribute setting, and any
    # entity_filter.
    #
    #   # Assume that the entity "s" is defined to be "sean", and that the 
    #   # entity "r" is defined to be "russell"
    #   t = Text.new( "< & sean russell", false, nil, false, ['s'] ) 
    #   t.value   #-> "< & sean russell"
    #   t = Text.new( "< & &s; russell", false, nil, false )
    #   t.value   #-> "< & sean russell"
    #   u = Text.new( "sean russell", false, nil, true )
    #   u.value   #-> "sean russell"
    def value
      @unnormalized if @unnormalized
      doctype = nil
      if @parent
        doc = @parent.document
        doctype = doc.doctype if doc
      end
      @unnormalized = Text::unnormalize( @string, doctype )
    end

    # Sets the contents of this text node.  This expects the text to be 
    # unnormalized.  It returns self.
    #
    #   e = Element.new( "a" )
    #   e.add_text( "foo" )   # <a>foo</a>
    #   e[0].value = "bar"    # <a>bar</a>
    #   e[0].value = "<a>"    # <a>&lt;a&gt;</a>
    def value=( val )
      @string = val.gsub( /\r\n?/, "\n" )
      @unnormalized = nil
      @normalized = nil
      @raw = false
    end
 
     def wrap(string, width, addnewline=false)
       # Recursively wrap string at width.
       return string if string.length <= width
       place = string.rindex(' ', width) # Position in string with last ' ' before cutoff
       if addnewline then
         return "\n" + string[0,place] + "\n" + wrap(string[place+1..-1], width)
       else
         return string[0,place] + "\n" + wrap(string[place+1..-1], width)
       end
     end

    def indent_text(string, level=1, style="\t", indentfirstline=true)
      return string if level < 0
      new_string = ''
      string.each { |line|
        indent_string = style * level
        new_line = (indent_string + line).sub(/[\s]+$/,'')
        new_string << new_line
      }
      new_string.strip! unless indentfirstline
      return new_string
    end
 
    # == DEPRECATED
    # See REXML::Formatters
    #
    def write( writer, indent=-1, transitive=false, ie_hack=false ) 
      Kernel.warn("#{self.class.name}.write is deprecated.  See REXML::Formatters")
      formatter = if indent > -1
          REXML::Formatters::Pretty.new( indent )
        else
          REXML::Formatters::Default.new
        end
      formatter.write( self, writer )
    end

    # FIXME
    # This probably won't work properly
    def xpath
      path = @parent.xpath
      path += "/text()"
      return path
    end

    # Writes out text, substituting special characters beforehand.
    # +out+ A String, IO, or any other object supporting <<( String )
    # +input+ the text to substitute and the write out
    #
    #   z=utf8.unpack("U*")
    #   ascOut=""
    #   z.each{|r|
    #     if r <  0x100
    #       ascOut.concat(r.chr)
    #     else
    #       ascOut.concat(sprintf("&#x%x;", r))
    #     end
    #   }
    #   puts ascOut
    def write_with_substitution out, input
      copy = input.clone
      # Doing it like this rather than in a loop improves the speed
      copy.gsub!( SPECIALS[0], SUBSTITUTES[0] )
      copy.gsub!( SPECIALS[1], SUBSTITUTES[1] )
      copy.gsub!( SPECIALS[2], SUBSTITUTES[2] )
      copy.gsub!( SPECIALS[3], SUBSTITUTES[3] )
      copy.gsub!( SPECIALS[4], SUBSTITUTES[4] )
      copy.gsub!( SPECIALS[5], SUBSTITUTES[5] )
      out << copy
    end

    # Reads text, substituting entities
    def Text::read_with_substitution( input, illegal=nil )
      copy = input.clone

      if copy =~ illegal
        raise ParseException.new( "malformed text: Illegal character #$& in \"#{copy}\"" )
      end if illegal
      
      copy.gsub!( /\r\n?/, "\n" )
      if copy.include? ?&
        copy.gsub!( SETUTITSBUS[0], SLAICEPS[0] )
        copy.gsub!( SETUTITSBUS[1], SLAICEPS[1] )
        copy.gsub!( SETUTITSBUS[2], SLAICEPS[2] )
        copy.gsub!( SETUTITSBUS[3], SLAICEPS[3] )
        copy.gsub!( SETUTITSBUS[4], SLAICEPS[4] )
        copy.gsub!( /&#0*((?:\d+)|(?:x[a-f0-9]+));/ ) {|m|
          m=$1
          #m='0' if m==''
          m = "0#{m}" if m[0] == ?x
          [Integer(m)].pack('U*')
        }
      end
      copy
    end

    EREFERENCE = /&(?!#{Entity::NAME};)/
    # Escapes all possible entities
    def Text::normalize( input, doctype=nil, entity_filter=nil )
      copy = input.to_s
      # Doing it like this rather than in a loop improves the speed
      #copy = copy.gsub( EREFERENCE, '&amp;' )
      copy = copy.gsub( "&", "&amp;" )
      if doctype
        # Replace all ampersands that aren't part of an entity
        doctype.entities.each_value do |entity|
          copy = copy.gsub( entity.value, 
            "&#{entity.name};" ) if entity.value and 
              not( entity_filter and entity_filter.include?(entity) )
        end
      else
        # Replace all ampersands that aren't part of an entity
        DocType::DEFAULT_ENTITIES.each_value do |entity|
          copy = copy.gsub(entity.value, "&#{entity.name};" )
        end
      end
      copy
    end

    # Unescapes all possible entities
    def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )
      sum = 0
      string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) {
        s = Text.expand($&, doctype, filter)
        if sum + s.bytesize > REXML.entity_expansion_text_limit
          raise "entity expansion has grown too large"
        else
          sum += s.bytesize
        end
        s
      }
    end

    def Text.expand(ref, doctype, filter)
      if ref[1] == ?#
        if ref[2] == ?x
          [ref[3...-1].to_i(16)].pack('U*')
        else
          [ref[2...-1].to_i].pack('U*')
        end
      elsif ref == '&amp;'
        '&'
      elsif filter and filter.include?( ref[1...-1] )
        ref
      elsif doctype
        doctype.entity( ref[1...-1] ) or ref
      else
        entity_value = DocType::DEFAULT_ENTITIES[ ref[1...-1] ]
        entity_value ? entity_value.value : ref
      end
    end
  end
end
PK     Y\a      rexml/namespace.rbnu [        require 'rexml/xmltokens'

module REXML
	# Adds named attributes to an object.
	module Namespace
		# The name of the object, valid if set
		attr_reader :name, :expanded_name
		# The expanded name of the object, valid if name is set
		attr_accessor :prefix
		include XMLTokens
		NAMESPLIT = /^(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})/u

		# Sets the name and the expanded name
		def name=( name )
			@expanded_name = name
			name =~ NAMESPLIT
			if $1
				@prefix = $1
			else
				@prefix = ""
				@namespace = ""
			end
			@name = $2
		end

		# Compares names optionally WITH namespaces
		def has_name?( other, ns=nil )
			if ns
				return (namespace() == ns and name() == other)
			elsif other.include? ":"
				return fully_expanded_name == other
			else
				return name == other
			end
		end

		alias :local_name :name

		# Fully expand the name, even if the prefix wasn't specified in the
		# source file.
		def fully_expanded_name
			ns = prefix
			return "#{ns}:#@name" if ns.size > 0 
			return @name
		end
	end
end
PK     Y\;ŝ      rexml/quickpath.rbnu [        require 'rexml/functions'
require 'rexml/xmltokens'

module REXML
	class QuickPath
		include Functions
		include XMLTokens

		EMPTY_HASH = {}

		def QuickPath::first element, path, namespaces=EMPTY_HASH
			match(element, path, namespaces)[0]
		end

		def QuickPath::each element, path, namespaces=EMPTY_HASH, &block
			path = "*" unless path
			match(element, path, namespaces).each( &block )
		end

		def QuickPath::match element, path, namespaces=EMPTY_HASH
			raise "nil is not a valid xpath" unless path
			results = nil
			Functions::namespace_context = namespaces
			case path
			when /^\/([^\/]|$)/u
				# match on root
				path = path[1..-1]
				return [element.root.parent] if path == ''
				results = filter([element.root], path)
			when /^[-\w]*::/u
				results = filter([element], path)
			when /^\*/u
				results = filter(element.to_a, path)
			when /^[\[!\w:]/u
				# match on child
				matches = []
				children = element.to_a
				results = filter(children, path)
			else
				results = filter([element], path)
			end
			return results
		end

		# Given an array of nodes it filters the array based on the path. The
		# result is that when this method returns, the array will contain elements
		# which match the path
		def QuickPath::filter elements, path
			return elements if path.nil? or path == '' or elements.size == 0
			case path
			when /^\/\//u											# Descendant
				return axe( elements, "descendant-or-self", $' )
			when /^\/?\b(\w[-\w]*)\b::/u							# Axe
				axe_name = $1
				rest = $'
				return axe( elements, $1, $' )
			when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/u	# Child
				rest = $'
				results = []
				elements.each do |element|
					results |= filter( element.to_a, rest )
				end
				return results
			when /^\/?(\w[-\w]*)\(/u							# / Function
				return function( elements, $1, $' )
			when Namespace::NAMESPLIT		# Element name
				name = $2
				ns = $1
				rest = $'
				elements.delete_if do |element|
					!(element.kind_of? Element and 
						(element.expanded_name == name or
						 (element.name == name and
						  element.namespace == Functions.namespace_context[ns])))
				end
				return filter( elements, rest )
			when /^\/\[/u
				matches = []
				elements.each do |element|
					matches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element
				end
				return matches
			when /^\[/u												# Predicate
				return predicate( elements, path )
			when /^\/?\.\.\./u										# Ancestor
				return axe( elements, "ancestor", $' )
			when /^\/?\.\./u											# Parent
				return filter( elements.collect{|e|e.parent}, $' )
			when /^\/?\./u												# Self
				return filter( elements, $' )
			when /^\*/u													# Any
				results = []
				elements.each do |element|
					results |= filter( [element], $' ) if element.kind_of? Element
					#if element.kind_of? Element
					#	children = element.to_a
					#	children.delete_if { |child| !child.kind_of?(Element) }
					#	results |= filter( children, $' )
					#end
				end
				return results
			end
			return []
		end

		def QuickPath::axe( elements, axe_name, rest )
			matches = []
			matches = filter( elements.dup, rest ) if axe_name =~ /-or-self$/u
			case axe_name
			when /^descendant/u
				elements.each do |element|
					matches |= filter( element.to_a, "descendant-or-self::#{rest}" ) if element.kind_of? Element
				end
			when /^ancestor/u
				elements.each do |element|
					while element.parent
						matches << element.parent
						element = element.parent
					end
				end
				matches = filter( matches, rest )
			when "self"
				matches = filter( elements, rest )
			when "child"
				elements.each do |element|
					matches |= filter( element.to_a, rest ) if element.kind_of? Element
				end
			when "attribute"
				elements.each do |element|
					matches << element.attributes[ rest ] if element.kind_of? Element
				end
			when "parent"
				matches = filter(elements.collect{|element| element.parent}.uniq, rest)
			when "following-sibling"
				matches = filter(elements.collect{|element| element.next_sibling}.uniq,
					rest)
			when "previous-sibling"
				matches = filter(elements.collect{|element| 
					element.previous_sibling}.uniq, rest )
			end
			return matches.uniq
		end

		# A predicate filters a node-set with respect to an axis to produce a
		# new node-set. For each node in the node-set to be filtered, the 
		# PredicateExpr is evaluated with that node as the context node, with 
		# the number of nodes in the node-set as the context size, and with the 
		# proximity position of the node in the node-set with respect to the
		# axis as the context position; if PredicateExpr evaluates to true for
		# that node, the node is included in the new node-set; otherwise, it is
		# not included.
		#
		# A PredicateExpr is evaluated by evaluating the Expr and converting
		# the result to a boolean. If the result is a number, the result will
		# be converted to true if the number is equal to the context position
		# and will be converted to false otherwise; if the result is not a
		# number, then the result will be converted as if by a call to the
		# boolean function. Thus a location path para[3] is equivalent to
		# para[position()=3].
		def QuickPath::predicate( elements, path ) 
			ind = 1
			bcount = 1
			while bcount > 0
				bcount += 1 if path[ind] == ?[
				bcount -= 1 if path[ind] == ?]
				ind += 1
			end
			ind -= 1
			predicate = path[1..ind-1]
			rest = path[ind+1..-1]

			# have to change 'a [=<>] b [=<>] c' into 'a [=<>] b and b [=<>] c'
			predicate.gsub!( /([^\s(and)(or)<>=]+)\s*([<>=])\s*([^\s(and)(or)<>=]+)\s*([<>=])\s*([^\s(and)(or)<>=]+)/u ) { 
				"#$1 #$2 #$3 and #$3 #$4 #$5"
			}
			# Let's do some Ruby trickery to avoid some work:
			predicate.gsub!( /&/u, "&&" )
			predicate.gsub!( /=/u, "==" )
			predicate.gsub!( /@(\w[-\w.]*)/u ) {
				"attribute(\"#$1\")" 
			}
			predicate.gsub!( /\bmod\b/u, "%" )
			predicate.gsub!( /\b(\w[-\w.]*\()/u ) {
				fname = $1
				fname.gsub( /-/u, "_" )
			}
			
			Functions.pair = [ 0, elements.size ]
			results = []
			elements.each do |element|
				Functions.pair[0] += 1
				Functions.node = element
				res = eval( predicate )
				case res
				when true
					results << element
				when Fixnum
					results << element if Functions.pair[0] == res
				when String
					results << element
				end
			end
			return filter( results, rest )
		end

		def QuickPath::attribute( name )
			return Functions.node.attributes[name] if Functions.node.kind_of? Element
		end

		def QuickPath::name()
			return Functions.node.name if Functions.node.kind_of? Element
		end

		def QuickPath::method_missing( id, *args )
			begin
				Functions.send( id.id2name, *args )
			rescue Exception
				raise "METHOD: #{id.id2name}(#{args.join ', '})\n#{$!.message}"
			end
		end

		def QuickPath::function( elements, fname, rest )
			args = parse_args( elements, rest )
			Functions.pair = [0, elements.size]
			results = []
			elements.each do |element|
				Functions.pair[0] += 1
				Functions.node = element
				res = Functions.send( fname, *args )
				case res
				when true
					results << element
				when Fixnum
					results << element if Functions.pair[0] == res
				end
			end
			return results
		end

		def QuickPath::parse_args( element, string )
			# /.*?(?:\)|,)/
			arguments = []
			buffer = ""
			while string and string != ""
				c = string[0]
				string.sub!(/^./u, "")
				case c
				when ?,
					# if depth = 1, then we start a new argument
					arguments << evaluate( buffer )
					#arguments << evaluate( string[0..count] )
				when ?(
					# start a new method call
					function( element, buffer, string )
					buffer = ""
				when ?)
					# close the method call and return arguments
					return arguments
				else
					buffer << c
				end
			end
			""
		end
	end
end
PK     Y\3%      rexml/xmltokens.rbnu [        module REXML
	# Defines a number of tokens used for parsing XML.  Not for general
	# consumption.
	module XMLTokens
		NCNAME_STR= '[\w:][\-\w\d.]*'
		NAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}"

		NAMECHAR = '[\-\w\d\.:]'
		NAME = "([\\w:]#{NAMECHAR}*)"
		NMTOKEN = "(?:#{NAMECHAR})+"
		NMTOKENS = "#{NMTOKEN}(\\s+#{NMTOKEN})*"
		REFERENCE = "(?:&#{NAME};|&#\\d+;|&#x[0-9a-fA-F]+;)"

		#REFERENCE = "(?:#{ENTITYREF}|#{CHARREF})"
		#ENTITYREF = "&#{NAME};"
		#CHARREF = "&#\\d+;|&#x[0-9a-fA-F]+;"
	end
end
PK     Y\(:2
  
    rexml/xmldecl.rbnu [        require 'rexml/encoding'
require 'rexml/source'

module REXML
	# NEEDS DOCUMENTATION
	class XMLDecl < Child
		include Encoding

		DEFAULT_VERSION = "1.0";
		DEFAULT_ENCODING = "UTF-8";
		DEFAULT_STANDALONE = "no";
		START = '<\?xml';
		STOP = '\?>';

		attr_accessor :version, :standalone
    attr_reader :writeencoding, :writethis

		def initialize(version=DEFAULT_VERSION, encoding=nil, standalone=nil)
      @writethis = true
      @writeencoding = !encoding.nil?
			if version.kind_of? XMLDecl
				super()
				@version = version.version
				self.encoding = version.encoding
        @writeencoding = version.writeencoding
				@standalone = version.standalone
			else
				super()
				@version = version
				self.encoding = encoding
				@standalone = standalone
			end
			@version = DEFAULT_VERSION if @version.nil?
		end

		def clone
			XMLDecl.new(self)
		end

    # indent::
    #   Ignored.  There must be no whitespace before an XML declaration
    # transitive::
    #   Ignored
    # ie_hack::
    #   Ignored
		def write(writer, indent=-1, transitive=false, ie_hack=false)
      return nil unless @writethis or writer.kind_of? Output
			writer << START.sub(/\\/u, '')
      if writer.kind_of? Output
        writer << " #{content writer.encoding}"
      else
        writer << " #{content encoding}"
      end
			writer << STOP.sub(/\\/u, '')
		end

		def ==( other )
		  other.kind_of?(XMLDecl) and
		  other.version == @version and
		  other.encoding == self.encoding and
		  other.standalone == @standalone
		end

		def xmldecl version, encoding, standalone
			@version = version
			self.encoding = encoding
			@standalone = standalone
		end

		def node_type
			:xmldecl
		end

		alias :stand_alone? :standalone
    alias :old_enc= :encoding=

    def encoding=( enc )
      if enc.nil?
        self.old_enc = "UTF-8"
        @writeencoding = false
      else
        self.old_enc = enc
        @writeencoding = true
      end
      self.dowrite
    end

    # Only use this if you do not want the XML declaration to be written;
    # this object is ignored by the XML writer.  Otherwise, instantiate your
    # own XMLDecl and add it to the document.
    #
    # Note that XML 1.1 documents *must* include an XML declaration
    def XMLDecl.default
      rv = XMLDecl.new( "1.0" )
      rv.nowrite
      rv
    end

    def nowrite
      @writethis = false
    end

    def dowrite
      @writethis = true
    end

    def inspect
      START.sub(/\\/u, '') + " ... " + STOP.sub(/\\/u, '')
    end

		private
		def content(enc)
			rv = "version='#@version'"
			rv << " encoding='#{enc}'" if @writeencoding || enc !~ /utf-8/i
			rv << " standalone='#@standalone'" if @standalone
			rv
		end
	end
end
PK     Y\L      rexml/rexml.rbnu [        # -*- encoding: utf-8 -*-
# REXML is an XML toolkit for Ruby[http://www.ruby-lang.org], in Ruby.
#
# REXML is a _pure_ Ruby, XML 1.0 conforming,
# non-validating[http://www.w3.org/TR/2004/REC-xml-20040204/#sec-conformance]
# toolkit with an intuitive API.  REXML passes 100% of the non-validating Oasis
# tests[http://www.oasis-open.org/committees/xml-conformance/xml-test-suite.shtml],
# and provides tree, stream, SAX2, pull, and lightweight APIs.  REXML also 
# includes a full XPath[http://www.w3c.org/tr/xpath] 1.0 implementation. Since 
# Ruby 1.8, REXML is included in the standard Ruby distribution.
#
# Main page:: http://www.germane-software.com/software/rexml
# Author:: Sean Russell <serATgermaneHYPHENsoftwareDOTcom>
# Version:: 3.1.7.2
# Date:: 2007/275
# Revision:: $Revision: 40812 $
# 
# This API documentation can be downloaded from the REXML home page, or can
# be accessed online[http://www.germane-software.com/software/rexml_doc]
#
# A tutorial is available in the REXML distribution in docs/tutorial.html,
# or can be accessed 
# online[http://www.germane-software.com/software/rexml/docs/tutorial.html]
module REXML
  COPYRIGHT = "Copyright \xC2\xA9 2001-2006 Sean Russell <ser@germane-software.com>"
  VERSION = "3.1.7.3"
  DATE = "2007/275"
  REVISION = "$Revision: 40812 $".gsub(/\$Revision:|\$/,'').strip

  Copyright = COPYRIGHT
  Version = VERSION

  @@entity_expansion_text_limit = 10_240

  # Set the entity expansion limit. By default the limit is set to 10240.
  def self.entity_expansion_text_limit=( val )
    @@entity_expansion_text_limit = val
  end

  # Get the entity expansion limit. By default the limit is set to 10240.
  def self.entity_expansion_text_limit
    return @@entity_expansion_text_limit
  end
end
PK     Y\4
a.  .    rexml/attlistdecl.rbnu [        #vim:ts=2 sw=2 noexpandtab:
require 'rexml/child'
require 'rexml/source'

module REXML
	# This class needs:
	# * Documentation
	# * Work!  Not all types of attlists are intelligently parsed, so we just
	# spew back out what we get in.  This works, but it would be better if
	# we formatted the output ourselves.
	#
	# AttlistDecls provide *just* enough support to allow namespace
	# declarations.  If you need some sort of generalized support, or have an
	# interesting idea about how to map the hideous, terrible design of DTD
	# AttlistDecls onto an intuitive Ruby interface, let me know.  I'm desperate
	# for anything to make DTDs more palateable.
	class AttlistDecl < Child
		include Enumerable

		# What is this?  Got me.
		attr_reader :element_name

		# Create an AttlistDecl, pulling the information from a Source.  Notice
		# that this isn't very convenient; to create an AttlistDecl, you basically
		# have to format it yourself, and then have the initializer parse it.
		# Sorry, but for the forseeable future, DTD support in REXML is pretty
		# weak on convenience.  Have I mentioned how much I hate DTDs?
		def initialize(source)
			super()
			if (source.kind_of? Array)
				@element_name, @pairs, @contents = *source
			end
		end
	
		# Access the attlist attribute/value pairs.
		#  value = attlist_decl[ attribute_name ]
		def [](key)
			@pairs[key]
		end

		# Whether an attlist declaration includes the given attribute definition
		#  if attlist_decl.include? "xmlns:foobar"
		def include?(key)
			@pairs.keys.include? key
		end

		# Iterate over the key/value pairs:
		#  attlist_decl.each { |attribute_name, attribute_value| ... }
		def each(&block)
			@pairs.each(&block)
		end

		# Write out exactly what we got in.
		def write out, indent=-1
			out << @contents
		end

		def node_type
			:attlistdecl
		end
	end
end
PK     Y\聓_:  :    rexml/validation/relaxng.rbnu [        require "rexml/validation/validation"
require "rexml/parsers/baseparser"

module REXML
  module Validation
    # Implemented:
    # * empty
    # * element
    # * attribute
    # * text
    # * optional
    # * choice
    # * oneOrMore
    # * zeroOrMore
    # * group
    # * value
    # * interleave
    # * mixed
    # * ref
    # * grammar
    # * start
    # * define
    #
    # Not implemented:
    # * data
    # * param
    # * include
    # * externalRef
    # * notAllowed
    # * anyName
    # * nsName
    # * except
    # * name
    class RelaxNG
      include Validator

      INFINITY = 1.0 / 0.0
      EMPTY = Event.new( nil )
      TEXT = [:start_element, "text"]
      attr_accessor :current
      attr_accessor :count
      attr_reader :references

      # FIXME: Namespaces
      def initialize source
        parser = REXML::Parsers::BaseParser.new( source )

        @count = 0
        @references = {}
        @root = @current = Sequence.new(self)
        @root.previous = true
        states = [ @current ]
        begin
          event = parser.pull
          case event[0]
          when :start_element
            case event[1]
            when "empty"
            when "element", "attribute", "text", "value"
              states[-1] << event
            when "optional"
              states << Optional.new( self )
              states[-2] << states[-1]
            when "choice"
              states << Choice.new( self )
              states[-2] << states[-1]
            when "oneOrMore"
              states << OneOrMore.new( self )
              states[-2] << states[-1]
            when "zeroOrMore"
              states << ZeroOrMore.new( self )
              states[-2] << states[-1]
            when "group"
              states << Sequence.new( self )
              states[-2] << states[-1]
            when "interleave"
              states << Interleave.new( self )
              states[-2] << states[-1]
            when "mixed"
              states << Interleave.new( self )
              states[-2] << states[-1]
              states[-1] << TEXT 
            when "define"
              states << [ event[2]["name"] ]
            when "ref"
              states[-1] << Ref.new( event[2]["name"] )
            when "anyName"
              states << AnyName.new( self )
              states[-2] << states[-1]
            when "nsName"
            when "except"
            when "name"
            when "data"
            when "param"
            when "include"
            when "grammar"
            when "start"
            when "externalRef"
            when "notAllowed"
            end
          when :end_element
            case event[1]
            when "element", "attribute"
              states[-1] << event
            when "zeroOrMore", "oneOrMore", "choice", "optional", 
              "interleave", "group", "mixed"
              states.pop
            when "define"
              ref = states.pop
              @references[ ref.shift ] = ref
            #when "empty"
            end
          when :end_document
            states[-1] << event
          when :text
            states[-1] << event
          end
        end while event[0] != :end_document
      end

      def receive event
        validate( event )
      end
    end

    class State
      def initialize( context )
        @previous = []
        @events = []
        @current = 0
        @count = context.count += 1
        @references = context.references
        @value = false
      end

      def reset
        return if @current == 0
        @current = 0
        @events.each {|s| s.reset if s.kind_of? State }
      end

      def previous=( previous ) 
        @previous << previous
      end

      def next( event )
        #print "In next with #{event.inspect}.  "
        #puts "Next (#@current) is #{@events[@current]}"
        #p @previous
        return @previous.pop.next( event ) if @events[@current].nil?
        expand_ref_in( @events, @current ) if @events[@current].class == Ref
        if ( @events[@current].kind_of? State )
          @current += 1
          @events[@current-1].previous = self
          return @events[@current-1].next( event )
        end
        #puts "Current isn't a state"
        if ( @events[@current].matches?(event) )
          @current += 1
          if @events[@current].nil?
            #puts "#{inspect[0,5]} 1RETURNING #{@previous.inspect[0,5]}"
            return @previous.pop
          elsif @events[@current].kind_of? State
            @current += 1
            #puts "#{inspect[0,5]} 2RETURNING (#{@current-1}) #{@events[@current-1].inspect[0,5]}; on return, next is #{@events[@current]}"
            @events[@current-1].previous = self
            return @events[@current-1]
          else
            #puts "#{inspect[0,5]} RETURNING self w/ next(#@current) = #{@events[@current]}"
            return self
          end
        else
          return nil
        end
      end

      def to_s
        # Abbreviated:
        self.class.name =~ /(?:::)(\w)\w+$/
        # Full:
        #self.class.name =~ /(?:::)(\w+)$/
        "#$1.#@count"
      end

      def inspect
        "< #{to_s} #{@events.collect{|e| 
          pre = e == @events[@current] ? '#' : ''
          pre + e.inspect unless self == e
        }.join(', ')} >"
      end

      def expected
        return [@events[@current]]
      end

      def <<( event )
        add_event_to_arry( @events, event )
      end


      protected
      def expand_ref_in( arry, ind )
        new_events = []
        @references[ arry[ind].to_s ].each{ |evt| 
          add_event_to_arry(new_events,evt)
        }
        arry[ind,1] = new_events
      end

      def add_event_to_arry( arry, evt ) 
        evt = generate_event( evt )
        if evt.kind_of? String 
          arry[-1].event_arg = evt if arry[-1].kind_of? Event and @value
          @value = false
        else
          arry << evt
        end
      end

      def generate_event( event )
        return event if event.kind_of? State or event.class == Ref
        evt = nil
        arg = nil
        case event[0]
        when :start_element
          case event[1]
          when "element"
            evt = :start_element
            arg = event[2]["name"]
          when "attribute"
            evt = :start_attribute
            arg = event[2]["name"]
          when "text"
            evt = :text
          when "value"
            evt = :text
            @value = true
          end
        when :text
          return event[1]
        when :end_document
          return Event.new( event[0] )
        else # then :end_element
          case event[1]
          when "element"
            evt = :end_element
          when "attribute"
            evt = :end_attribute
          end
        end
        return Event.new( evt, arg )
      end
    end


    class Sequence < State
      def matches?(event)
        @events[@current].matches?( event )
      end
    end


    class Optional < State
      def next( event )
        if @current == 0
          rv = super
          return rv if rv
          @prior = @previous.pop
          return @prior.next( event )
        end
        super
      end

      def matches?(event)
        @events[@current].matches?(event) || 
        (@current == 0 and @previous[-1].matches?(event))
      end

      def expected
        return [ @prior.expected, @events[0] ].flatten if @current == 0
        return [@events[@current]]
      end
    end


    class ZeroOrMore < Optional
      def next( event )
        expand_ref_in( @events, @current ) if @events[@current].class == Ref
        if ( @events[@current].matches?(event) )
          @current += 1
          if @events[@current].nil?
            @current = 0
            return self
          elsif @events[@current].kind_of? State
            @current += 1
            @events[@current-1].previous = self
            return @events[@current-1]
          else
            return self
          end
        else
          @prior = @previous.pop
          return @prior.next( event ) if @current == 0
          return nil
        end
      end

      def expected
        return [ @prior.expected, @events[0] ].flatten if @current == 0
        return [@events[@current]]
      end
    end


    class OneOrMore < State
      def initialize context
        super
        @ord = 0
      end

      def reset
        super 
        @ord = 0
      end

      def next( event )
        expand_ref_in( @events, @current ) if @events[@current].class == Ref
        if ( @events[@current].matches?(event) )
          @current += 1
          @ord += 1
          if @events[@current].nil?
            @current = 0
            return self
          elsif @events[@current].kind_of? State
            @current += 1
            @events[@current-1].previous = self
            return @events[@current-1]
          else
            return self
          end
        else
          return @previous.pop.next( event ) if @current == 0 and @ord > 0
          return nil
        end
      end

      def matches?( event )
        @events[@current].matches?(event) || 
        (@current == 0 and @ord > 0 and @previous[-1].matches?(event))
      end

      def expected
        if @current == 0 and @ord > 0
          return [@previous[-1].expected, @events[0]].flatten
        else
          return [@events[@current]]
        end
      end
    end


    class Choice < State
      def initialize context
        super
        @choices = []
      end

      def reset
        super
        @events = []
        @choices.each { |c| c.each { |s| s.reset if s.kind_of? State } }
      end

      def <<( event )
        add_event_to_arry( @choices, event )
      end

      def next( event )
        # Make the choice if we haven't
        if @events.size == 0
          c = 0 ; max = @choices.size
          while c < max
            if @choices[c][0].class == Ref
              expand_ref_in( @choices[c], 0 )
              @choices += @choices[c]
              @choices.delete( @choices[c] )
              max -= 1
            else
              c += 1
            end
          end
          @events = @choices.find { |evt| evt[0].matches? event }
          # Remove the references
          # Find the events
        end
        #puts "In next with #{event.inspect}."
        #puts "events is #{@events.inspect}"
        unless @events
          @events = []
          return nil
        end
        #puts "current = #@current"
        super
      end

      def matches?( event )
        return @events[@current].matches?( event ) if @events.size > 0
        !@choices.find{|evt| evt[0].matches?(event)}.nil?
      end

      def expected
        #puts "IN CHOICE EXPECTED"
        #puts "EVENTS = #{@events.inspect}"
        return [@events[@current]] if @events.size > 0
        return @choices.collect do |x| 
          if x[0].kind_of? State
            x[0].expected
          else
            x[0]
          end
        end.flatten
      end

      def inspect
        "< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' or ')} >"
      end

      protected
      def add_event_to_arry( arry, evt ) 
        if evt.kind_of? State or evt.class == Ref
          arry << [evt]
        elsif evt[0] == :text 
         if arry[-1] and
            arry[-1][-1].kind_of?( Event ) and 
            arry[-1][-1].event_type == :text and @value

            arry[-1][-1].event_arg = evt[1]
            @value = false
          end
        else
          arry << [] if evt[0] == :start_element
          arry[-1] << generate_event( evt )
        end
      end
    end


    class Interleave < Choice
      def initialize context
        super
        @choice = 0
      end

      def reset
        @choice = 0
      end

      def next_current( event )
        # Expand references
        c = 0 ; max = @choices.size
        while c < max
          if @choices[c][0].class == Ref
            expand_ref_in( @choices[c], 0 )
            @choices += @choices[c]
            @choices.delete( @choices[c] )
            max -= 1
          else
            c += 1
          end
        end
        @events = @choices[@choice..-1].find { |evt| evt[0].matches? event }
        @current = 0
        if @events
          # reorder the choices
          old = @choices[@choice]
          idx = @choices.index( @events )
          @choices[@choice] = @events
          @choices[idx] = old
          @choice += 1
        end
        
       #puts "In next with #{event.inspect}."
       #puts "events is #{@events.inspect}"
        @events = [] unless @events
      end


      def next( event )
        # Find the next series
        next_current(event) unless @events[@current]
        return nil unless @events[@current]

        expand_ref_in( @events, @current ) if @events[@current].class == Ref 
       #puts "In next with #{event.inspect}."
       #puts "Next (#@current) is #{@events[@current]}"
        if ( @events[@current].kind_of? State )
          @current += 1
          @events[@current-1].previous = self
          return @events[@current-1].next( event )
        end
       #puts "Current isn't a state"
        return @previous.pop.next( event ) if @events[@current].nil?
        if ( @events[@current].matches?(event) )
          @current += 1
          if @events[@current].nil?
           #puts "#{inspect[0,5]} 1RETURNING self" unless @choices[@choice].nil?
            return self unless @choices[@choice].nil?
           #puts "#{inspect[0,5]} 1RETURNING #{@previous[-1].inspect[0,5]}"
            return @previous.pop
          elsif @events[@current].kind_of? State
            @current += 1
           #puts "#{inspect[0,5]} 2RETURNING (#{@current-1}) #{@events[@current-1].inspect[0,5]}; on return, next is #{@events[@current]}"
            @events[@current-1].previous = self
            return @events[@current-1]
          else
           #puts "#{inspect[0,5]} RETURNING self w/ next(#@current) = #{@events[@current]}"
            return self
          end
        else
          return nil
        end
      end

      def matches?( event )
        return @events[@current].matches?( event ) if @events[@current]
        !@choices[@choice..-1].find{|evt| evt[0].matches?(event)}.nil?
      end

      def expected
        #puts "IN CHOICE EXPECTED"
        #puts "EVENTS = #{@events.inspect}"
        return [@events[@current]] if @events[@current]
        return @choices[@choice..-1].collect do |x| 
          if x[0].kind_of? State
            x[0].expected
          else
            x[0]
          end
        end.flatten
      end

      def inspect
        "< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' and ')} >"
      end
    end

    class Ref
      def initialize value
        @value = value
      end
      def to_s
        @value
      end
      def inspect
        "{#{to_s}}"
      end
    end
  end
end
PK     Y\Yڑ      '  rexml/validation/validationexception.rbnu [        module REXML
  module Validation
    class ValidationException < RuntimeError
      def initialize msg
        super
      end
    end
  end
end
PK     Y\R_5  5    rexml/validation/validation.rbnu [        require 'rexml/validation/validationexception'

module REXML
  module Validation
    module Validator
      NILEVENT = [ nil ]
      def reset
        @current = @root
        @root.reset
        @root.previous = true
        @attr_stack = []
        self
      end
      def dump
        puts @root.inspect
      end
      def validate( event ) 
        #puts "Current: #@current"
        #puts "Event: #{event.inspect}"
        @attr_stack = [] unless defined? @attr_stack
        match = @current.next(event)
        raise ValidationException.new( "Validation error.  Expected: "+
          @current.expected.join( " or " )+" from #{@current.inspect} "+
          " but got #{Event.new( event[0], event[1] ).inspect}" ) unless match
        @current = match

        # Check for attributes
        case event[0]
        when :start_element
          #puts "Checking attributes"
          @attr_stack << event[2]
          begin
            sattr = [:start_attribute, nil]
            eattr = [:end_attribute]
            text = [:text, nil]
            k,v = event[2].find { |k,v| 
              sattr[1] = k
              #puts "Looking for #{sattr.inspect}"
              m = @current.next( sattr )
              #puts "Got #{m.inspect}"
              if m 
                # If the state has text children...
                #puts "Looking for #{eattr.inspect}"
                #puts "Expect #{m.expected}"
                if m.matches?( eattr )
                  #puts "Got end"
                  @current = m
                else
                  #puts "Didn't get end"
                  text[1] = v
                  #puts "Looking for #{text.inspect}"
                  m = m.next( text )
                  #puts "Got #{m.inspect}"
                  text[1] = nil
                  return false unless m
                  @current = m if m
                end
                m = @current.next( eattr )
                if m
                  @current = m
                  true
                else
                  false
                end
              else
                false
              end
            }
            event[2].delete(k) if k
          end while k
        when :end_element
          attrs = @attr_stack.pop
          raise ValidationException.new( "Validation error.  Illegal "+
            " attributes: #{attrs.inspect}") if attrs.length > 0
        end
      end
    end

    class Event
      def initialize(event_type, event_arg=nil )
        @event_type = event_type
        @event_arg = event_arg
      end

      attr_reader :event_type
      attr_accessor :event_arg

      def done?
        @done
      end

      def single?
        return (@event_type != :start_element and @event_type != :start_attribute)
      end

      def matches?( event )
        #puts "#@event_type =? #{event[0]} && #@event_arg =? #{event[1]} "
        return false unless event[0] == @event_type
        case event[0]
        when nil
          return true
        when :start_element
          return true if event[1] == @event_arg
        when :end_element
          return true
        when :start_attribute
          return true if event[1] == @event_arg
        when :end_attribute
          return true
        when :end_document
          return true
        when :text
          return (@event_arg.nil? or @event_arg == event[1])
=begin
        when :processing_instruction
          false
        when :xmldecl
          false
        when :start_doctype
          false
        when :end_doctype
          false
        when :externalentity
          false
        when :elementdecl
          false
        when :entity
          false
        when :attlistdecl
          false
        when :notationdecl
          false
        when :end_doctype
          false
=end
        else
          false
        end
      end

      def ==( other )
        return false unless other.kind_of? Event
        @event_type == other.event_type and @event_arg == other.event_arg
      end

      def to_s
        inspect
      end

      def inspect
        "#{@event_type.inspect}( #@event_arg )"
      end
    end
  end
end
PK     Y\Sŕ      rexml/parent.rbnu [        require "rexml/child"

module REXML
  # A parent has children, and has methods for accessing them.  The Parent
  # class is never encountered except as the superclass for some other
  # object.
  class Parent < Child
    include Enumerable
    
    # Constructor
    # @param parent if supplied, will be set as the parent of this object
    def initialize parent=nil
      super(parent)
      @children = []
    end
    
    def add( object )
      #puts "PARENT GOTS #{size} CHILDREN"
      object.parent = self
      @children << object
      #puts "PARENT NOW GOTS #{size} CHILDREN"
      object
    end
    
    alias :push :add
    alias :<< :push
    
    def unshift( object )
      object.parent = self
      @children.unshift object
    end
    
    def delete( object )
      found = false
      @children.delete_if {|c| c.equal?(object) and found = true }
      object.parent = nil if found
    end
    
    def each(&block)
      @children.each(&block)
    end
    
    def delete_if( &block )
      @children.delete_if(&block)
    end
    
    def delete_at( index )
      @children.delete_at index
    end
    
    def each_index( &block )
      @children.each_index(&block)
    end
    
    # Fetches a child at a given index
    # @param index the Integer index of the child to fetch
    def []( index )
      @children[index]
    end
    
    alias :each_child :each
    
    
    
    # Set an index entry.  See Array.[]=
    # @param index the index of the element to set
    # @param opt either the object to set, or an Integer length
    # @param child if opt is an Integer, this is the child to set
    # @return the parent (self)
    def []=( *args )
      args[-1].parent = self
      @children[*args[0..-2]] = args[-1]
    end
    
    # Inserts an child before another child
    # @param child1 this is either an xpath or an Element.  If an Element,
    # child2 will be inserted before child1 in the child list of the parent.
    # If an xpath, child2 will be inserted before the first child to match
    # the xpath.
    # @param child2 the child to insert
    # @return the parent (self)
    def insert_before( child1, child2 )
      if child1.kind_of? String
        child1 = XPath.first( self, child1 )
        child1.parent.insert_before child1, child2
      else
        ind = index(child1)
        child2.parent.delete(child2) if child2.parent
        @children[ind,0] = child2
        child2.parent = self
      end
      self
    end
    
    # Inserts an child after another child
    # @param child1 this is either an xpath or an Element.  If an Element,
    # child2 will be inserted after child1 in the child list of the parent.
    # If an xpath, child2 will be inserted after the first child to match
    # the xpath.
    # @param child2 the child to insert
    # @return the parent (self)
    def insert_after( child1, child2 )
      if child1.kind_of? String
        child1 = XPath.first( self, child1 )
        child1.parent.insert_after child1, child2
      else
        ind = index(child1)+1
        child2.parent.delete(child2) if child2.parent
        @children[ind,0] = child2
        child2.parent = self
      end
      self
    end
    
    def to_a
      @children.dup
    end
    
    # Fetches the index of a given child
    # @param child the child to get the index of
    # @return the index of the child, or nil if the object is not a child
    # of this parent.
    def index( child )
      count = -1
      @children.find { |i| count += 1 ; i.hash == child.hash }
      count
    end
    
    # @return the number of children of this parent
    def size
      @children.size
    end
    
    alias :length :size
    
    # Replaces one child with another, making sure the nodelist is correct
    # @param to_replace the child to replace (must be a Child)
    # @param replacement the child to insert into the nodelist (must be a 
    # Child)
    def replace_child( to_replace, replacement )
      @children.map! {|c| c.equal?( to_replace ) ? replacement : c }
      to_replace.parent = nil
      replacement.parent = self
    end
    
    # Deeply clones this object.  This creates a complete duplicate of this
    # Parent, including all descendants.
    def deep_clone
      cl = clone()
      each do |child|
        if child.kind_of? Parent
          cl << child.deep_clone
        else
          cl << child.clone
        end
      end
      cl
    end
    
    alias :children :to_a
    
    def parent?
      true
    end
  end
end
PK     Y\      rexml/doctype.rbnu [        require "rexml/parent"
require "rexml/parseexception"
require "rexml/namespace"
require 'rexml/entity'
require 'rexml/attlistdecl'
require 'rexml/xmltokens'

module REXML
  # Represents an XML DOCTYPE declaration; that is, the contents of <!DOCTYPE
  # ... >.  DOCTYPES can be used to declare the DTD of a document, as well as
  # being used to declare entities used in the document.
  class DocType < Parent
    include XMLTokens
    START = "<!DOCTYPE"
    STOP = ">"
    SYSTEM = "SYSTEM"
    PUBLIC = "PUBLIC"
    DEFAULT_ENTITIES = { 
      'gt'=>EntityConst::GT, 
      'lt'=>EntityConst::LT, 
      'quot'=>EntityConst::QUOT, 
      "apos"=>EntityConst::APOS 
    }

    # name is the name of the doctype
    # external_id is the referenced DTD, if given
    attr_reader :name, :external_id, :entities, :namespaces

    # Constructor
    #
    #   dt = DocType.new( 'foo', '-//I/Hate/External/IDs' )
    #   # <!DOCTYPE foo '-//I/Hate/External/IDs'>
    #   dt = DocType.new( doctype_to_clone )
    #   # Incomplete.  Shallow clone of doctype
    #
    # +Note+ that the constructor: 
    #
    #  Doctype.new( Source.new( "<!DOCTYPE foo 'bar'>" ) )
    #
    # is _deprecated_.  Do not use it.  It will probably disappear.
    def initialize( first, parent=nil )
      @entities = DEFAULT_ENTITIES
      @long_name = @uri = nil
      if first.kind_of? String
        super()
        @name = first
        @external_id = parent
      elsif first.kind_of? DocType
        super( parent )
        @name = first.name
        @external_id = first.external_id
      elsif first.kind_of? Array
        super( parent )
        @name = first[0]
        @external_id = first[1]
        @long_name = first[2]
        @uri = first[3]
      elsif first.kind_of? Source
        super( parent )
        parser = Parsers::BaseParser.new( first )
        event = parser.pull
        if event[0] == :start_doctype
          @name, @external_id, @long_name, @uri, = event[1..-1]
        end
      else
        super()
      end
    end

    def node_type
      :doctype
    end

    def attributes_of element
      rv = []
      each do |child|
        child.each do |key,val|
          rv << Attribute.new(key,val)
        end if child.kind_of? AttlistDecl and child.element_name == element
      end
      rv
    end

    def attribute_of element, attribute
      att_decl = find do |child|
        child.kind_of? AttlistDecl and
        child.element_name == element and
        child.include? attribute
      end
      return nil unless att_decl
      att_decl[attribute]
    end

    def clone
      DocType.new self
    end

    # output::
    #   Where to write the string
    # indent::
    #   An integer.  If -1, no indentation will be used; otherwise, the
    #   indentation will be this number of spaces, and children will be
    #   indented an additional amount.
    # transitive::
    #   Ignored
    # ie_hack::
    #   Ignored
    def write( output, indent=0, transitive=false, ie_hack=false )
      f = REXML::Formatters::Default.new
      indent( output, indent )
      output << START
      output << ' '
      output << @name
      output << " #@external_id" if @external_id
      output << " #{@long_name.inspect}" if @long_name
      output << " #{@uri.inspect}" if @uri
      unless @children.empty?
        next_indent = indent + 1
        output << ' ['
        child = nil    # speed
        @children.each { |child|
          output << "\n"
          f.write( child, output )
        }
        output << "\n]"
      end
      output << STOP
    end

    def context
      @parent.context
    end

    def entity( name )
      @entities[name].unnormalized if @entities[name]
    end

    def add child
      super(child)
      @entities = DEFAULT_ENTITIES.clone if @entities == DEFAULT_ENTITIES
      @entities[ child.name ] = child if child.kind_of? Entity
    end
    
    # This method retrieves the public identifier identifying the document's 
    # DTD.
    #
    # Method contributed by Henrik Martensson
    def public
      case @external_id
      when "SYSTEM"
        nil
      when "PUBLIC"
        strip_quotes(@long_name)
      end
    end
    
    # This method retrieves the system identifier identifying the document's DTD
    #
    # Method contributed by Henrik Martensson
    def system
      case @external_id
      when "SYSTEM"
        strip_quotes(@long_name)
      when "PUBLIC"
        @uri.kind_of?(String) ? strip_quotes(@uri) : nil
      end
    end
    
    # This method returns a list of notations that have been declared in the
    # _internal_ DTD subset. Notations in the external DTD subset are not 
    # listed.
    #
    # Method contributed by Henrik Martensson
    def notations
      children().select {|node| node.kind_of?(REXML::NotationDecl)}
    end
    
    # Retrieves a named notation. Only notations declared in the internal
    # DTD subset can be retrieved.
    #
    # Method contributed by Henrik Martensson
    def notation(name)
      notations.find { |notation_decl|
        notation_decl.name == name
      }
    end
    
    private
    
    # Method contributed by Henrik Martensson
    def strip_quotes(quoted_string)
      quoted_string =~ /^[\'\"].*[\´\"]$/ ?
        quoted_string[1, quoted_string.length-2] :
        quoted_string
    end
  end

  # We don't really handle any of these since we're not a validating
  # parser, so we can be pretty dumb about them.  All we need to be able
  # to do is spew them back out on a write()

  # This is an abstract class.  You never use this directly; it serves as a
  # parent class for the specific declarations.
  class Declaration < Child
    def initialize src
      super()
      @string = src
    end

    def to_s
      @string+'>'
    end

    # == DEPRECATED
    # See REXML::Formatters
    #
    def write( output, indent )
      output << to_s
    end
  end
  
  public
  class ElementDecl < Declaration
    def initialize( src )
      super
    end
  end

  class ExternalEntity < Child
    def initialize( src )
      super()
      @entity = src
    end
    def to_s
      @entity
    end
    def write( output, indent )
      output << @entity
    end
  end

  class NotationDecl < Child
    attr_accessor :public, :system
    def initialize name, middle, pub, sys
      super(nil)
      @name = name
      @middle = middle
      @public = pub
      @system = sys
    end

    def to_s
      "<!NOTATION #@name #@middle#{
        @public ? ' ' + public.inspect : '' 
      }#{
        @system ? ' ' +@system.inspect : ''
      }>"
    end

    def write( output, indent=-1 )
      output << to_s
    end
    
    # This method retrieves the name of the notation.
    #
    # Method contributed by Henrik Martensson
    def name
      @name
    end
  end
end
PK     Y\`      $  rexml/undefinednamespaceexception.rbnu [        require 'rexml/parseexception'
module REXML
  class UndefinedNamespaceException < ParseException
    def initialize( prefix, source, parser )
      super( "Undefined prefix #{prefix} found" )
    end
  end
end
PK     Y\x      rexml/instruction.rbnu [        require "rexml/child"
require "rexml/source"

module REXML
	# Represents an XML Instruction; IE, <? ... ?>
	# TODO: Add parent arg (3rd arg) to constructor
	class Instruction < Child
		START = '<\?'
		STOP = '\?>'

		# target is the "name" of the Instruction; IE, the "tag" in <?tag ...?>
		# content is everything else.
		attr_accessor :target, :content

		# Constructs a new Instruction
		# @param target can be one of a number of things.  If String, then 
		# the target of this instruction is set to this.  If an Instruction,
		# then the Instruction is shallowly cloned (target and content are
		# copied).  If a Source, then the source is scanned and parsed for
		# an Instruction declaration.
		# @param content Must be either a String, or a Parent.  Can only
		# be a Parent if the target argument is a Source.  Otherwise, this
		# String is set as the content of this instruction.
		def initialize(target, content=nil)
			if target.kind_of? String
				super()
				@target = target
				@content = content
			elsif target.kind_of? Instruction
				super(content)
				@target = target.target
				@content = target.content
			end
			@content.strip! if @content
		end

		def clone
			Instruction.new self
		end
		
    # == DEPRECATED
    # See the rexml/formatters package
    #
		def write writer, indent=-1, transitive=false, ie_hack=false
      Kernel.warn( "#{self.class.name}.write is deprecated" )
			indent(writer, indent)
			writer << START.sub(/\\/u, '')
			writer << @target
			writer << ' '
			writer << @content
			writer << STOP.sub(/\\/u, '')
		end

		# @return true if other is an Instruction, and the content and target
		# of the other matches the target and content of this object.
		def ==( other )
			other.kind_of? Instruction and
			other.target == @target and
			other.content == @content
		end

    def node_type
      :processing_instruction
    end

    def inspect
      "<?p-i #{target} ...?>"
    end
	end
end
PK     Y\:i      rexml/comment.rbnu [        require "rexml/child"

module REXML
	##
	# Represents an XML comment; that is, text between \<!-- ... -->
	class Comment < Child
		include Comparable
		START = "<!--"
		STOP = "-->"

		# The content text

		attr_accessor :string

		##
		# Constructor.  The first argument can be one of three types:
		# @param first If String, the contents of this comment are set to the 
		# argument.  If Comment, the argument is duplicated.  If
		# Source, the argument is scanned for a comment.
		# @param second If the first argument is a Source, this argument 
		# should be nil, not supplied, or a Parent to be set as the parent 
		# of this object
		def initialize( first, second = nil )
			#puts "IN COMMENT CONSTRUCTOR; SECOND IS #{second.type}"
			super(second)
			if first.kind_of? String
				@string = first
			elsif first.kind_of? Comment
				@string = first.string
			end
		end

		def clone
			Comment.new self
		end

    # == DEPRECATED
    # See REXML::Formatters
    #
		# output::
		#	 Where to write the string
		# indent::
		#	 An integer.	If -1, no indenting will be used; otherwise, the
		#	 indentation will be this number of spaces, and children will be
		#	 indented an additional amount.
		# transitive::
		#	 Ignored by this class.	The contents of comments are never modified.
		# ie_hack::
		#	 Needed for conformity to the child API, but not used by this class.
		def write( output, indent=-1, transitive=false, ie_hack=false )
      Kernel.warn("Comment.write is deprecated.  See REXML::Formatters")
			indent( output, indent )
			output << START
			output << @string
			output << STOP
		end

		alias :to_s :string

		##
		# Compares this Comment to another; the contents of the comment are used
		# in the comparison.
		def <=>(other)
			other.to_s <=> @string
		end

		##
		# Compares this Comment to another; the contents of the comment are used
		# in the comparison.
		def ==( other )
			other.kind_of? Comment and
			(other <=> self) == 0
		end

    def node_type
      :comment
    end
	end
end
#vim:ts=2 sw=2 noexpandtab:
PK     Y\)*      rexml/encodings/ICONV.rbnu [        require "iconv"
raise LoadError unless defined? Iconv

module REXML
  module Encoding
    def decode_iconv(str)
      Iconv.conv(UTF_8, @encoding, str)
    end

    def encode_iconv(content)
      Iconv.conv(@encoding, UTF_8, content)
    end

    register("ICONV") do |obj|
      Iconv.conv(UTF_8, obj.encoding, nil)
      class << obj
        alias decode decode_iconv
        alias encode encode_iconv
      end
    end
  end
end
PK     Y\*      rexml/encodings/UNILE.rbnu [        module REXML
  module Encoding
    def encode_unile content
      array_utf8 = content.unpack("U*")
      array_enc = []
      array_utf8.each do |num|
        if ((num>>16) > 0)
          array_enc << ??
          array_enc << 0
        else
          array_enc << (num & 0xFF)
          array_enc << (num >> 8)
        end
      end
      array_enc.pack('C*')
    end

    def decode_unile(str)
      array_enc=str.unpack('C*')
      array_utf8 = []
      0.step(array_enc.size-1, 2){|i| 
        array_utf8 << (array_enc.at(i) + array_enc.at(i+1)*0x100)
      }
      array_utf8.pack('U*')
    end

    register(UNILE) do |obj|
      class << obj
        alias decode decode_unile
        alias encode encode_unile
      end
    end
  end
end
PK     Y\3#      rexml/encodings/UTF-8.rbnu [        module REXML
  module Encoding
    def encode_utf8 content
      content
    end

    def decode_utf8(str)
      str
    end

    register(UTF_8) do |obj|
      class << obj
        alias decode decode_utf8
        alias encode encode_utf8
      end
    end
  end
end
PK     Y\,v>        rexml/encodings/ISO-8859-1.rbnu [        require 'rexml/encodings/US-ASCII'

module REXML
  module Encoding
    register("ISO-8859-1", &encoding_method("US-ASCII"))
  end
end
PK     Y\      rexml/encodings/US-ASCII.rbnu [        module REXML
  module Encoding
    # Convert from UTF-8
    def encode_ascii content
      array_utf8 = content.unpack('U*')
      array_enc = []
      array_utf8.each do |num|
        if num <= 0x7F
          array_enc << num
        else
          # Numeric entity (&#nnnn;); shard by  Stefan Scholl
          array_enc.concat "&\##{num};".unpack('C*')
        end
      end
      array_enc.pack('C*')
    end

    # Convert to UTF-8
    def decode_ascii(str)
      str.unpack('C*').pack('U*')
    end

    register("US-ASCII") do |obj|
      class << obj
        alias decode decode_ascii
        alias encode encode_ascii
      end
    end
  end
end
PK     Y\F	m	  	    rexml/encodings/ISO-8859-15.rbnu [        #
# This class was contributed by Mikko Tiihonen mikko DOT tiihonen AT hut DOT fi
#
module REXML
  module Encoding
  	register("ISO-8859-15") do |o|
  		alias encode to_iso_8859_15
      alias decode from_iso_8859_15
  	end

    # Convert from UTF-8
    def to_iso_8859_15(content)
      array_utf8 = content.unpack('U*')
      array_enc = []
      array_utf8.each do |num|
        case num
          # shortcut first bunch basic characters
        when 0..0xA3; array_enc << num
          # characters removed compared to iso-8859-1
        when 0xA4; array_enc << '&#164;'
        when 0xA6; array_enc << '&#166;'
        when 0xA8; array_enc << '&#168;'
        when 0xB4; array_enc << '&#180;'
        when 0xB8; array_enc << '&#184;'
        when 0xBC; array_enc << '&#188;'
        when 0xBD; array_enc << '&#189;'
        when 0xBE; array_enc << '&#190;'
          # characters added compared to iso-8859-1
        when 0x20AC; array_enc << 0xA4 # 0xe2 0x82 0xac
        when 0x0160; array_enc << 0xA6 # 0xc5 0xa0
        when 0x0161; array_enc << 0xA8 # 0xc5 0xa1
        when 0x017D; array_enc << 0xB4 # 0xc5 0xbd
        when 0x017E; array_enc << 0xB8 # 0xc5 0xbe
        when 0x0152; array_enc << 0xBC # 0xc5 0x92
        when 0x0153; array_enc << 0xBD # 0xc5 0x93
        when 0x0178; array_enc << 0xBE # 0xc5 0xb8
        else
          # all remaining basic characters can be used directly
          if num <= 0xFF
            array_enc << num
          else
            # Numeric entity (&#nnnn;); shard by  Stefan Scholl
            array_enc.concat "&\##{num};".unpack('C*')
          end
        end
      end
      array_enc.pack('C*')
    end
    
    # Convert to UTF-8
    def from_iso_8859_15(str)
      array_latin9 = str.unpack('C*')
      array_enc = []
      array_latin9.each do |num|
        case num
          # characters that differ compared to iso-8859-1
        when 0xA4; array_enc << 0x20AC
        when 0xA6; array_enc << 0x0160
        when 0xA8; array_enc << 0x0161
        when 0xB4; array_enc << 0x017D
        when 0xB8; array_enc << 0x017E
        when 0xBC; array_enc << 0x0152
        when 0xBD; array_enc << 0x0153
        when 0xBE; array_enc << 0x0178
        else
          array_enc << num
        end
      end
      array_enc.pack('U*')
    end
  end
end
PK     Y\(FS  S    rexml/encodings/EUC-JP.rbnu [        module REXML
  module Encoding
    begin
      require 'uconv'

      def decode_eucjp(str)
        Uconv::euctou8(str)
      end

      def encode_eucjp content
        Uconv::u8toeuc(content)
      end
    rescue LoadError
      require 'nkf'

      EUCTOU8 = '-Ewm0'
      U8TOEUC = '-Wem0'

      def decode_eucjp(str)
        NKF.nkf(EUCTOU8, str)
      end

      def encode_eucjp content
        NKF.nkf(U8TOEUC, content)
      end
    end

    register("EUC-JP") do |obj|
      class << obj
        alias decode decode_eucjp
        alias encode encode_eucjp
      end
    end
  end
end
PK     Y\M&  &    rexml/encodings/CP-1252.rbnu [        #
# This class was contributed by Mikko Tiihonen mikko DOT tiihonen AT hut DOT fi
#
module REXML
  module Encoding
  	register( "CP-1252" ) do |o|
  		class << o
  			alias encode encode_cp1252
			alias decode decode_cp1252
  		end
  	end

    # Convert from UTF-8
    def encode_cp1252(content)
      array_utf8 = content.unpack('U*')
      array_enc = []
      array_utf8.each do |num|
        case num
          # shortcut first bunch basic characters
        when 0..0xFF; array_enc << num
          # characters added compared to iso-8859-1
        when 0x20AC; array_enc << 0x80 # 0xe2 0x82 0xac
        when 0x201A; array_enc << 0x82 # 0xe2 0x82 0x9a
        when 0x0192; array_enc << 0x83 # 0xc6 0x92
        when 0x201E; array_enc << 0x84 # 0xe2 0x82 0x9e
        when 0x2026; array_enc << 0x85 # 0xe2 0x80 0xa6
        when 0x2020; array_enc << 0x86 # 0xe2 0x80 0xa0
        when 0x2021; array_enc << 0x87 # 0xe2 0x80 0xa1
        when 0x02C6; array_enc << 0x88 # 0xcb 0x86
        when 0x2030; array_enc << 0x89 # 0xe2 0x80 0xb0
        when 0x0160; array_enc << 0x8A # 0xc5 0xa0
        when 0x2039; array_enc << 0x8B # 0xe2 0x80 0xb9
        when 0x0152; array_enc << 0x8C # 0xc5 0x92
        when 0x017D; array_enc << 0x8E # 0xc5 0xbd
        when 0x2018; array_enc << 0x91 # 0xe2 0x80 0x98
        when 0x2019; array_enc << 0x92 # 0xe2 0x80 0x99
        when 0x201C; array_enc << 0x93 # 0xe2 0x80 0x9c
        when 0x201D; array_enc << 0x94 # 0xe2 0x80 0x9d
        when 0x2022; array_enc << 0x95 # 0xe2 0x80 0xa2
        when 0x2013; array_enc << 0x96 # 0xe2 0x80 0x93
        when 0x2014; array_enc << 0x97 # 0xe2 0x80 0x94
        when 0x02DC; array_enc << 0x98 # 0xcb 0x9c
        when 0x2122; array_enc << 0x99 # 0xe2 0x84 0xa2
        when 0x0161; array_enc << 0x9A # 0xc5 0xa1
        when 0x203A; array_enc << 0x9B # 0xe2 0x80 0xba
        when 0x0152; array_enc << 0x9C # 0xc5 0x93
        when 0x017E; array_enc << 0x9E # 0xc5 0xbe
        when 0x0178; array_enc << 0x9F # 0xc5 0xb8
        else
          # all remaining basic characters can be used directly
          if num <= 0xFF
            array_enc << num
          else
            # Numeric entity (&#nnnn;); shard by  Stefan Scholl
            array_enc.concat "&\##{num};".unpack('C*')
          end
        end
      end
      array_enc.pack('C*')
    end
    
    # Convert to UTF-8
    def decode_cp1252(str)
      array_latin9 = str.unpack('C*')
      array_enc = []
      array_latin9.each do |num|
        case num
          # characters that added compared to iso-8859-1
        when 0x80; array_enc << 0x20AC # 0xe2 0x82 0xac
        when 0x82; array_enc << 0x201A # 0xe2 0x82 0x9a
        when 0x83; array_enc << 0x0192 # 0xc6 0x92
        when 0x84; array_enc << 0x201E # 0xe2 0x82 0x9e
        when 0x85; array_enc << 0x2026 # 0xe2 0x80 0xa6
        when 0x86; array_enc << 0x2020 # 0xe2 0x80 0xa0
        when 0x87; array_enc << 0x2021 # 0xe2 0x80 0xa1
        when 0x88; array_enc << 0x02C6 # 0xcb 0x86
        when 0x89; array_enc << 0x2030 # 0xe2 0x80 0xb0
        when 0x8A; array_enc << 0x0160 # 0xc5 0xa0
        when 0x8B; array_enc << 0x2039 # 0xe2 0x80 0xb9
        when 0x8C; array_enc << 0x0152 # 0xc5 0x92
        when 0x8E; array_enc << 0x017D # 0xc5 0xbd
        when 0x91; array_enc << 0x2018 # 0xe2 0x80 0x98
        when 0x92; array_enc << 0x2019 # 0xe2 0x80 0x99
        when 0x93; array_enc << 0x201C # 0xe2 0x80 0x9c
        when 0x94; array_enc << 0x201D # 0xe2 0x80 0x9d
        when 0x95; array_enc << 0x2022 # 0xe2 0x80 0xa2
        when 0x96; array_enc << 0x2013 # 0xe2 0x80 0x93
        when 0x97; array_enc << 0x2014 # 0xe2 0x80 0x94
        when 0x98; array_enc << 0x02DC # 0xcb 0x9c
        when 0x99; array_enc << 0x2122 # 0xe2 0x84 0xa2
        when 0x9A; array_enc << 0x0161 # 0xc5 0xa1
        when 0x9B; array_enc << 0x203A # 0xe2 0x80 0xba
        when 0x9C; array_enc << 0x0152 # 0xc5 0x93
        when 0x9E; array_enc << 0x017E # 0xc5 0xbe
        when 0x9F; array_enc << 0x0178 # 0xc5 0xb8
        else
          array_enc << num
        end
      end
      array_enc.pack('U*')
    end
  end
end
PK     Y\(;8      rexml/encodings/UTF-16.rbnu [        module REXML
  module Encoding
    def encode_utf16 content
      array_utf8 = content.unpack("U*")
      array_enc = []
      array_utf8.each do |num|
        if ((num>>16) > 0)
          array_enc << 0
          array_enc << ??
        else
          array_enc << (num >> 8)
          array_enc << (num & 0xFF)
        end
      end
      array_enc.pack('C*')
    end

    def decode_utf16(str)
      str = str[2..-1] if /^\376\377/n =~ str
      array_enc=str.unpack('C*')
      array_utf8 = []
      0.step(array_enc.size-1, 2){|i| 
        array_utf8 << (array_enc.at(i+1) + array_enc.at(i)*0x100)
      }
      array_utf8.pack('U*')
    end

    register(UTF_16) do |obj|
      class << obj
        alias decode decode_utf16
        alias encode encode_utf16
      end
    end
  end
end
PK     Y\<rއ      rexml/encodings/SHIFT-JIS.rbnu [        module REXML
  module Encoding
    begin
      require 'uconv'

      def decode_sjis content
        Uconv::sjistou8(content)
      end

      def encode_sjis(str)
        Uconv::u8tosjis(str)
      end
    rescue LoadError
      require 'nkf'

      SJISTOU8 = '-Swm0x'
      U8TOSJIS = '-Wsm0x'

      def decode_sjis(str)
        NKF.nkf(SJISTOU8, str)
      end

      def encode_sjis content
        NKF.nkf(U8TOSJIS, content)
      end
    end

    b = proc do |obj|
      class << obj
        alias decode decode_sjis
        alias encode encode_sjis
      end
    end
    register("SHIFT-JIS", &b)
    register("SHIFT_JIS", &b)
  end
end
PK     Y\`m$   $     rexml/encodings/SHIFT_JIS.rbnu [        require 'rexml/encodings/SHIFT-JIS'
PK     Y\{{S  S    rexml/encoding.rbnu [        # -*- mode: ruby; ruby-indent-level: 2; indent-tabs-mode: t; tab-width: 2 -*- vim: sw=2 ts=2
module REXML
  module Encoding
    @encoding_methods = {}
    def self.register(enc, &block)
      @encoding_methods[enc] = block
    end
    def self.apply(obj, enc)
      @encoding_methods[enc][obj]
    end
    def self.encoding_method(enc)
      @encoding_methods[enc]
    end

    # Native, default format is UTF-8, so it is declared here rather than in
    # an encodings/ definition.
    UTF_8 = 'UTF-8'
    UTF_16 = 'UTF-16'
    UNILE = 'UNILE'

    # ID ---> Encoding name
    attr_reader :encoding
    def encoding=( enc )
      old_verbosity = $VERBOSE
      begin
        $VERBOSE = false
        enc = enc.nil? ? nil : enc.upcase
        return false if defined? @encoding and enc == @encoding
        if enc and enc != UTF_8
          @encoding = enc
          raise ArgumentError, "Bad encoding name #@encoding" unless @encoding =~ /^[\w-]+$/
          @encoding.untaint 
          begin
            require 'rexml/encodings/ICONV.rb'
            Encoding.apply(self, "ICONV")
          rescue LoadError, Exception
            begin
              enc_file = File.join( "rexml", "encodings", "#@encoding.rb" )
              require enc_file
              Encoding.apply(self, @encoding)
            rescue LoadError => err
              puts err.message
              raise ArgumentError, "No decoder found for encoding #@encoding.  Please install iconv."
            end
          end
        else
          @encoding = UTF_8
          require 'rexml/encodings/UTF-8.rb'
          Encoding.apply(self, @encoding)
        end
      ensure
        $VERBOSE = old_verbosity
      end
      true
    end

    def check_encoding str
      # We have to recognize UTF-16, LSB UTF-16, and UTF-8
      if str[0] == 0xfe && str[1] == 0xff
        str[0,2] = ""
        return UTF_16
      elsif str[0] == 0xff && str[1] == 0xfe
        str[0,2] = ""
        return UNILE
      end
      str =~ /^\s*<\?xml\s+version\s*=\s*(['"]).*?\1\s+encoding\s*=\s*(["'])(.*?)\2/um
      return $3.upcase if $3
      return UTF_8
    end
  end
end
PK     Y\      rexml/parsers/sax2parser.rbnu [        require 'rexml/parsers/baseparser'
require 'rexml/parseexception'
require 'rexml/namespace'
require 'rexml/text'

module REXML
	module Parsers
    # SAX2Parser
		class SAX2Parser
			def initialize source
				@parser = BaseParser.new(source)
				@listeners = []
				@procs = []
				@namespace_stack = []
				@has_listeners = false
				@tag_stack = []
        @entities = {}
			end

      def source
        @parser.source
      end
			
      def add_listener( listener )
        @parser.add_listener( listener )
      end

			# Listen arguments:
			#
			# Symbol, Array, Block
			# 	Listen to Symbol events on Array elements
			# Symbol, Block
			#   Listen to Symbol events
			# Array, Listener
			# 	Listen to all events on Array elements
			# Array, Block
			# 	Listen to :start_element events on Array elements
			# Listener
			# 	Listen to All events
			#
			# Symbol can be one of: :start_element, :end_element,
			# :start_prefix_mapping, :end_prefix_mapping, :characters,
			# :processing_instruction, :doctype, :attlistdecl, :elementdecl,
			# :entitydecl, :notationdecl, :cdata, :xmldecl, :comment
      #
      # There is an additional symbol that can be listened for: :progress.
      # This will be called for every event generated, passing in the current 
      # stream position.
			#
			# Array contains regular expressions or strings which will be matched
			# against fully qualified element names.
			#
			# Listener must implement the methods in SAX2Listener
			#
			# Block will be passed the same arguments as a SAX2Listener method would
			# be, where the method name is the same as the matched Symbol.
			# See the SAX2Listener for more information.
			def listen( *args, &blok )
				if args[0].kind_of? Symbol
					if args.size == 2
						args[1].each { |match| @procs << [args[0], match, blok] }
					else
						add( [args[0], nil, blok] )
					end
				elsif args[0].kind_of? Array
					if args.size == 2
						args[0].each { |match| add( [nil, match, args[1]] ) }
					else
						args[0].each { |match| add( [ :start_element, match, blok ] ) }
					end
				else
					add([nil, nil, args[0]])
				end
			end
			
			def deafen( listener=nil, &blok )
				if listener
					@listeners.delete_if {|item| item[-1] == listener }
					@has_listeners = false if @listeners.size == 0
				else
					@procs.delete_if {|item| item[-1] == blok }
				end
			end
			
			def parse
				@procs.each { |sym,match,block| block.call if sym == :start_document }
				@listeners.each { |sym,match,block| 
					block.start_document if sym == :start_document or sym.nil?
				}
				root = context = []
				while true
					event = @parser.pull
					case event[0]
					when :end_document
						handle( :end_document )
						break
          when :start_doctype
            handle( :doctype, *event[1..-1])
					when :end_doctype
						context = context[1]
					when :start_element
						@tag_stack.push(event[1])
						# find the observers for namespaces
						procs = get_procs( :start_prefix_mapping, event[1] )
						listeners = get_listeners( :start_prefix_mapping, event[1] )
						if procs or listeners
							# break out the namespace declarations
							# The attributes live in event[2]
							event[2].each {|n, v| event[2][n] = @parser.normalize(v)}
							nsdecl = event[2].find_all { |n, value| n =~ /^xmlns(:|$)/ }
							nsdecl.collect! { |n, value| [ n[6..-1], value ] }
							@namespace_stack.push({})
							nsdecl.each do |n,v|
								@namespace_stack[-1][n] = v
								# notify observers of namespaces
								procs.each { |ob| ob.call( n, v ) } if procs
								listeners.each { |ob| ob.start_prefix_mapping(n, v) } if listeners
							end
						end
						event[1] =~ Namespace::NAMESPLIT
						prefix = $1
						local = $2
						uri = get_namespace(prefix)
						# find the observers for start_element
						procs = get_procs( :start_element, event[1] )
						listeners = get_listeners( :start_element, event[1] )
						# notify observers
						procs.each { |ob| ob.call( uri, local, event[1], event[2] ) } if procs
						listeners.each { |ob| 
							ob.start_element( uri, local, event[1], event[2] ) 
						} if listeners
					when :end_element
						@tag_stack.pop
						event[1] =~ Namespace::NAMESPLIT
						prefix = $1
						local = $2
						uri = get_namespace(prefix)
						# find the observers for start_element
						procs = get_procs( :end_element, event[1] )
						listeners = get_listeners( :end_element, event[1] )
						# notify observers
						procs.each { |ob| ob.call( uri, local, event[1] ) } if procs
						listeners.each { |ob| 
							ob.end_element( uri, local, event[1] ) 
						} if listeners

						namespace_mapping = @namespace_stack.pop
						# find the observers for namespaces
						procs = get_procs( :end_prefix_mapping, event[1] )
						listeners = get_listeners( :end_prefix_mapping, event[1] )
						if procs or listeners
							namespace_mapping.each do |prefix, uri|
								# notify observers of namespaces
								procs.each { |ob| ob.call( prefix ) } if procs
								listeners.each { |ob| ob.end_prefix_mapping(prefix) } if listeners
							end
						end
					when :text
            #normalized = @parser.normalize( event[1] )
            #handle( :characters, normalized )
            copy = event[1].clone
            @entities.each { |key, value| copy = copy.gsub("&#{key};", value) }
            copy.gsub!( Text::NUMERICENTITY ) {|m|
              m=$1
              m = "0#{m}" if m[0] == ?x
              [Integer(m)].pack('U*')
            }
            handle( :characters, copy )
          when :entitydecl
            @entities[ event[1] ] = event[2] if event.size == 3
						handle( *event )
					when :processing_instruction, :comment, :attlistdecl, 
						:elementdecl, :cdata, :notationdecl, :xmldecl
						handle( *event )
					end
          handle( :progress, @parser.position )
				end
			end

			private
			def handle( symbol, *arguments )
				tag = @tag_stack[-1]
				procs = get_procs( symbol, tag )
				listeners = get_listeners( symbol, tag )
				# notify observers
				procs.each { |ob| ob.call( *arguments ) } if procs
				listeners.each { |l| 
					l.send( symbol.to_s, *arguments ) 
				} if listeners
			end

			# The following methods are duplicates, but it is faster than using
			# a helper
			def get_procs( symbol, name )
				return nil if @procs.size == 0
				@procs.find_all do |sym, match, block|
          #puts sym.inspect+"=="+symbol.inspect+ "\t"+match.inspect+"=="+name.inspect+ "\t"+( (sym.nil? or symbol == sym) and ((name.nil? and match.nil?) or match.nil? or ( (name == match) or (match.kind_of? Regexp and name =~ match)))).to_s
					(
						(sym.nil? or symbol == sym) and 
						((name.nil? and match.nil?) or match.nil? or (
							(name == match) or
							(match.kind_of? Regexp and name =~ match)
							)
						)
					)
				end.collect{|x| x[-1]}
			end
			def get_listeners( symbol, name )
				return nil if @listeners.size == 0
				@listeners.find_all do |sym, match, block|
					(
						(sym.nil? or symbol == sym) and 
						((name.nil? and match.nil?) or match.nil? or (
							(name == match) or
							(match.kind_of? Regexp and name =~ match)
							)
						)
					)
				end.collect{|x| x[-1]}
			end

			def add( pair )
				if pair[-1].respond_to? :call
					@procs << pair unless @procs.include? pair
				else
					@listeners << pair unless @listeners.include? pair
					@has_listeners = true
				end
			end

			def get_namespace( prefix ) 
        uris = (@namespace_stack.find_all { |ns| not ns[prefix].nil? }) ||
					(@namespace_stack.find { |ns| not ns[nil].nil? })
				uris[-1][prefix] unless uris.nil? or 0 == uris.size
			end
		end
	end
end
PK     Y\L  L    rexml/parsers/xpathparser.rbnu [        require 'rexml/namespace'
require 'rexml/xmltokens'

module REXML
  module Parsers
    # You don't want to use this class.  Really.  Use XPath, which is a wrapper
    # for this class.  Believe me.  You don't want to poke around in here.
    # There is strange, dark magic at work in this code.  Beware.  Go back!  Go
    # back while you still can!
    class XPathParser
      include XMLTokens
      LITERAL    = /^'([^']*)'|^"([^"]*)"/u

      def namespaces=( namespaces )
        Functions::namespace_context = namespaces
        @namespaces = namespaces
      end

      def parse path
        path.gsub!(/([\(\[])\s+/, '\1') # Strip ignorable spaces
        path.gsub!( /\s+([\]\)])/, '\1' )
        parsed = []
        path = OrExpr(path, parsed)
        parsed
      end

      def predicate path
        parsed = []
        Predicate( "[#{path}]", parsed )
        parsed
      end

      def abbreviate( path )
        path = path.kind_of?(String) ? parse( path ) : path
        string = ""
        document = false
        while path.size > 0
          op = path.shift
          case op
          when :node
          when :attribute
						string << "/" if string.size > 0
						string << "@"
          when :child
						string << "/" if string.size > 0
          when :descendant_or_self
            string << "/"
          when :self
            string << "."
          when :parent
            string << ".."
          when :any
            string << "*"
					when :text
						string << "text()"
          when :following, :following_sibling, 
                :ancestor, :ancestor_or_self, :descendant, 
                :namespace, :preceding, :preceding_sibling
            string << "/" unless string.size == 0
            string << op.to_s.tr("_", "-")
            string << "::"
          when :qname
            prefix = path.shift
            name = path.shift
            string << prefix+":" if prefix.size > 0
            string << name
          when :predicate
            string << '['
            string << predicate_to_string( path.shift ) {|x| abbreviate( x ) }
            string << ']'
          when :document
            document = true
					when :function
						string << path.shift
						string << "( "
						string << predicate_to_string( path.shift[0] ) {|x| abbreviate( x )}
						string << " )"
					when :literal
						string << %Q{ "#{path.shift}" }
          else
            string << "/" unless string.size == 0
            string << "UNKNOWN("
            string << op.inspect
            string << ")"
          end
        end
				string = "/"+string if document
        return string
      end

      def expand( path )
        path = path.kind_of?(String) ? parse( path ) : path
        string = ""
        document = false
        while path.size > 0
          op = path.shift
          case op
          when :node
            string << "node()"
          when :attribute, :child, :following, :following_sibling, 
                :ancestor, :ancestor_or_self, :descendant, :descendant_or_self,
                :namespace, :preceding, :preceding_sibling, :self, :parent
            string << "/" unless string.size == 0
            string << op.to_s.tr("_", "-")
            string << "::"
          when :any
            string << "*"
          when :qname
            prefix = path.shift
            name = path.shift
            string << prefix+":" if prefix.size > 0
            string << name
          when :predicate
            string << '['
            string << predicate_to_string( path.shift ) { |x| expand(x) }
            string << ']'
          when :document
            document = true
          else
            string << "/" unless string.size == 0
            string << "UNKNOWN("
            string << op.inspect
            string << ")"
          end
        end
        string = "/"+string if document
        return string
      end

      def predicate_to_string( path, &block )
        string = ""
        case path[0]
        when :and, :or, :mult, :plus, :minus, :neq, :eq, :lt, :gt, :lteq, :gteq, :div, :mod, :union
          op = path.shift
          case op
          when :eq
            op = "="
          when :lt
            op = "<"
          when :gt
            op = ">"
          when :lteq
            op = "<="
          when :gteq
            op = ">="
          when :neq
            op = "!="
          when :union
            op = "|"
          end
          left = predicate_to_string( path.shift, &block )
          right = predicate_to_string( path.shift, &block )
          string << " "
          string << left
          string << " "
          string << op.to_s
          string << " "
          string << right
          string << " "
        when :function
          path.shift
          name = path.shift
          string << name
          string << "( "
          string << predicate_to_string( path.shift, &block )
          string << " )"
        when :literal
          path.shift
          string << " "
          string << path.shift.inspect
          string << " "
        else
          string << " "
          string << yield( path )
          string << " "
        end
        return string.squeeze(" ")
      end

      private
      #LocationPath
      #  | RelativeLocationPath
      #  | '/' RelativeLocationPath?
      #  | '//' RelativeLocationPath
      def LocationPath path, parsed
        #puts "LocationPath '#{path}'"
        path = path.strip
        if path[0] == ?/
          parsed << :document
          if path[1] == ?/
            parsed << :descendant_or_self
            parsed << :node
            path = path[2..-1]
          else
            path = path[1..-1]
          end
        end
        #puts parsed.inspect
        return RelativeLocationPath( path, parsed ) if path.size > 0
      end

      #RelativeLocationPath
      #  |                                                    Step
      #    | (AXIS_NAME '::' | '@' | '')                     AxisSpecifier
      #      NodeTest
      #        Predicate
      #    | '.' | '..'                                      AbbreviatedStep
      #  |  RelativeLocationPath '/' Step
      #  | RelativeLocationPath '//' Step
      AXIS = /^(ancestor|ancestor-or-self|attribute|child|descendant|descendant-or-self|following|following-sibling|namespace|parent|preceding|preceding-sibling|self)::/
      def RelativeLocationPath path, parsed
        #puts "RelativeLocationPath #{path}"
        while path.size > 0
          # (axis or @ or <child::>) nodetest predicate  >
          # OR                                          >  / Step
          # (. or ..)                                    >
          if path[0] == ?.
            if path[1] == ?.
              parsed << :parent
              parsed << :node
              path = path[2..-1]
            else
              parsed << :self
              parsed << :node
              path = path[1..-1]
            end
          else
            if path[0] == ?@
              #puts "ATTRIBUTE"
              parsed << :attribute
              path = path[1..-1]
              # Goto Nodetest
            elsif path =~ AXIS
              parsed << $1.tr('-','_').intern
              path = $'
              # Goto Nodetest
            else
              parsed << :child
            end

            #puts "NODETESTING '#{path}'"
            n = []
            path = NodeTest( path, n)
            #puts "NODETEST RETURNED '#{path}'"

            if path[0] == ?[
              path = Predicate( path, n )
            end

            parsed.concat(n)
          end
          
          if path.size > 0
            if path[0] == ?/
              if path[1] == ?/
                parsed << :descendant_or_self
                parsed << :node
                path = path[2..-1]
              else
                path = path[1..-1]
              end
            else
              return path
            end
          end
        end
        return path
      end

      # Returns a 1-1 map of the nodeset
      # The contents of the resulting array are either:
      #   true/false, if a positive match
      #   String, if a name match
      #NodeTest
      #  | ('*' | NCNAME ':' '*' | QNAME)                NameTest
      #  | NODE_TYPE '(' ')'                              NodeType
      #  | PI '(' LITERAL ')'                            PI
      #    | '[' expr ']'                                Predicate
      NCNAMETEST= /^(#{NCNAME_STR}):\*/u
      QNAME     = Namespace::NAMESPLIT
      NODE_TYPE  = /^(comment|text|node)\(\s*\)/m
      PI        = /^processing-instruction\(/
      def NodeTest path, parsed
        #puts "NodeTest with #{path}"
        res = nil
        case path
        when /^\*/
          path = $'
          parsed << :any
        when NODE_TYPE
          type = $1
          path = $'
          parsed << type.tr('-', '_').intern
        when PI
          path = $'
          literal = nil
          if path !~ /^\s*\)/
            path =~ LITERAL
            literal = $1
            path = $'
            raise ParseException.new("Missing ')' after processing instruction") if path[0] != ?)
            path = path[1..-1]
          end
          parsed << :processing_instruction
          parsed << (literal || '')
        when NCNAMETEST
          #puts "NCNAMETEST"
          prefix = $1
          path = $'
          parsed << :namespace
          parsed << prefix
        when QNAME
          #puts "QNAME"
          prefix = $1
          name = $2
          path = $'
          prefix = "" unless prefix
          parsed << :qname
          parsed << prefix
          parsed << name
        end
        return path
      end

      # Filters the supplied nodeset on the predicate(s)
      def Predicate path, parsed
        #puts "PREDICATE with #{path}"
        return nil unless path[0] == ?[
        predicates = []
        while path[0] == ?[
          path, expr = get_group(path)
          predicates << expr[1..-2] if expr
        end
        #puts "PREDICATES = #{predicates.inspect}"
        predicates.each{ |expr| 
          #puts "ORING #{expr}"
          preds = []
          parsed << :predicate
          parsed << preds
          OrExpr(expr, preds) 
        }
        #puts "PREDICATES = #{predicates.inspect}"
        path
      end

      # The following return arrays of true/false, a 1-1 mapping of the
      # supplied nodeset, except for axe(), which returns a filtered
      # nodeset

      #| OrExpr S 'or' S AndExpr
      #| AndExpr
      def OrExpr path, parsed
        #puts "OR >>> #{path}"
        n = []
        rest = AndExpr( path, n )
        #puts "OR <<< #{rest}"
        if rest != path
          while rest =~ /^\s*( or )/
            n = [ :or, n, [] ]
            rest = AndExpr( $', n[-1] )
          end
        end
        if parsed.size == 0 and n.size != 0
          parsed.replace(n)
        elsif n.size > 0
          parsed << n
        end
        rest
      end

      #| AndExpr S 'and' S EqualityExpr
      #| EqualityExpr
      def AndExpr path, parsed
        #puts "AND >>> #{path}"
        n = []
        rest = EqualityExpr( path, n )
        #puts "AND <<< #{rest}"
        if rest != path
          while rest =~ /^\s*( and )/
            n = [ :and, n, [] ]
            #puts "AND >>> #{rest}"
            rest = EqualityExpr( $', n[-1] )
            #puts "AND <<< #{rest}"
          end
        end
        if parsed.size == 0 and n.size != 0
          parsed.replace(n)
        elsif n.size > 0
          parsed << n
        end
        rest
      end

      #| EqualityExpr ('=' | '!=')  RelationalExpr
      #| RelationalExpr
      def EqualityExpr path, parsed
        #puts "EQUALITY >>> #{path}"
        n = []
        rest = RelationalExpr( path, n )
        #puts "EQUALITY <<< #{rest}"
        if rest != path
          while rest =~ /^\s*(!?=)\s*/
            if $1[0] == ?!
              n = [ :neq, n, [] ]
            else
              n = [ :eq, n, [] ]
            end
            rest = RelationalExpr( $', n[-1] )
          end
        end
        if parsed.size == 0 and n.size != 0
          parsed.replace(n)
        elsif n.size > 0
          parsed << n
        end
        rest
      end

      #| RelationalExpr ('<' | '>' | '<=' | '>=') AdditiveExpr
      #| AdditiveExpr
      def RelationalExpr path, parsed
        #puts "RELATION >>> #{path}"
        n = []
        rest = AdditiveExpr( path, n )
        #puts "RELATION <<< #{rest}"
        if rest != path
          while rest =~ /^\s*([<>]=?)\s*/
            if $1[0] == ?<
              sym = "lt"
            else
              sym = "gt"
            end
            sym << "eq" if $1[-1] == ?=
            n = [ sym.intern, n, [] ]
            rest = AdditiveExpr( $', n[-1] )
          end
        end
        if parsed.size == 0 and n.size != 0
          parsed.replace(n)
        elsif n.size > 0
          parsed << n
        end
        rest
      end

      #| AdditiveExpr ('+' | S '-') MultiplicativeExpr
      #| MultiplicativeExpr
      def AdditiveExpr path, parsed
        #puts "ADDITIVE >>> #{path}"
        n = []
        rest = MultiplicativeExpr( path, n )
        #puts "ADDITIVE <<< #{rest}"
        if rest != path
          while rest =~ /^\s*(\+| -)\s*/
            if $1[0] == ?+
              n = [ :plus, n, [] ]
            else
              n = [ :minus, n, [] ]
            end
            rest = MultiplicativeExpr( $', n[-1] )
          end
        end
        if parsed.size == 0 and n.size != 0
          parsed.replace(n)
        elsif n.size > 0
          parsed << n
        end
        rest
      end

      #| MultiplicativeExpr ('*' | S ('div' | 'mod') S) UnaryExpr
      #| UnaryExpr
      def MultiplicativeExpr path, parsed
        #puts "MULT >>> #{path}"
        n = []
        rest = UnaryExpr( path, n )
        #puts "MULT <<< #{rest}"
        if rest != path
          while rest =~ /^\s*(\*| div | mod )\s*/
            if $1[0] == ?*
              n = [ :mult, n, [] ]
            elsif $1.include?( "div" )
              n = [ :div, n, [] ]
            else
              n = [ :mod, n, [] ]
            end
            rest = UnaryExpr( $', n[-1] )
          end
        end
        if parsed.size == 0 and n.size != 0
          parsed.replace(n)
        elsif n.size > 0
          parsed << n
        end
        rest
      end

      #| '-' UnaryExpr
      #| UnionExpr
      def UnaryExpr path, parsed
        path =~ /^(\-*)/
        path = $'
        if $1 and (($1.size % 2) != 0)
          mult = -1
        else
          mult = 1
        end
        parsed << :neg if mult < 0

        #puts "UNARY >>> #{path}"
        n = []
        path = UnionExpr( path, n )
        #puts "UNARY <<< #{path}"
        parsed.concat( n )
        path
      end

      #| UnionExpr '|' PathExpr
      #| PathExpr
      def UnionExpr path, parsed
        #puts "UNION >>> #{path}"
        n = []
        rest = PathExpr( path, n )
        #puts "UNION <<< #{rest}"
        if rest != path
          while rest =~ /^\s*(\|)\s*/
            n = [ :union, n, [] ]
            rest = PathExpr( $', n[-1] )
          end
        end
        if parsed.size == 0 and n.size != 0
          parsed.replace( n )
        elsif n.size > 0
          parsed << n
        end
        rest
      end

      #| LocationPath
      #| FilterExpr ('/' | '//') RelativeLocationPath
      def PathExpr path, parsed
        path =~ /^\s*/
        path = $'
        #puts "PATH >>> #{path}"
        n = []
        rest = FilterExpr( path, n )
        #puts "PATH <<< '#{rest}'"
        if rest != path
          if rest and rest[0] == ?/
            return RelativeLocationPath(rest, n)
          end
        end
        #puts "BEFORE WITH '#{rest}'"
        rest = LocationPath(rest, n) if rest =~ /\A[\/\.\@\[\w_*]/
        parsed.concat(n)
        return rest
      end

      #| FilterExpr Predicate
      #| PrimaryExpr
      def FilterExpr path, parsed
        #puts "FILTER >>> #{path}"
        n = []
        path = PrimaryExpr( path, n )
        #puts "FILTER <<< #{path}"
        path = Predicate(path, n) if path and path[0] == ?[
        #puts "FILTER <<< #{path}"
        parsed.concat(n)
        path
      end

      #| VARIABLE_REFERENCE
      #| '(' expr ')'
      #| LITERAL
      #| NUMBER
      #| FunctionCall
      VARIABLE_REFERENCE  = /^\$(#{NAME_STR})/u
      NUMBER              = /^(\d*\.?\d+)/
      NT        = /^comment|text|processing-instruction|node$/
      def PrimaryExpr path, parsed
        arry = []
        case path
        when VARIABLE_REFERENCE
          varname = $1
          path = $'
          parsed << :variable
          parsed << varname
          #arry << @variables[ varname ]
        when /^(\w[-\w]*)(?:\()/
          #puts "PrimaryExpr :: Function >>> #$1 -- '#$''"
          fname = $1
          tmp = $'
          #puts "#{fname} =~ #{NT.inspect}"
          return path if fname =~ NT
          path = tmp
          parsed << :function
          parsed << fname
          path = FunctionCall(path, parsed)
        when NUMBER
          #puts "LITERAL or NUMBER: #$1"
          varname = $1.nil? ? $2 : $1
          path = $'
          parsed << :literal 
          parsed << (varname.include?('.') ? varname.to_f : varname.to_i)
        when LITERAL
          #puts "LITERAL or NUMBER: #$1"
          varname = $1.nil? ? $2 : $1
          path = $'
          parsed << :literal 
          parsed << varname
        when /^\(/                                               #/
          path, contents = get_group(path)
          contents = contents[1..-2]
          n = []
          OrExpr( contents, n )
          parsed.concat(n)
        end
        path
      end

      #| FUNCTION_NAME '(' ( expr ( ',' expr )* )? ')'
      def FunctionCall rest, parsed
        path, arguments = parse_args(rest)
        argset = []
        for argument in arguments
          args = []
          OrExpr( argument, args )
          argset << args
        end
        parsed << argset
        path
      end

      # get_group( '[foo]bar' ) -> ['bar', '[foo]']
      def get_group string
        ind = 0
        depth = 0
        st = string[0,1]
        en = (st == "(" ? ")" : "]")
        begin
          case string[ind,1]
          when st
            depth += 1
          when en
            depth -= 1
          end
          ind += 1
        end while depth > 0 and ind < string.length
        return nil unless depth==0
        [string[ind..-1], string[0..ind-1]]
      end
      
      def parse_args( string )
        arguments = []
        ind = 0
				inquot = false
				inapos = false
        depth = 1
        begin
          case string[ind]
          when ?"
          	inquot = !inquot unless inapos
          when ?'
          	inapos = !inapos unless inquot
          else
          	unless inquot or inapos
          		case string[ind]
							when ?(
								depth += 1
                if depth == 1
                	string = string[1..-1]
                	ind -= 1
                end
							when ?)
								depth -= 1
								if depth == 0
									s = string[0,ind].strip
									arguments << s unless s == ""
									string = string[ind+1..-1]
								end
							when ?,
								if depth == 1
									s = string[0,ind].strip
									arguments << s unless s == ""
									string = string[ind+1..-1]
									ind = -1 
								end
							end
            end
          end
          ind += 1
        end while depth > 0 and ind < string.length
        return nil unless depth==0
        [string,arguments]
      end
    end
  end
end
PK     Y\UHJ  J    rexml/parsers/baseparser.rbnu [        require 'rexml/parseexception'
require 'rexml/undefinednamespaceexception'
require 'rexml/source'
require 'set'

module REXML
  module Parsers
    # = Using the Pull Parser
    # <em>This API is experimental, and subject to change.</em>
    #  parser = PullParser.new( "<a>text<b att='val'/>txet</a>" )
    #  while parser.has_next?
    #    res = parser.next
    #    puts res[1]['att'] if res.start_tag? and res[0] == 'b'
    #  end
    # See the PullEvent class for information on the content of the results.
    # The data is identical to the arguments passed for the various events to
    # the StreamListener API.
    #
    # Notice that:
    #  parser = PullParser.new( "<a>BAD DOCUMENT" )
    #  while parser.has_next?
    #    res = parser.next
    #    raise res[1] if res.error?
    #  end
    #
    # Nat Price gave me some good ideas for the API.
    class BaseParser
      NCNAME_STR= '[\w:][\-\w\d.]*'
      NAME_STR= "(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})"
      UNAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}"

      NAMECHAR = '[\-\w\d\.:]'
      NAME = "([\\w:]#{NAMECHAR}*)"
      NMTOKEN = "(?:#{NAMECHAR})+"
      NMTOKENS = "#{NMTOKEN}(\\s+#{NMTOKEN})*"
      REFERENCE = "(?:&#{NAME};|&#\\d+;|&#x[0-9a-fA-F]+;)"
      REFERENCE_RE = /#{REFERENCE}/

      DOCTYPE_START = /\A\s*<!DOCTYPE\s/um
      DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/um
      ATTRIBUTE_PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\4/um
      COMMENT_START = /\A<!--/u
      COMMENT_PATTERN = /<!--(.*?)-->/um
      CDATA_START = /\A<!\[CDATA\[/u
      CDATA_END = /^\s*\]\s*>/um
      CDATA_PATTERN = /<!\[CDATA\[(.*?)\]\]>/um
      XMLDECL_START = /\A<\?xml\s/u;
      XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>/um
      INSTRUCTION_START = /\A<\?/u
      INSTRUCTION_PATTERN = /<\?(.*?)(\s+.*?)?\?>/um
      TAG_MATCH = /^<((?>#{NAME_STR}))\s*((?>\s+#{UNAME_STR}\s*=\s*(["']).*?\5)*)\s*(\/)?>/um
      CLOSE_MATCH = /^\s*<\/(#{NAME_STR})\s*>/um

      VERSION = /\bversion\s*=\s*["'](.*?)['"]/um
      ENCODING = /\bencoding\s*=\s*["'](.*?)['"]/um
      STANDALONE = /\bstandalone\s*=\s["'](.*?)['"]/um

      ENTITY_START = /^\s*<!ENTITY/
      IDENTITY = /^([!\*\w\-]+)(\s+#{NCNAME_STR})?(\s+["'](.*?)['"])?(\s+['"](.*?)["'])?/u
      ELEMENTDECL_START = /^\s*<!ELEMENT/um
      ELEMENTDECL_PATTERN = /^\s*(<!ELEMENT.*?)>/um
      SYSTEMENTITY = /^\s*(%.*?;)\s*$/um
      ENUMERATION = "\\(\\s*#{NMTOKEN}(?:\\s*\\|\\s*#{NMTOKEN})*\\s*\\)"
      NOTATIONTYPE = "NOTATION\\s+\\(\\s*#{NAME}(?:\\s*\\|\\s*#{NAME})*\\s*\\)"
      ENUMERATEDTYPE = "(?:(?:#{NOTATIONTYPE})|(?:#{ENUMERATION}))"
      ATTTYPE = "(CDATA|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS|#{ENUMERATEDTYPE})"
      ATTVALUE = "(?:\"((?:[^<&\"]|#{REFERENCE})*)\")|(?:'((?:[^<&']|#{REFERENCE})*)')"
      DEFAULTDECL = "(#REQUIRED|#IMPLIED|(?:(#FIXED\\s+)?#{ATTVALUE}))"
      ATTDEF = "\\s+#{NAME}\\s+#{ATTTYPE}\\s+#{DEFAULTDECL}"
      ATTDEF_RE = /#{ATTDEF}/
      ATTLISTDECL_START = /^\s*<!ATTLIST/um
      ATTLISTDECL_PATTERN = /^\s*<!ATTLIST\s+#{NAME}(?:#{ATTDEF})*\s*>/um
      NOTATIONDECL_START = /^\s*<!NOTATION/um
      PUBLIC = /^\s*<!NOTATION\s+(\w[\-\w]*)\s+(PUBLIC)\s+(["'])(.*?)\3(?:\s+(["'])(.*?)\5)?\s*>/um
      SYSTEM = /^\s*<!NOTATION\s+(\w[\-\w]*)\s+(SYSTEM)\s+(["'])(.*?)\3\s*>/um

      TEXT_PATTERN = /\A([^<]*)/um

      # Entity constants
      PUBIDCHAR = "\x20\x0D\x0Aa-zA-Z0-9\\-()+,./:=?;!*@$_%#"
      SYSTEMLITERAL = %Q{((?:"[^"]*")|(?:'[^']*'))}
      PUBIDLITERAL = %Q{("[#{PUBIDCHAR}']*"|'[#{PUBIDCHAR}]*')}
      EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))"
      NDATADECL = "\\s+NDATA\\s+#{NAME}"
      PEREFERENCE = "%#{NAME};"
      ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))}
      PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})"
      ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))"
      PEDECL = "<!ENTITY\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>"
      GEDECL = "<!ENTITY\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>"
      ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um

      EREFERENCE = /&(?!#{NAME};)/

      DEFAULT_ENTITIES = { 
        'gt' => [/&gt;/, '&gt;', '>', />/], 
        'lt' => [/&lt;/, '&lt;', '<', /</], 
        'quot' => [/&quot;/, '&quot;', '"', /"/], 
        "apos" => [/&apos;/, "&apos;", "'", /'/] 
      }


      ######################################################################
      # These are patterns to identify common markup errors, to make the
      # error messages more informative.
      ######################################################################
      MISSING_ATTRIBUTE_QUOTES = /^<#{NAME_STR}\s+#{NAME_STR}\s*=\s*[^"']/um

      def initialize( source )
        self.stream = source
      end

      def add_listener( listener )
        if !defined?(@listeners) or !@listeners
          @listeners = []
          instance_eval <<-EOL
            alias :_old_pull :pull
            def pull
              event = _old_pull
              @listeners.each do |listener|
                listener.receive event
              end
              event
            end
          EOL
        end
        @listeners << listener
      end

      attr_reader :source

      def stream=( source )
        @source = SourceFactory.create_from( source )
        @closed = nil
        @document_status = nil
        @tags = []
        @stack = []
        @entities = []
        @nsstack = []
      end

      def position
        if @source.respond_to? :position
          @source.position
        else
          # FIXME
          0
        end
      end

      # Returns true if there are no more events
      def empty?
        return (@source.empty? and @stack.empty?)
      end

      # Returns true if there are more events.  Synonymous with !empty?
      def has_next?
        return !(@source.empty? and @stack.empty?)
      end

      # Push an event back on the head of the stream.  This method
      # has (theoretically) infinite depth.
      def unshift token
        @stack.unshift(token)
      end

      # Peek at the +depth+ event in the stack.  The first element on the stack
      # is at depth 0.  If +depth+ is -1, will parse to the end of the input
      # stream and return the last event, which is always :end_document.
      # Be aware that this causes the stream to be parsed up to the +depth+ 
      # event, so you can effectively pre-parse the entire document (pull the 
      # entire thing into memory) using this method.  
      def peek depth=0
        raise %Q[Illegal argument "#{depth}"] if depth < -1
        temp = []
        if depth == -1
          temp.push(pull()) until empty?
        else
          while @stack.size+temp.size < depth+1
            temp.push(pull())
          end
        end
        @stack += temp if temp.size > 0
        @stack[depth]
      end

      # Returns the next event.  This is a +PullEvent+ object.
      def pull
        if @closed
          x, @closed = @closed, nil
          return [ :end_element, x ]
        end
        return [ :end_document ] if empty?
        return @stack.shift if @stack.size > 0
        #STDERR.puts @source.encoding
        @source.read if @source.buffer.size<2
        #STDERR.puts "BUFFER = #{@source.buffer.inspect}"
        if @document_status == nil
          #@source.consume( /^\s*/um )
          word = @source.match( /^((?:\s+)|(?:<[^>]*>))/um )
          word = word[1] unless word.nil?
          #STDERR.puts "WORD = #{word.inspect}"
          case word
          when COMMENT_START
            return [ :comment, @source.match( COMMENT_PATTERN, true )[1] ]
          when XMLDECL_START
            #STDERR.puts "XMLDECL"
            results = @source.match( XMLDECL_PATTERN, true )[1]
            version = VERSION.match( results )
            version = version[1] unless version.nil?
            encoding = ENCODING.match(results)
            encoding = encoding[1] unless encoding.nil?
            @source.encoding = encoding
            standalone = STANDALONE.match(results)
            standalone = standalone[1] unless standalone.nil?
            return [ :xmldecl, version, encoding, standalone ]
          when INSTRUCTION_START
            return [ :processing_instruction, *@source.match(INSTRUCTION_PATTERN, true)[1,2] ]
          when DOCTYPE_START
            md = @source.match( DOCTYPE_PATTERN, true )
            @nsstack.unshift(curr_ns=Set.new)
            identity = md[1]
            close = md[2]
            identity =~ IDENTITY
            name = $1
            raise REXML::ParseException.new("DOCTYPE is missing a name") if name.nil?
            pub_sys = $2.nil? ? nil : $2.strip
            long_name = $4.nil? ? nil : $4.strip
            uri = $6.nil? ? nil : $6.strip
            args = [ :start_doctype, name, pub_sys, long_name, uri ]
            if close == ">"
              @document_status = :after_doctype
              @source.read if @source.buffer.size<2
              md = @source.match(/^\s*/um, true)
              @stack << [ :end_doctype ]
            else
              @document_status = :in_doctype
            end
            return args
          when /^\s+/
          else
            @document_status = :after_doctype
            @source.read if @source.buffer.size<2
            md = @source.match(/\s*/um, true)
          end
        end
        if @document_status == :in_doctype
          md = @source.match(/\s*(.*?>)/um)
          case md[1]
          when SYSTEMENTITY 
            match = @source.match( SYSTEMENTITY, true )[1]
            return [ :externalentity, match ]

          when ELEMENTDECL_START
            return [ :elementdecl, @source.match( ELEMENTDECL_PATTERN, true )[1] ]

          when ENTITY_START
            match = @source.match( ENTITYDECL, true ).to_a.compact
            match[0] = :entitydecl
            ref = false
            if match[1] == '%'
              ref = true
              match.delete_at 1
            end
            # Now we have to sort out what kind of entity reference this is
            if match[2] == 'SYSTEM'
              # External reference
              match[3] = match[3][1..-2] # PUBID
              match.delete_at(4) if match.size > 4 # Chop out NDATA decl
              # match is [ :entity, name, SYSTEM, pubid(, ndata)? ]
            elsif match[2] == 'PUBLIC'
              # External reference
              match[3] = match[3][1..-2] # PUBID
              match[4] = match[4][1..-2] # HREF
              # match is [ :entity, name, PUBLIC, pubid, href ]
            else
              match[2] = match[2][1..-2]
              match.pop if match.size == 4
              # match is [ :entity, name, value ]
            end
            match << '%' if ref
            return match
          when ATTLISTDECL_START
            md = @source.match( ATTLISTDECL_PATTERN, true )
            raise REXML::ParseException.new( "Bad ATTLIST declaration!", @source ) if md.nil?
            element = md[1]
            contents = md[0]

            pairs = {}
            values = md[0].scan( ATTDEF_RE )
            values.each do |attdef|
              unless attdef[3] == "#IMPLIED"
                attdef.compact!
                val = attdef[3]
                val = attdef[4] if val == "#FIXED "
                pairs[attdef[0]] = val
                if attdef[0] =~ /^xmlns:(.*)/
                  @nsstack[0] << $1
                end
              end
            end
            return [ :attlistdecl, element, pairs, contents ]
          when NOTATIONDECL_START
            md = nil
            if @source.match( PUBLIC )
              md = @source.match( PUBLIC, true )
              vals = [md[1],md[2],md[4],md[6]]
            elsif @source.match( SYSTEM )
              md = @source.match( SYSTEM, true )
              vals = [md[1],md[2],nil,md[4]]
            else
              raise REXML::ParseException.new( "error parsing notation: no matching pattern", @source )
            end
            return [ :notationdecl, *vals ]
          when CDATA_END
            @document_status = :after_doctype
            @source.match( CDATA_END, true )
            return [ :end_doctype ]
          end
        end
        begin
          if @source.buffer[0] == ?<
            if @source.buffer[1] == ?/
              @nsstack.shift
              last_tag = @tags.pop
              #md = @source.match_to_consume( '>', CLOSE_MATCH)
              md = @source.match( CLOSE_MATCH, true )
              raise REXML::ParseException.new( "Missing end tag for "+
                "'#{last_tag}' (got \"#{md[1]}\")", 
                @source) unless last_tag == md[1]
              return [ :end_element, last_tag ]
            elsif @source.buffer[1] == ?!
              md = @source.match(/\A(\s*[^>]*>)/um)
              #STDERR.puts "SOURCE BUFFER = #{source.buffer}, #{source.buffer.size}"
              raise REXML::ParseException.new("Malformed node", @source) unless md
              if md[0][2] == ?-
                md = @source.match( COMMENT_PATTERN, true )
                return [ :comment, md[1] ] if md
              else
                md = @source.match( CDATA_PATTERN, true )
                return [ :cdata, md[1] ] if md
              end
              raise REXML::ParseException.new( "Declarations can only occur "+
                "in the doctype declaration.", @source)
            elsif @source.buffer[1] == ??
              md = @source.match( INSTRUCTION_PATTERN, true )
              return [ :processing_instruction, md[1], md[2] ] if md
              raise REXML::ParseException.new( "Bad instruction declaration",
                @source)
            else
              # Get the next tag
              md = @source.match(TAG_MATCH, true)
              unless md
                # Check for missing attribute quotes
                raise REXML::ParseException.new("missing attribute quote", @source) if @source.match(MISSING_ATTRIBUTE_QUOTES )
                raise REXML::ParseException.new("malformed XML: missing tag start", @source) 
              end
              attributes = {}
              prefixes = Set.new
              prefixes << md[2] if md[2]
              @nsstack.unshift(curr_ns=Set.new)
              if md[4].size > 0
                attrs = md[4].scan( ATTRIBUTE_PATTERN )
                raise REXML::ParseException.new( "error parsing attributes: [#{attrs.join ', '}], excess = \"#$'\"", @source) if $' and $'.strip.size > 0
                attrs.each { |a,b,c,d,e| 
                  if b == "xmlns"
                    if c == "xml"
                      if d != "http://www.w3.org/XML/1998/namespace"
                        msg = "The 'xml' prefix must not be bound to any other namespace "+
                        "(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
                        raise REXML::ParseException.new( msg, @source, self )
                      end
                    elsif c == "xmlns"
                      msg = "The 'xmlns' prefix must not be declared "+
                      "(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
                      raise REXML::ParseException.new( msg, @source, self)
                    end
                    curr_ns << c
                  elsif b
                    prefixes << b unless b == "xml"
                  end
                  attributes[a] = e 
                }
              end
        
              # Verify that all of the prefixes have been defined
              for prefix in prefixes
                unless @nsstack.find{|k| k.member?(prefix)}
                  raise UndefinedNamespaceException.new(prefix,@source,self)
                end
              end

              if md[6]
                @closed = md[1]
                @nsstack.shift
              else
                @tags.push( md[1] )
              end
              return [ :start_element, md[1], attributes ]
            end
          else
            md = @source.match( TEXT_PATTERN, true )
            if md[0].length == 0
              @source.match( /(\s+)/, true )
            end
            #STDERR.puts "GOT #{md[1].inspect}" unless md[0].length == 0
            #return [ :text, "" ] if md[0].length == 0
            # unnormalized = Text::unnormalize( md[1], self )
            # return PullEvent.new( :text, md[1], unnormalized )
            return [ :text, md[1] ]
          end
        rescue REXML::UndefinedNamespaceException
          raise
        rescue REXML::ParseException
          raise
        rescue Exception, NameError => error
          raise REXML::ParseException.new( "Exception parsing",
            @source, self, (error ? error : $!) )
        end
        return [ :dummy ]
      end

      def entity( reference, entities )
        value = nil
        value = entities[ reference ] if entities
        if not value
          value = DEFAULT_ENTITIES[ reference ]
          value = value[2] if value
        end
        unnormalize( value, entities ) if value
      end

      # Escapes all possible entities
      def normalize( input, entities=nil, entity_filter=nil )
        copy = input.clone
        # Doing it like this rather than in a loop improves the speed
        copy.gsub!( EREFERENCE, '&amp;' )
        entities.each do |key, value|
          copy.gsub!( value, "&#{key};" ) unless entity_filter and 
                                      entity_filter.include?(entity)
        end if entities
        copy.gsub!( EREFERENCE, '&amp;' )
        DEFAULT_ENTITIES.each do |key, value|
          copy.gsub!( value[3], value[1] )
        end
        copy
      end

      # Unescapes all possible entities
      def unnormalize( string, entities=nil, filter=nil )
        rv = string.clone
        rv.gsub!( /\r\n?/, "\n" )
        matches = rv.scan( REFERENCE_RE )
        return rv if matches.size == 0
        rv.gsub!( /&#0*((?:\d+)|(?:x[a-fA-F0-9]+));/ ) {|m|
          m=$1
          m = "0#{m}" if m[0] == ?x
          [Integer(m)].pack('U*')
        }
        matches.collect!{|x|x[0]}.compact!
        if matches.size > 0
          matches.each do |entity_reference|
            unless filter and filter.include?(entity_reference)
              entity_value = entity( entity_reference, entities )
              if entity_value
                re = /&#{entity_reference};/
                rv.gsub!( re, entity_value )
              end
            end
          end
          matches.each do |entity_reference|
            unless filter and filter.include?(entity_reference)
              er = DEFAULT_ENTITIES[entity_reference]
              rv.gsub!( er[0], er[2] ) if er
            end
          end
          rv.gsub!( /&amp;/, '&' )
        end
        rv
      end
    end
  end
end

=begin
  case event[0]
  when :start_element
  when :text
  when :end_element
  when :processing_instruction
  when :cdata
  when :comment
  when :xmldecl
  when :start_doctype
  when :end_doctype
  when :externalentity
  when :elementdecl
  when :entity
  when :attlistdecl
  when :notationdecl
  when :end_doctype
  end
=end
PK     Y\^=      rexml/parsers/streamparser.rbnu [        module REXML
  module Parsers
    class StreamParser
      def initialize source, listener
        @listener = listener
        @parser = BaseParser.new( source )
      end
      
      def add_listener( listener )
        @parser.add_listener( listener )
      end
      
      def parse
        # entity string
        while true
          event = @parser.pull
          case event[0]
          when :end_document
            return
          when :start_element
            attrs = event[2].each do |n, v|
              event[2][n] = @parser.unnormalize( v )
            end
            @listener.tag_start( event[1], attrs )
          when :end_element
            @listener.tag_end( event[1] )
          when :text
            normalized = @parser.unnormalize( event[1] )
            @listener.text( normalized )
          when :processing_instruction
            @listener.instruction( *event[1,2] )
          when :start_doctype
            @listener.doctype( *event[1..-1] )
          when :end_doctype
            # FIXME: remove this condition for milestone:3.2
            @listener.doctype_end if @listener.respond_to? :doctype_end
          when :comment, :attlistdecl, :cdata, :xmldecl, :elementdecl
            @listener.send( event[0].to_s, *event[1..-1] )
          when :entitydecl, :notationdecl
            @listener.send( event[0].to_s, event[1..-1] )
          end
        end
      end
    end
  end
end
PK     Y\@H    !  rexml/parsers/ultralightparser.rbnu [        require 'rexml/parsers/streamparser'
require 'rexml/parsers/baseparser'

module REXML
	module Parsers
		class UltraLightParser
			def initialize stream
				@stream = stream
				@parser = REXML::Parsers::BaseParser.new( stream )
			end

      def add_listener( listener )
        @parser.add_listener( listener )
      end

      def rewind
        @stream.rewind
        @parser.stream = @stream
      end

			def parse
				root = context = []
				while true
					event = @parser.pull
					case event[0]
					when :end_document
						break
					when :end_doctype
						context = context[1]
					when :start_element, :doctype
						context << event
						event[1,0] = [context]
						context = event
					when :end_element
						context = context[1]
					else
						context << event
					end
				end
				root
			end
		end

		# An element is an array.  The array contains:
		#  0			The parent element
		#  1			The tag name
		#  2			A hash of attributes
		#  3..-1	The child elements
		# An element is an array of size > 3
		# Text is a String
		# PIs are [ :processing_instruction, target, data ]
		# Comments are [ :comment, data ]
		# DocTypes are DocType structs
		# The root is an array with XMLDecls, Text, DocType, Array, Text
	end
end
PK     Y\廋z  z    rexml/parsers/treeparser.rbnu [        require 'rexml/validation/validationexception'
require 'rexml/undefinednamespaceexception'

module REXML
  module Parsers
    class TreeParser
      def initialize( source, build_context = Document.new )
        @build_context = build_context
        @parser = Parsers::BaseParser.new( source )
      end

      def add_listener( listener )
        @parser.add_listener( listener )
      end

      def parse
        tag_stack = []
        in_doctype = false
        entities = nil
        begin
          while true
            event = @parser.pull
            #STDERR.puts "TREEPARSER GOT #{event.inspect}"
            case event[0]
            when :end_document
              unless tag_stack.empty?
                #raise ParseException.new("No close tag for #{tag_stack.inspect}")
                raise ParseException.new("No close tag for #{@build_context.xpath}")
              end
              return
            when :start_element
              tag_stack.push(event[1])
              el = @build_context = @build_context.add_element( event[1], event[2] )
            when :end_element
              tag_stack.pop
              @build_context = @build_context.parent
            when :text
              if not in_doctype
                if @build_context[-1].instance_of? Text
                  @build_context[-1] << event[1]
                else
                  @build_context.add( 
                    Text.new(event[1], @build_context.whitespace, nil, true) 
                  ) unless (
                    @build_context.ignore_whitespace_nodes and
                    event[1].strip.size==0
                  )
                end
              end
            when :comment
              c = Comment.new( event[1] )
              @build_context.add( c )
            when :cdata
              c = CData.new( event[1] )
              @build_context.add( c )
            when :processing_instruction
              @build_context.add( Instruction.new( event[1], event[2] ) )
            when :end_doctype
              in_doctype = false
              entities.each { |k,v| entities[k] = @build_context.entities[k].value }
              @build_context = @build_context.parent
            when :start_doctype
              doctype = DocType.new( event[1..-1], @build_context )
              @build_context = doctype
              entities = {}
              in_doctype = true
            when :attlistdecl
              n = AttlistDecl.new( event[1..-1] )
              @build_context.add( n )
            when :externalentity
              n = ExternalEntity.new( event[1] )
              @build_context.add( n )
            when :elementdecl
              n = ElementDecl.new( event[1] )
              @build_context.add(n)
            when :entitydecl
              entities[ event[1] ] = event[2] unless event[2] =~ /PUBLIC|SYSTEM/
              @build_context.add(Entity.new(event))
            when :notationdecl
              n = NotationDecl.new( *event[1..-1] )
              @build_context.add( n )
            when :xmldecl
              x = XMLDecl.new( event[1], event[2], event[3] )
              @build_context.add( x )
            end
          end
        rescue REXML::Validation::ValidationException
          raise
        rescue REXML::UndefinedNamespaceException
          raise
        rescue
          raise ParseException.new( $!.message, @parser.source, @parser, $! )
        end
      end
    end
  end
end
PK     Y\l W  W    rexml/parsers/pullparser.rbnu [        require 'forwardable'

require 'rexml/parseexception'
require 'rexml/parsers/baseparser'
require 'rexml/xmltokens'

module REXML
  module Parsers
    # = Using the Pull Parser
    # <em>This API is experimental, and subject to change.</em>
    #  parser = PullParser.new( "<a>text<b att='val'/>txet</a>" )
    #  while parser.has_next?
    #    res = parser.next
    #    puts res[1]['att'] if res.start_tag? and res[0] == 'b'
    #  end
    # See the PullEvent class for information on the content of the results.
    # The data is identical to the arguments passed for the various events to
    # the StreamListener API.
    #
    # Notice that:
    #  parser = PullParser.new( "<a>BAD DOCUMENT" )
    #  while parser.has_next?
    #    res = parser.next
    #    raise res[1] if res.error?
    #  end
    #
    # Nat Price gave me some good ideas for the API.
    class PullParser
      include XMLTokens
      extend Forwardable

      def_delegators( :@parser, :has_next? )
      def_delegators( :@parser, :entity )
      def_delegators( :@parser, :empty? )
      def_delegators( :@parser, :source )

      def initialize stream
        @entities = {}
        @listeners = nil
        @parser = BaseParser.new( stream )
        @my_stack = []
      end

      def add_listener( listener )
        @listeners = [] unless @listeners
        @listeners << listener
      end

      def each
        while has_next?
          yield self.pull
        end
      end

      def peek depth=0
        if @my_stack.length <= depth
          (depth - @my_stack.length + 1).times {
            e = PullEvent.new(@parser.pull)
            @my_stack.push(e)
          }
        end
        @my_stack[depth]
      end

      def pull
        return @my_stack.shift if @my_stack.length > 0

        event = @parser.pull
        case event[0]
        when :entitydecl
          @entities[ event[1] ] = 
            event[2] unless event[2] =~ /PUBLIC|SYSTEM/
        when :text
          unnormalized = @parser.unnormalize( event[1], @entities )
          event << unnormalized
        end
        PullEvent.new( event )
      end

      def unshift token
        @my_stack.unshift token
      end
    end

    # A parsing event.  The contents of the event are accessed as an +Array?,
    # and the type is given either by the ...? methods, or by accessing the
    # +type+ accessor.  The contents of this object vary from event to event,
    # but are identical to the arguments passed to +StreamListener+s for each
    # event.
    class PullEvent
      # The type of this event.  Will be one of :tag_start, :tag_end, :text,
      # :processing_instruction, :comment, :doctype, :attlistdecl, :entitydecl,
      # :notationdecl, :entity, :cdata, :xmldecl, or :error.
      def initialize(arg)
        @contents = arg
      end

      def []( start, endd=nil)
        if start.kind_of? Range
          @contents.slice( start.begin+1 .. start.end )
        elsif start.kind_of? Numeric
          if endd.nil?
            @contents.slice( start+1 )
          else
            @contents.slice( start+1, endd )
          end
        else
          raise "Illegal argument #{start.inspect} (#{start.class})"
        end
      end

      def event_type
        @contents[0]
      end

      # Content: [ String tag_name, Hash attributes ]
      def start_element?
        @contents[0] == :start_element
      end

      # Content: [ String tag_name ]
      def end_element?
        @contents[0] == :end_element
      end

      # Content: [ String raw_text, String unnormalized_text ]
      def text?
        @contents[0] == :text
      end

      # Content: [ String text ]
      def instruction?
        @contents[0] == :processing_instruction
      end

      # Content: [ String text ]
      def comment?
        @contents[0] == :comment
      end

      # Content: [ String name, String pub_sys, String long_name, String uri ]
      def doctype?
        @contents[0] == :start_doctype
      end

      # Content: [ String text ]
      def attlistdecl?
        @contents[0] == :attlistdecl
      end

      # Content: [ String text ]
      def elementdecl?
        @contents[0] == :elementdecl
      end

      # Due to the wonders of DTDs, an entity declaration can be just about
      # anything.  There's no way to normalize it; you'll have to interpret the
      # content yourself.  However, the following is true:
      #
      # * If the entity declaration is an internal entity:
      #   [ String name, String value ]
      # Content: [ String text ]
      def entitydecl?
        @contents[0] == :entitydecl
      end

      # Content: [ String text ]
      def notationdecl?
        @contents[0] == :notationdecl
      end

      # Content: [ String text ]
      def entity?
        @contents[0] == :entity
      end

      # Content: [ String text ]
      def cdata?
        @contents[0] == :cdata
      end

      # Content: [ String version, String encoding, String standalone ]
      def xmldecl?
        @contents[0] == :xmldecl
      end

      def error?
        @contents[0] == :error
      end

      def inspect
        @contents[0].to_s + ": " + @contents[1..-1].inspect
      end
    end
  end
end
PK     Y\O"g  g    rexml/parsers/lightparser.rbnu [        require 'rexml/parsers/streamparser'
require 'rexml/parsers/baseparser'
require 'rexml/light/node'

module REXML
	module Parsers
		class LightParser
			def initialize stream
				@stream = stream
				@parser = REXML::Parsers::BaseParser.new( stream )
			end

      def add_listener( listener )
        @parser.add_listener( listener )
      end

      def rewind
        @stream.rewind
        @parser.stream = @stream
      end

			def parse
				root = context = [ :document ]
				while true
					event = @parser.pull
					case event[0]
					when :end_document
						break
					when :end_doctype
						context = context[1]
					when :start_element, :start_doctype
						new_node = event
						context << new_node
						new_node[1,0] = [context]
						context = new_node
					when :end_element, :end_doctype
						context = context[1]
					else
						new_node = event
						context << new_node
						new_node[1,0] = [context]
					end
				end
				root
			end
		end

		# An element is an array.  The array contains:
		#  0			The parent element
		#  1			The tag name
		#  2			A hash of attributes
		#  3..-1	The child elements
		# An element is an array of size > 3
		# Text is a String
		# PIs are [ :processing_instruction, target, data ]
		# Comments are [ :comment, data ]
		# DocTypes are DocType structs
		# The root is an array with XMLDecls, Text, DocType, Array, Text
	end
end
PK     Y\K7      rexml/document.rbnu [        require "rexml/element"
require "rexml/xmldecl"
require "rexml/source"
require "rexml/comment"
require "rexml/doctype"
require "rexml/instruction"
require "rexml/rexml"
require "rexml/parseexception"
require "rexml/output"
require "rexml/parsers/baseparser"
require "rexml/parsers/streamparser"
require "rexml/parsers/treeparser"

module REXML
  # Represents a full XML document, including PIs, a doctype, etc.  A
  # Document has a single child that can be accessed by root().
  # Note that if you want to have an XML declaration written for a document
  # you create, you must add one; REXML documents do not write a default
	# declaration for you.  See |DECLARATION| and |write|.
	class Document < Element
		# A convenient default XML declaration.  If you want an XML declaration,
		# the easiest way to add one is mydoc << Document::DECLARATION
    # +DEPRECATED+
    # Use: mydoc << XMLDecl.default
		DECLARATION = XMLDecl.default

		# Constructor
		# @param source if supplied, must be a Document, String, or IO. 
		# Documents have their context and Element attributes cloned.
	  # Strings are expected to be valid XML documents.  IOs are expected
	  # to be sources of valid XML documents.
	  # @param context if supplied, contains the context of the document;
	  # this should be a Hash.
		def initialize( source = nil, context = {} )
      @entity_expansion_count = 0
			super()
			@context = context
			return if source.nil?
			if source.kind_of? Document
				@context = source.context
				super source
			else
				build(  source )
			end
		end

    def node_type
      :document
    end

		# Should be obvious
		def clone
			Document.new self
		end

		# According to the XML spec, a root node has no expanded name
		def expanded_name
			''
			#d = doc_type
			#d ? d.name : "UNDEFINED"
		end

		alias :name :expanded_name

		# We override this, because XMLDecls and DocTypes must go at the start
		# of the document
		def add( child )
			if child.kind_of? XMLDecl
				@children.unshift child
        child.parent = self
			elsif child.kind_of? DocType
        # Find first Element or DocType node and insert the decl right 
        # before it.  If there is no such node, just insert the child at the
        # end.  If there is a child and it is an DocType, then replace it.
        insert_before_index = 0
        @children.find { |x| 
          insert_before_index += 1
          x.kind_of?(Element) || x.kind_of?(DocType)
        }
        if @children[ insert_before_index ] # Not null = not end of list
          if @children[ insert_before_index ].kind_of DocType
            @children[ insert_before_index ] = child
          else
            @children[ index_before_index-1, 0 ] = child
          end
        else  # Insert at end of list
          @children[insert_before_index] = child
        end
				child.parent = self
			else
				rv = super
				raise "attempted adding second root element to document" if @elements.size > 1
				rv
			end
		end
		alias :<< :add

		def add_element(arg=nil, arg2=nil)
			rv = super
			raise "attempted adding second root element to document" if @elements.size > 1
			rv
		end

		# @return the root Element of the document, or nil if this document
		# has no children.
		def root
      elements[1]
      #self
      #@children.find { |item| item.kind_of? Element }
		end

		# @return the DocType child of the document, if one exists,
		# and nil otherwise.
		def doctype
			@children.find { |item| item.kind_of? DocType }
		end

		# @return the XMLDecl of this document; if no XMLDecl has been
		# set, the default declaration is returned.
		def xml_decl
			rv = @children[0]
      return rv if rv.kind_of? XMLDecl
      rv = @children.unshift(XMLDecl.default)[0]
		end

		# @return the XMLDecl version of this document as a String.
		# If no XMLDecl has been set, returns the default version.
		def version
			xml_decl().version
		end

		# @return the XMLDecl encoding of this document as a String.
		# If no XMLDecl has been set, returns the default encoding.
		def encoding
			xml_decl().encoding
		end

		# @return the XMLDecl standalone value of this document as a String.
		# If no XMLDecl has been set, returns the default setting.
		def stand_alone?
			xml_decl().stand_alone?
		end

    # Write the XML tree out, optionally with indent.  This writes out the
    # entire XML document, including XML declarations, doctype declarations,
    # and processing instructions (if any are given).
    #
    # A controversial point is whether Document should always write the XML
    # declaration (<?xml version='1.0'?>) whether or not one is given by the
    # user (or source document).  REXML does not write one if one was not
    # specified, because it adds unnecessary bandwidth to applications such
    # as XML-RPC.
    #
    # See also the classes in the rexml/formatters package for the proper way
    # to change the default formatting of XML output
    #
    # _Examples_
    #   Document.new("<a><b/></a>").serialize
    #
    #   output_string = ""
    #   tr = Transitive.new( output_string )
    #   Document.new("<a><b/></a>").serialize( tr )
    #
    # output::
    #	  output an object which supports '<< string'; this is where the
    #   document will be written.
    # indent::
    #   An integer.  If -1, no indenting will be used; otherwise, the
    #   indentation will be twice this number of spaces, and children will be
    #   indented an additional amount.  For a value of 3, every item will be 
    #   indented 3 more levels, or 6 more spaces (2 * 3). Defaults to -1
    # trans::
    #   If transitive is true and indent is >= 0, then the output will be
    #   pretty-printed in such a way that the added whitespace does not affect
    #   the absolute *value* of the document -- that is, it leaves the value
    #   and number of Text nodes in the document unchanged.
    # ie_hack::
    #   Internet Explorer is the worst piece of crap to have ever been
    #   written, with the possible exception of Windows itself.  Since IE is
    #   unable to parse proper XML, we have to provide a hack to generate XML
    #   that IE's limited abilities can handle.  This hack inserts a space 
    #   before the /> on empty tags.  Defaults to false
		def write( output=$stdout, indent=-1, trans=false, ie_hack=false )
      if xml_decl.encoding != "UTF-8" && !output.kind_of?(Output)
        output = Output.new( output, xml_decl.encoding )
      end
      formatter = if indent > -1
          if trans
            REXML::Formatters::Transitive.new( indent, ie_hack )
          else
            REXML::Formatters::Pretty.new( indent, ie_hack )
          end
        else
          REXML::Formatters::Default.new( ie_hack )
        end
      formatter.write( self, output )
		end

		
		def Document::parse_stream( source, listener )
			Parsers::StreamParser.new( source, listener ).parse
		end

    @@entity_expansion_limit = 10_000

    # Set the entity expansion limit. By default the limit is set to 10000.
    def Document::entity_expansion_limit=( val )
      @@entity_expansion_limit = val
    end

    # Get the entity expansion limit. By default the limit is set to 10000.
    def Document::entity_expansion_limit
      return @@entity_expansion_limit
    end

    # Set the entity expansion limit. By default the limit is set to 10240.
    #
    # Deprecated. Use REXML.entity_expansion_text_limit= instead.
    def Document::entity_expansion_text_limit=( val )
      REXML.entity_expansion_text_limit = val
    end

    # Get the entity expansion limit. By default the limit is set to 10000.
    #
    # Deprecated. Use REXML.entity_expansion_text_limit instead.
    def Document::entity_expansion_text_limit
      return REXML.entity_expansion_text_limit
    end

    attr_reader :entity_expansion_count
    
    def record_entity_expansion
      @entity_expansion_count += 1
      if @entity_expansion_count > @@entity_expansion_limit
        raise "number of entity expansions exceeded, processing aborted."
      end
    end

		private
		def build( source )
      Parsers::TreeParser.new( source, self ).parse
		end
	end
end
PK     Y\)      rexml/node.rbnu [        require "rexml/parseexception"
require "rexml/formatters/pretty"
require "rexml/formatters/default"

module REXML
	# Represents a node in the tree.  Nodes are never encountered except as
	# superclasses of other objects.  Nodes have siblings.
	module Node
		# @return the next sibling (nil if unset)
		def next_sibling_node
			return nil if @parent.nil?
			@parent[ @parent.index(self) + 1 ]
		end

		# @return the previous sibling (nil if unset)
		def previous_sibling_node
			return nil if @parent.nil?
			ind = @parent.index(self)
			return nil if ind == 0
			@parent[ ind - 1 ]
		end

    # indent::
    #   *DEPRECATED* This parameter is now ignored.  See the formatters in the
    #   REXML::Formatters package for changing the output style.
		def to_s indent=nil
      unless indent.nil?
        Kernel.warn( "#{self.class.name}.to_s(indent) parameter is deprecated" )
        f = REXML::Formatters::Pretty.new( indent )
        f.write( self, rv = "" )
      else
        f = REXML::Formatters::Default.new
        f.write( self, rv = "" )
      end
      return rv
		end

		def indent to, ind
 			if @parent and @parent.context and not @parent.context[:indentstyle].nil? then
 				indentstyle = @parent.context[:indentstyle]
 			else
 				indentstyle = '  '
 			end
 			to << indentstyle*ind unless ind<1
		end

		def parent?
			false;
		end


		# Visit all subnodes of +self+ recursively
		def each_recursive(&block) # :yields: node
			self.elements.each {|node|
				block.call(node)
				node.each_recursive(&block)
			}
		end

		# Find (and return) first subnode (recursively) for which the block 
    # evaluates to true. Returns +nil+ if none was found.
		def find_first_recursive(&block) # :yields: node
      each_recursive {|node|
        return node if block.call(node)
      }
      return nil
    end

    # Returns the position that +self+ holds in its parent's array, indexed
    # from 1.
    def index_in_parent
      parent.index(self)+1
    end
	end
end
PK     Y\z      rexml/sax2listener.rbnu [        module REXML
	# A template for stream parser listeners.
	# Note that the declarations (attlistdecl, elementdecl, etc) are trivially
	# processed; REXML doesn't yet handle doctype entity declarations, so you 
	# have to parse them out yourself.
	# === Missing methods from SAX2
	#  ignorable_whitespace
	# === Methods extending SAX2 
	# +WARNING+
	# These methods are certainly going to change, until DTDs are fully
	# supported.  Be aware of this.
	#  start_document
	#  end_document
	#  doctype
	#  elementdecl
	#  attlistdecl
	#  entitydecl
	#  notationdecl
	#  cdata
	#  xmldecl
	#  comment
	module SAX2Listener
		def start_document
		end
		def end_document
		end
		def start_prefix_mapping prefix, uri
		end
		def end_prefix_mapping prefix
		end
		def start_element uri, localname, qname, attributes
		end
		def end_element uri, localname, qname
		end
		def characters text
		end
		def processing_instruction target, data
		end
		# Handles a doctype declaration. Any attributes of the doctype which are
		# not supplied will be nil.  # EG, <!DOCTYPE me PUBLIC "foo" "bar">
		# @p name the name of the doctype; EG, "me"
		# @p pub_sys "PUBLIC", "SYSTEM", or nil.  EG, "PUBLIC"
		# @p long_name the supplied long name, or nil.  EG, "foo"
		# @p uri the uri of the doctype, or nil.  EG, "bar"
		def doctype name, pub_sys, long_name, uri
		end
		# If a doctype includes an ATTLIST declaration, it will cause this
		# method to be called.  The content is the declaration itself, unparsed.
		# EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as "el
		# attr CDATA #REQUIRED".  This is the same for all of the .*decl
		# methods.
		def attlistdecl(element, pairs, contents)
		end
		# <!ELEMENT ...>
		def elementdecl content
		end
		# <!ENTITY ...>
		# The argument passed to this method is an array of the entity
		# declaration.  It can be in a number of formats, but in general it
		# returns (example, result):
		#  <!ENTITY % YN '"Yes"'>  
		#  ["%", "YN", "'\"Yes\"'", "\""]
		#  <!ENTITY % YN 'Yes'>
		#  ["%", "YN", "'Yes'", "s"]
		#  <!ENTITY WhatHeSaid "He said %YN;">
		#  ["WhatHeSaid", "\"He said %YN;\"", "YN"]
		#  <!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
		#  ["open-hatch", "SYSTEM", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
		#  <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
		#  ["open-hatch", "PUBLIC", "\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\"", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
		#  <!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif>
		#  ["hatch-pic", "SYSTEM", "\"../grafix/OpenHatch.gif\"", "\n\t\t\t\t\t\t\tNDATA gif", "gif"]
		def entitydecl name, decl
		end
		# <!NOTATION ...>
		def notationdecl content
		end
		# Called when <![CDATA[ ... ]]> is encountered in a document.
		# @p content "..."
		def cdata content
		end
		# Called when an XML PI is encountered in the document.
		# EG: <?xml version="1.0" encoding="utf"?>
		# @p version the version attribute value.  EG, "1.0"
		# @p encoding the encoding attribute value, or nil.  EG, "utf"
		# @p standalone the standalone attribute value, or nil.  EG, nil
    # @p spaced the declaration is followed by a line break
		def xmldecl version, encoding, standalone
		end
		# Called when a comment is encountered.
		# @p comment The content of the comment
		def comment comment
		end
    def progress position
    end
	end	
end
PK     Y\
\	  	    rexml/xpath.rbnu [        require 'rexml/functions'
require 'rexml/xpath_parser'

module REXML
	# Wrapper class.  Use this class to access the XPath functions.
	class XPath
		include Functions
		EMPTY_HASH = {}

		# Finds and returns the first node that matches the supplied xpath.
		# element::
		# 	The context element
		# path::
		# 	The xpath to search for.  If not supplied or nil, returns the first
		# 	node matching '*'.
		# namespaces::
		# 	If supplied, a Hash which defines a namespace mapping.
		#
		#  XPath.first( node )
		#  XPath.first( doc, "//b"} )
		#  XPath.first( node, "a/x:b", { "x"=>"http://doofus" } )
    def XPath::first element, path=nil, namespaces=nil, variables={}
      raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
      raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
			parser = XPathParser.new
			parser.namespaces = namespaces
			parser.variables = variables
			path = "*" unless path
			element = [element] unless element.kind_of? Array
			parser.parse(path, element).flatten[0]
		end

		# Iterates over nodes that match the given path, calling the supplied
		# block with the match.
		# element::
		#   The context element
		# path::
		#   The xpath to search for.  If not supplied or nil, defaults to '*'
		# namespaces::
		# 	If supplied, a Hash which defines a namespace mapping
		#
		#  XPath.each( node ) { |el| ... }
		#  XPath.each( node, '/*[@attr='v']' ) { |el| ... }
		#  XPath.each( node, 'ancestor::x' ) { |el| ... }
		def XPath::each element, path=nil, namespaces=nil, variables={}, &block
      raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
      raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
			parser = XPathParser.new
			parser.namespaces = namespaces
			parser.variables = variables
			path = "*" unless path
			element = [element] unless element.kind_of? Array
			parser.parse(path, element).each( &block )
		end

		# Returns an array of nodes matching a given XPath.  
		def XPath::match element, path=nil, namespaces=nil, variables={}
			parser = XPathParser.new
			parser.namespaces = namespaces
			parser.variables = variables
			path = "*" unless path
			element = [element] unless element.kind_of? Array
			parser.parse(path,element)
		end
	end
end
PK     Y\uL      rexml/streamlistener.rbnu [        module REXML
	# A template for stream parser listeners.
	# Note that the declarations (attlistdecl, elementdecl, etc) are trivially
	# processed; REXML doesn't yet handle doctype entity declarations, so you 
	# have to parse them out yourself.
	module StreamListener
		# Called when a tag is encountered.
		# @p name the tag name
		# @p attrs an array of arrays of attribute/value pairs, suitable for
		# use with assoc or rassoc.  IE, <tag attr1="value1" attr2="value2">
		# will result in 
		# tag_start( "tag", # [["attr1","value1"],["attr2","value2"]])
		def tag_start name, attrs
		end
		# Called when the end tag is reached.  In the case of <tag/>, tag_end
		# will be called immidiately after tag_start
		# @p the name of the tag
		def tag_end name
		end
		# Called when text is encountered in the document
		# @p text the text content.
		def text text
		end
		# Called when an instruction is encountered.  EG: <?xsl sheet='foo'?>
		# @p name the instruction name; in the example, "xsl"
		# @p instruction the rest of the instruction.  In the example,
		# "sheet='foo'"
		def instruction name, instruction
		end
		# Called when a comment is encountered.
		# @p comment The content of the comment
		def comment comment
		end
		# Handles a doctype declaration. Any attributes of the doctype which are
		# not supplied will be nil.  # EG, <!DOCTYPE me PUBLIC "foo" "bar">
		# @p name the name of the doctype; EG, "me"
		# @p pub_sys "PUBLIC", "SYSTEM", or nil.  EG, "PUBLIC"
		# @p long_name the supplied long name, or nil.  EG, "foo"
		# @p uri the uri of the doctype, or nil.  EG, "bar"
		def doctype name, pub_sys, long_name, uri
		end
		# Called when the doctype is done
		def doctype_end
		end
		# If a doctype includes an ATTLIST declaration, it will cause this
		# method to be called.  The content is the declaration itself, unparsed.
		# EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as "el
		# attr CDATA #REQUIRED".  This is the same for all of the .*decl
		# methods.
		def attlistdecl element_name, attributes, raw_content
		end
		# <!ELEMENT ...>
		def elementdecl content
		end
		# <!ENTITY ...>
		# The argument passed to this method is an array of the entity
		# declaration.  It can be in a number of formats, but in general it
		# returns (example, result):
		#  <!ENTITY % YN '"Yes"'>  
		#  ["%", "YN", "'\"Yes\"'", "\""]
		#  <!ENTITY % YN 'Yes'>
		#  ["%", "YN", "'Yes'", "s"]
		#  <!ENTITY WhatHeSaid "He said %YN;">
		#  ["WhatHeSaid", "\"He said %YN;\"", "YN"]
		#  <!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
		#  ["open-hatch", "SYSTEM", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
		#  <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
		#  ["open-hatch", "PUBLIC", "\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\"", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
		#  <!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif>
		#  ["hatch-pic", "SYSTEM", "\"../grafix/OpenHatch.gif\"", "\n\t\t\t\t\t\t\tNDATA gif", "gif"]
		def entitydecl content
		end
		# <!NOTATION ...>
		def notationdecl content
		end
		# Called when %foo; is encountered in a doctype declaration.
		# @p content "foo"
		def entity content
		end
		# Called when <![CDATA[ ... ]]> is encountered in a document.
		# @p content "..."
		def cdata content
		end
		# Called when an XML PI is encountered in the document.
		# EG: <?xml version="1.0" encoding="utf"?>
		# @p version the version attribute value.  EG, "1.0"
		# @p encoding the encoding attribute value, or nil.  EG, "utf"
		# @p standalone the standalone attribute value, or nil.  EG, nil
		def xmldecl version, encoding, standalone
		end
	end
end
PK     Y\#&      rexml/parseexception.rbnu [        module REXML
  class ParseException < RuntimeError
    attr_accessor :source, :parser, :continued_exception

    def initialize( message, source=nil, parser=nil, exception=nil )
      super(message)
      @source = source
      @parser = parser
      @continued_exception = exception
    end

    def to_s
      # Quote the original exception, if there was one
      if @continued_exception
        err = @continued_exception.inspect
        err << "\n"
        err << @continued_exception.backtrace.join("\n")
        err << "\n...\n"
      else
        err = ""
      end

      # Get the stack trace and error message
      err << super

      # Add contextual information
      if @source
        err << "\nLine: #{line}\n"
        err << "Position: #{position}\n"
        err << "Last 80 unconsumed characters:\n"
        err << @source.buffer[0..80].gsub(/\n/, ' ')
      end
      
      err
    end

    def position
      @source.current_line[0] if @source and defined? @source.current_line and
      @source.current_line
    end

    def line
      @source.current_line[2] if @source and defined? @source.current_line and 
      @source.current_line
    end

    def context
      @source.current_line
    end
  end  
end
PK     Y\      rexml/element.rbnu [        require "rexml/parent"
require "rexml/namespace"
require "rexml/attribute"
require "rexml/cdata"
require "rexml/xpath"
require "rexml/parseexception"

module REXML
  # An implementation note about namespaces:
  # As we parse, when we find namespaces we put them in a hash and assign
  # them a unique ID.  We then convert the namespace prefix for the node
  # to the unique ID.  This makes namespace lookup much faster for the
  # cost of extra memory use.  We save the namespace prefix for the
  # context node and convert it back when we write it.
  @@namespaces = {}

  # Represents a tagged XML element.  Elements are characterized by
  # having children, attributes, and names, and can themselves be
  # children.
  class Element < Parent
    include Namespace

    UNDEFINED = "UNDEFINED";		# The default name

    # Mechanisms for accessing attributes and child elements of this
    # element.
    attr_reader :attributes, :elements
    # The context holds information about the processing environment, such as
    # whitespace handling.
    attr_accessor :context

    # Constructor
    # arg:: 
    # 	if not supplied, will be set to the default value.
    # 	If a String, the name of this object will be set to the argument.
    # 	If an Element, the object will be shallowly cloned; name, 
    # 	attributes, and namespaces will be copied.  Children will +not+ be
    # 	copied.
    # parent:: 
    # 	if supplied, must be a Parent, and will be used as
    # 	the parent of this object.
    # context::
    # 	If supplied, must be a hash containing context items.  Context items
    # 	include:
    # * <tt>:respect_whitespace</tt> the value of this is :+all+ or an array of
    #   strings being the names of the elements to respect
    #   whitespace for.  Defaults to :+all+.
    # * <tt>:compress_whitespace</tt> the value can be :+all+ or an array of
    #   strings being the names of the elements to ignore whitespace on.
    #   Overrides :+respect_whitespace+.
    # * <tt>:ignore_whitespace_nodes</tt> the value can be :+all+ or an array
    #   of strings being the names of the elements in which to ignore
    #   whitespace-only nodes.  If this is set, Text nodes which contain only
    #   whitespace will not be added to the document tree.
    # * <tt>:raw</tt> can be :+all+, or an array of strings being the names of
    #   the elements to process in raw mode.  In raw mode, special
    #   characters in text is not converted to or from entities.
    def initialize( arg = UNDEFINED, parent=nil, context=nil )
      super(parent)

      @elements = Elements.new(self)
      @attributes = Attributes.new(self)
      @context = context

      if arg.kind_of? String
        self.name = arg
      elsif arg.kind_of? Element
        self.name = arg.expanded_name
        arg.attributes.each_attribute{ |attribute|
          @attributes << Attribute.new( attribute )
        }
        @context = arg.context
      end
    end

    def inspect
      rv = "<#@expanded_name"

      @attributes.each_attribute do |attr|
        rv << " "
        attr.write( rv, 0 )
      end

      if children.size > 0
        rv << "> ... </>"
      else
        rv << "/>"
      end
    end


    # Creates a shallow copy of self.
    #   d = Document.new "<a><b/><b/><c><d/></c></a>"
    #   new_a = d.root.clone
    #   puts new_a  # => "<a/>"
    def clone
      self.class.new self
    end

    # Evaluates to the root node of the document that this element 
    # belongs to. If this element doesn't belong to a document, but does
    # belong to another Element, the parent's root will be returned, until the
    # earliest ancestor is found.
    #
    # Note that this is not the same as the document element.
    # In the following example, <a> is the document element, and the root
    # node is the parent node of the document element.  You may ask yourself
    # why the root node is useful: consider the doctype and XML declaration,
    # and any processing instructions before the document element... they
    # are children of the root node, or siblings of the document element.
    # The only time this isn't true is when an Element is created that is
    # not part of any Document.  In this case, the ancestor that has no
    # parent acts as the root node.
    #  d = Document.new '<a><b><c/></b></a>'
    #  a = d[1] ; c = a[1][1]
    #  d.root_node == d   # TRUE
    #  a.root_node        # namely, d
    #  c.root_node        # again, d
    def root_node
      parent.nil? ? self : parent.root_node
    end

    def root
      return elements[1] if self.kind_of? Document
      return self if parent.kind_of? Document or parent.nil?
      return parent.root
    end

    # Evaluates to the document to which this element belongs, or nil if this
    # element doesn't belong to a document.
    def document
      rt = root
      rt.parent if rt
    end

    # Evaluates to +true+ if whitespace is respected for this element.  This
    # is the case if:
    # 1. Neither :+respect_whitespace+ nor :+compress_whitespace+ has any value
    # 2. The context has :+respect_whitespace+ set to :+all+ or
    #    an array containing the name of this element, and 
    #    :+compress_whitespace+ isn't set to :+all+ or an array containing the 
    #    name of this element.
    # The evaluation is tested against +expanded_name+, and so is namespace
    # sensitive.
    def whitespace
      @whitespace = nil
      if @context
        if @context[:respect_whitespace]
          @whitespace = (@context[:respect_whitespace] == :all or
                         @context[:respect_whitespace].include? expanded_name)
        end
        @whitespace = false if (@context[:compress_whitespace] and
                                (@context[:compress_whitespace] == :all or
                                 @context[:compress_whitespace].include? expanded_name)
                               )
      end
      @whitespace = true unless @whitespace == false
      @whitespace
    end

    def ignore_whitespace_nodes
      @ignore_whitespace_nodes = false
      if @context
        if @context[:ignore_whitespace_nodes]
          @ignore_whitespace_nodes = 
            (@context[:ignore_whitespace_nodes] == :all or
             @context[:ignore_whitespace_nodes].include? expanded_name)
        end
      end
    end

    # Evaluates to +true+ if raw mode is set for this element.  This
    # is the case if the context has :+raw+ set to :+all+ or
    # an array containing the name of this element.
    #
    # The evaluation is tested against +expanded_name+, and so is namespace
    # sensitive.
    def raw
      @raw = (@context and @context[:raw] and
              (@context[:raw] == :all or
               @context[:raw].include? expanded_name))
               @raw
    end

    #once :whitespace, :raw, :ignore_whitespace_nodes

    #################################################
    # Namespaces                                    #
    #################################################

    # Evaluates to an +Array+ containing the prefixes (names) of all defined
    # namespaces at this context node.
    #  doc = Document.new("<a xmlns:x='1' xmlns:y='2'><b/><c xmlns:z='3'/></a>")
    #  doc.elements['//b'].prefixes # -> ['x', 'y']
    def prefixes
      prefixes = []
      prefixes = parent.prefixes if parent
      prefixes |= attributes.prefixes
      return prefixes
    end

    def namespaces
      namespaces = {}
      namespaces = parent.namespaces if parent
      namespaces = namespaces.merge( attributes.namespaces )
      return namespaces
    end

    # Evalutas to the URI for a prefix, or the empty string if no such 
    # namespace is declared for this element. Evaluates recursively for
    # ancestors.  Returns the default namespace, if there is one.
    # prefix:: 
    #   the prefix to search for.  If not supplied, returns the default
    #   namespace if one exists
    # Returns:: 
    #   the namespace URI as a String, or nil if no such namespace
    #   exists.  If the namespace is undefined, returns an empty string
    #  doc = Document.new("<a xmlns='1' xmlns:y='2'><b/><c xmlns:z='3'/></a>")
    #  b = doc.elements['//b']
    #  b.namespace           # -> '1'
    #  b.namespace("y")      # -> '2'
    def namespace(prefix=nil)
      if prefix.nil?
        prefix = prefix()
      end
      if prefix == ''
        prefix = "xmlns"
      else
        prefix = "xmlns:#{prefix}" unless prefix[0,5] == 'xmlns'
      end
      ns = attributes[ prefix ]
      ns = parent.namespace(prefix) if ns.nil? and parent
      ns = '' if ns.nil? and prefix == 'xmlns'
      return ns
    end

    # Adds a namespace to this element.
    # prefix:: 
    #   the prefix string, or the namespace URI if +uri+ is not
    #   supplied
    # uri::    
    #   the namespace URI.  May be nil, in which +prefix+ is used as
    #   the URI
    # Evaluates to: this Element
    #  a = Element.new("a")
    #  a.add_namespace("xmlns:foo", "bar" )
    #  a.add_namespace("foo", "bar")  # shorthand for previous line
    #  a.add_namespace("twiddle")
    #  puts a   #-> <a xmlns:foo='bar' xmlns='twiddle'/>
    def add_namespace( prefix, uri=nil )
      unless uri
        @attributes["xmlns"] = prefix
      else
        prefix = "xmlns:#{prefix}" unless prefix =~ /^xmlns:/
        @attributes[ prefix ] = uri
      end
      self
    end

    # Removes a namespace from this node.  This only works if the namespace is
    # actually declared in this node.  If no argument is passed, deletes the
    # default namespace.
    #
    # Evaluates to: this element
    #  doc = Document.new "<a xmlns:foo='bar' xmlns='twiddle'/>"
    #  doc.root.delete_namespace
    #  puts doc     # -> <a xmlns:foo='bar'/>
    #  doc.root.delete_namespace 'foo'
    #  puts doc     # -> <a/>
    def delete_namespace namespace="xmlns"
      namespace = "xmlns:#{namespace}" unless namespace == 'xmlns'
      attribute = attributes.get_attribute(namespace)
      attribute.remove unless attribute.nil?
      self
    end

    #################################################
    # Elements                                      #
    #################################################

    # Adds a child to this element, optionally setting attributes in
    # the element.
    # element:: 
    #   optional.  If Element, the element is added.
    #   Otherwise, a new Element is constructed with the argument (see
    #   Element.initialize).
    # attrs:: 
    #   If supplied, must be a Hash containing String name,value 
    #   pairs, which will be used to set the attributes of the new Element.
    # Returns:: the Element that was added
    #  el = doc.add_element 'my-tag'
    #  el = doc.add_element 'my-tag', {'attr1'=>'val1', 'attr2'=>'val2'}
    #  el = Element.new 'my-tag'
    #  doc.add_element el
    def add_element element, attrs=nil
      raise "First argument must be either an element name, or an Element object" if element.nil?
      el = @elements.add(element)
      attrs.each do |key, value|
        el.attributes[key]=Attribute.new(key,value,self)
      end	if attrs.kind_of? Hash
      el
    end

    # Deletes a child element.
    # element:: 
    #   Must be an +Element+, +String+, or +Integer+.  If Element, 
    #   the element is removed.  If String, the element is found (via XPath) 
    #   and removed.  <em>This means that any parent can remove any
    #   descendant.<em>  If Integer, the Element indexed by that number will be
    #   removed.
    # Returns:: the element that was removed.
    #  doc.delete_element "/a/b/c[@id='4']"
    #  doc.delete_element doc.elements["//k"]
    #  doc.delete_element 1
    def delete_element element
      @elements.delete element
    end

    # Evaluates to +true+ if this element has at least one child Element
    #  doc = Document.new "<a><b/><c>Text</c></a>"
    #  doc.root.has_elements               # -> true
    #  doc.elements["/a/b"].has_elements   # -> false
    #  doc.elements["/a/c"].has_elements   # -> false
    def has_elements?
      !@elements.empty?
    end

    # Iterates through the child elements, yielding for each Element that
    # has a particular attribute set.
    # key:: 
    #   the name of the attribute to search for
    # value:: 
    #   the value of the attribute
    # max:: 
    #   (optional) causes this method to return after yielding 
    #   for this number of matching children
    # name:: 
    #   (optional) if supplied, this is an XPath that filters
    #   the children to check.
    #
    #  doc = Document.new "<a><b @id='1'/><c @id='2'/><d @id='1'/><e/></a>"
    #  # Yields b, c, d
    #  doc.root.each_element_with_attribute( 'id' ) {|e| p e}
    #  # Yields b, d
    #  doc.root.each_element_with_attribute( 'id', '1' ) {|e| p e}
    #  # Yields b
    #  doc.root.each_element_with_attribute( 'id', '1', 1 ) {|e| p e}
    #  # Yields d
    #  doc.root.each_element_with_attribute( 'id', '1', 0, 'd' ) {|e| p e}
    def each_element_with_attribute( key, value=nil, max=0, name=nil, &block ) # :yields: Element
      each_with_something( proc {|child| 
        if value.nil?
          child.attributes[key] != nil
        else
          child.attributes[key]==value
        end
      }, max, name, &block )
    end

    # Iterates through the children, yielding for each Element that
    # has a particular text set.
    # text:: 
    #   the text to search for.  If nil, or not supplied, will iterate
    #   over all +Element+ children that contain at least one +Text+ node.
    # max:: 
    #   (optional) causes this method to return after yielding
    #   for this number of matching children
    # name:: 
    #   (optional) if supplied, this is an XPath that filters
    #   the children to check.
    #
    #  doc = Document.new '<a><b>b</b><c>b</c><d>d</d><e/></a>'
    #  # Yields b, c, d
    #  doc.each_element_with_text {|e|p e}
    #  # Yields b, c
    #  doc.each_element_with_text('b'){|e|p e}
    #  # Yields b
    #  doc.each_element_with_text('b', 1){|e|p e}
    #  # Yields d
    #  doc.each_element_with_text(nil, 0, 'd'){|e|p e}
    def each_element_with_text( text=nil, max=0, name=nil, &block ) # :yields: Element
      each_with_something( proc {|child| 
        if text.nil?
          child.has_text?
        else
          child.text == text
        end
      }, max, name, &block )
    end

    # Synonym for Element.elements.each
    def each_element( xpath=nil, &block ) # :yields: Element
      @elements.each( xpath, &block )
    end

    # Synonym for Element.to_a
    # This is a little slower than calling elements.each directly.
    # xpath:: any XPath by which to search for elements in the tree
    # Returns:: an array of Elements that match the supplied path
    def get_elements( xpath )
      @elements.to_a( xpath )
    end

    # Returns the next sibling that is an element, or nil if there is
    # no Element sibling after this one
    #  doc = Document.new '<a><b/>text<c/></a>'
    #  doc.root.elements['b'].next_element          #-> <c/>
    #  doc.root.elements['c'].next_element          #-> nil
    def next_element
      element = next_sibling
      element = element.next_sibling until element.nil? or element.kind_of? Element 
      return element
    end

    # Returns the previous sibling that is an element, or nil if there is
    # no Element sibling prior to this one
    #  doc = Document.new '<a><b/>text<c/></a>'
    #  doc.root.elements['c'].previous_element          #-> <b/>
    #  doc.root.elements['b'].previous_element          #-> nil
    def previous_element
      element = previous_sibling
      element = element.previous_sibling until element.nil? or element.kind_of? Element
      return element
    end


    #################################################
    # Text                                          #
    #################################################

    # Evaluates to +true+ if this element has at least one Text child
    def has_text?
      not text().nil?
    end

    # A convenience method which returns the String value of the _first_
    # child text element, if one exists, and +nil+ otherwise.
    #
    # <em>Note that an element may have multiple Text elements, perhaps
    # separated by other children</em>.  Be aware that this method only returns
    # the first Text node.
    #
    # This method returns the +value+ of the first text child node, which
    # ignores the +raw+ setting, so always returns normalized text. See
    # the Text::value documentation.
    #
    #  doc = Document.new "<p>some text <b>this is bold!</b> more text</p>"
    #  # The element 'p' has two text elements, "some text " and " more text".
    #  doc.root.text              #-> "some text "
    def text( path = nil )
      rv = get_text(path)
      return rv.value unless rv.nil?
      nil
    end

    # Returns the first child Text node, if any, or +nil+ otherwise.
    # This method returns the actual +Text+ node, rather than the String content.
    #  doc = Document.new "<p>some text <b>this is bold!</b> more text</p>"
    #  # The element 'p' has two text elements, "some text " and " more text".
    #  doc.root.get_text.value            #-> "some text "
    def get_text path = nil
      rv = nil
      if path
        element = @elements[ path ]
        rv = element.get_text unless element.nil?
      else
        rv = @children.find { |node| node.kind_of? Text }
      end
      return rv
    end

    # Sets the first Text child of this object.  See text() for a
    # discussion about Text children.
    #
    # If a Text child already exists, the child is replaced by this
    # content.  This means that Text content can be deleted by calling
    # this method with a nil argument.  In this case, the next Text
    # child becomes the first Text child.  In no case is the order of
    # any siblings disturbed.
    # text:: 
    #   If a String, a new Text child is created and added to
    #   this Element as the first Text child.  If Text, the text is set
    #   as the first Child element.  If nil, then any existing first Text
    #   child is removed.
    # Returns:: this Element.
    #  doc = Document.new '<a><b/></a>'
    #  doc.root.text = 'Sean'      #-> '<a><b/>Sean</a>'
    #  doc.root.text = 'Elliott'   #-> '<a><b/>Elliott</a>'
    #  doc.root.add_element 'c'    #-> '<a><b/>Elliott<c/></a>'
    #  doc.root.text = 'Russell'   #-> '<a><b/>Russell<c/></a>'
    #  doc.root.text = nil         #-> '<a><b/><c/></a>'
    def text=( text )
      if text.kind_of? String
        text = Text.new( text, whitespace(), nil, raw() )
      elsif !text.nil? and !text.kind_of? Text
        text = Text.new( text.to_s, whitespace(), nil, raw() )
      end
      old_text = get_text
      if text.nil?
        old_text.remove unless old_text.nil?
      else
        if old_text.nil?
          self << text
        else
          old_text.replace_with( text )
        end
      end
      return self
    end

    # A helper method to add a Text child.  Actual Text instances can
    # be added with regular Parent methods, such as add() and <<()
    # text::
    #   if a String, a new Text instance is created and added
    #   to the parent.  If Text, the object is added directly.
    # Returns:: this Element
    #  e = Element.new('a')          #-> <e/>
    #  e.add_text 'foo'              #-> <e>foo</e>
    #  e.add_text Text.new(' bar')    #-> <e>foo bar</e>
    # Note that at the end of this example, the branch has <b>3</b> nodes; the 'e'
    # element and <b>2</b> Text node children.
    def add_text( text )
      if text.kind_of? String 
        if @children[-1].kind_of? Text
          @children[-1] << text
          return
        end
        text = Text.new( text, whitespace(), nil, raw() )
      end
      self << text unless text.nil?
      return self
    end

    def node_type
      :element
    end

    def xpath
      path_elements = []
      cur = self
      path_elements << __to_xpath_helper( self )
      while cur.parent
        cur = cur.parent
        path_elements << __to_xpath_helper( cur )
      end
      return path_elements.reverse.join( "/" )
    end

    #################################################
    # Attributes                                    #
    #################################################

    def attribute( name, namespace=nil )
      prefix = nil
      prefix = namespaces.index(namespace) if namespace
      prefix = nil if prefix == 'xmlns'
      attributes.get_attribute( "#{prefix ? prefix + ':' : ''}#{name}" )
    end

    # Evaluates to +true+ if this element has any attributes set, false
    # otherwise.
    def has_attributes?
      return !@attributes.empty?
    end

    # Adds an attribute to this element, overwriting any existing attribute
    # by the same name.
    # key::
    #   can be either an Attribute or a String.  If an Attribute,
    #   the attribute is added to the list of Element attributes.  If String,
    #   the argument is used as the name of the new attribute, and the value
    #   parameter must be supplied.
    # value:: 
    #   Required if +key+ is a String, and ignored if the first argument is
    #   an Attribute.  This is a String, and is used as the value
    #   of the new Attribute.  This should be the unnormalized value of the
    #   attribute (without entities).
    # Returns:: the Attribute added
    #  e = Element.new 'e'
    #  e.add_attribute( 'a', 'b' )               #-> <e a='b'/>
    #  e.add_attribute( 'x:a', 'c' )             #-> <e a='b' x:a='c'/>
    #  e.add_attribute Attribute.new('b', 'd')   #-> <e a='b' x:a='c' b='d'/>
    def add_attribute( key, value=nil )
      if key.kind_of? Attribute
        @attributes << key
      else
        @attributes[key] = value
      end
    end

    # Add multiple attributes to this element.
    # hash:: is either a hash, or array of arrays
    #  el.add_attributes( {"name1"=>"value1", "name2"=>"value2"} )
    #  el.add_attributes( [ ["name1","value1"], ["name2"=>"value2"] ] )
    def add_attributes hash
      if hash.kind_of? Hash
        hash.each_pair {|key, value| @attributes[key] = value }
      elsif hash.kind_of? Array
        hash.each { |value| @attributes[ value[0] ] = value[1] }
      end
    end

    # Removes an attribute
    # key::
    #   either an Attribute or a String.  In either case, the
    #   attribute is found by matching the attribute name to the argument,
    #   and then removed.  If no attribute is found, no action is taken.
    # Returns:: 
    #   the attribute removed, or nil if this Element did not contain
    #   a matching attribute
    #  e = Element.new('E')
    #  e.add_attribute( 'name', 'Sean' )             #-> <E name='Sean'/>
    #  r = e.add_attribute( 'sur:name', 'Russell' )  #-> <E name='Sean' sur:name='Russell'/>
    #  e.delete_attribute( 'name' )                  #-> <E sur:name='Russell'/>
    #  e.delete_attribute( r )                       #-> <E/>
    def delete_attribute(key)
      attr = @attributes.get_attribute(key)
      attr.remove unless attr.nil?
    end

    #################################################
    # Other Utilities                               #
    #################################################

    # Get an array of all CData children.  
    # IMMUTABLE
    def cdatas
      find_all { |child| child.kind_of? CData }.freeze
    end

    # Get an array of all Comment children.
    # IMMUTABLE
    def comments
      find_all { |child| child.kind_of? Comment }.freeze
    end

    # Get an array of all Instruction children.
    # IMMUTABLE
    def instructions
      find_all { |child| child.kind_of? Instruction }.freeze
    end

    # Get an array of all Text children.
    # IMMUTABLE
    def texts
      find_all { |child| child.kind_of? Text }.freeze
    end

    # == DEPRECATED
    # See REXML::Formatters
    #
    # Writes out this element, and recursively, all children.
    # output::
    #	  output an object which supports '<< string'; this is where the
    #   document will be written.
    # indent::
    #   An integer.  If -1, no indenting will be used; otherwise, the
    #   indentation will be this number of spaces, and children will be
    #   indented an additional amount.  Defaults to -1
    # transitive::
    #   If transitive is true and indent is >= 0, then the output will be
    #   pretty-printed in such a way that the added whitespace does not affect
    #   the parse tree of the document
    # ie_hack::
    #   Internet Explorer is the worst piece of crap to have ever been
    #   written, with the possible exception of Windows itself.  Since IE is
    #   unable to parse proper XML, we have to provide a hack to generate XML
    #   that IE's limited abilities can handle.  This hack inserts a space 
    #   before the /> on empty tags.  Defaults to false
    #
    #  out = ''
    #  doc.write( out )     #-> doc is written to the string 'out'
    #  doc.write( $stdout ) #-> doc written to the console
    def write(writer=$stdout, indent=-1, transitive=false, ie_hack=false)
      Kernel.warn("#{self.class.name}.write is deprecated.  See REXML::Formatters")
      formatter = if indent > -1
          if transitive
            REXML::Formatters::Transitive.new( indent, ie_hack )
          else
            REXML::Formatters::Pretty.new( indent, ie_hack )
          end
        else
          REXML::Formatters::Default.new( ie_hack )
        end
      formatter.write( self, output )
    end


    private
    def __to_xpath_helper node
      rv = node.expanded_name.clone
      if node.parent
        results = node.parent.find_all {|n| 
          n.kind_of?(REXML::Element) and n.expanded_name == node.expanded_name 
        }
        if results.length > 1
          idx = results.index( node )
          rv << "[#{idx+1}]"
        end
      end
      rv
    end

    # A private helper method
    def each_with_something( test, max=0, name=nil )
      num = 0
      child=nil
      @elements.each( name ){ |child|
        yield child if test.call(child) and num += 1
        return if max>0 and num == max
      }
    end
  end

  ########################################################################
  # ELEMENTS                                                             #
  ########################################################################

  # A class which provides filtering of children for Elements, and
  # XPath search support.  You are expected to only encounter this class as
  # the <tt>element.elements</tt> object.  Therefore, you are 
  # _not_ expected to instantiate this yourself.
  class Elements
    include Enumerable
    # Constructor
    # parent:: the parent Element
    def initialize parent
      @element = parent
    end

    # Fetches a child element.  Filters only Element children, regardless of
    # the XPath match.
    # index:: 
    #   the search parameter.  This is either an Integer, which
    #   will be used to find the index'th child Element, or an XPath,
    #   which will be used to search for the Element.  <em>Because
    #   of the nature of XPath searches, any element in the connected XML
    #   document can be fetched through any other element.</em>  <b>The
    #   Integer index is 1-based, not 0-based.</b>  This means that the first
    #   child element is at index 1, not 0, and the +n+th element is at index
    #   +n+, not <tt>n-1</tt>.  This is because XPath indexes element children
    #   starting from 1, not 0, and the indexes should be the same.
    # name:: 
    #   optional, and only used in the first argument is an
    #   Integer.  In that case, the index'th child Element that has the
    #   supplied name will be returned.  Note again that the indexes start at 1.
    # Returns:: the first matching Element, or nil if no child matched
    #  doc = Document.new '<a><b/><c id="1"/><c id="2"/><d/></a>'
    #  doc.root.elements[1]       #-> <b/>
    #  doc.root.elements['c']     #-> <c id="1"/>
    #  doc.root.elements[2,'c']   #-> <c id="2"/>
    def []( index, name=nil)
      if index.kind_of? Integer
        raise "index (#{index}) must be >= 1" if index < 1
        name = literalize(name) if name
        num = 0
        child = nil
        @element.find { |child|
          child.kind_of? Element and
          (name.nil? ? true : child.has_name?( name )) and 
          (num += 1) == index
        }
      else
        return XPath::first( @element, index )
        #{ |element| 
        #	return element if element.kind_of? Element
        #}
        #return nil
      end
    end

    # Sets an element, replacing any previous matching element.  If no
    # existing element is found ,the element is added.
    # index:: Used to find a matching element to replace.  See []().
    # element:: 
    #   The element to replace the existing element with
    #   the previous element
    # Returns:: nil if no previous element was found.
    #
    #  doc = Document.new '<a/>'
    #  doc.root.elements[10] = Element.new('b')    #-> <a><b/></a>
    #  doc.root.elements[1]                        #-> <b/>
    #  doc.root.elements[1] = Element.new('c')     #-> <a><c/></a>
    #  doc.root.elements['c'] = Element.new('d')   #-> <a><d/></a>
    def []=( index, element )
      previous = self[index]
      if previous.nil?
        @element.add element
      else
        previous.replace_with element
      end
      return previous
    end

    # Returns +true+ if there are no +Element+ children, +false+ otherwise
    def empty?
      @element.find{ |child| child.kind_of? Element}.nil?
    end

    # Returns the index of the supplied child (starting at 1), or -1 if 
    # the element is not a child
    # element:: an +Element+ child
    def index element
      rv = 0
      found = @element.find do |child| 
        child.kind_of? Element and
        (rv += 1) and
        child == element
      end
      return rv if found == element
      return -1
    end

    # Deletes a child Element
    # element:: 
    #   Either an Element, which is removed directly; an
    #   xpath, where the first matching child is removed; or an Integer,
    #   where the n'th Element is removed.
    # Returns:: the removed child
    #  doc = Document.new '<a><b/><c/><c id="1"/></a>'
    #  b = doc.root.elements[1]
    #  doc.root.elements.delete b           #-> <a><c/><c id="1"/></a>
    #  doc.elements.delete("a/c[@id='1']")  #-> <a><c/></a>
    #  doc.root.elements.delete 1           #-> <a/>
    def delete element
      if element.kind_of? Element
        @element.delete element
      else
        el = self[element]
        el.remove if el
      end
    end

    # Removes multiple elements.  Filters for Element children, regardless of
    # XPath matching.
    # xpath:: all elements matching this String path are removed.
    # Returns:: an Array of Elements that have been removed
    #  doc = Document.new '<a><c/><c/><c/><c/></a>'
    #  deleted = doc.elements.delete_all 'a/c' #-> [<c/>, <c/>, <c/>, <c/>]
    def delete_all( xpath )
      rv = []
      XPath::each( @element, xpath) {|element| 
        rv << element if element.kind_of? Element
      }
      rv.each do |element|
        @element.delete element
        element.remove
      end
      return rv
    end

    # Adds an element
    # element:: 
    #   if supplied, is either an Element, String, or
    #   Source (see Element.initialize).  If not supplied or nil, a
    #   new, default Element will be constructed
    # Returns:: the added Element
    #  a = Element.new('a')
    #  a.elements.add(Element.new('b'))  #-> <a><b/></a>
    #  a.elements.add('c')               #-> <a><b/><c/></a>
    def add element=nil
      rv = nil
      if element.nil?
        Element.new("", self, @element.context)
      elsif not element.kind_of?(Element)
        Element.new(element, self, @element.context)
      else
        @element << element
        element.context = @element.context
        element
      end
    end

    alias :<< :add

    # Iterates through all of the child Elements, optionally filtering
    # them by a given XPath
    # xpath:: 
    #   optional.  If supplied, this is a String XPath, and is used to 
    #   filter the children, so that only matching children are yielded.  Note
    #   that XPaths are automatically filtered for Elements, so that
    #   non-Element children will not be yielded
    #  doc = Document.new '<a><b/><c/><d/>sean<b/><c/><d/></a>'
    #  doc.root.each {|e|p e}       #-> Yields b, c, d, b, c, d elements
    #  doc.root.each('b') {|e|p e}  #-> Yields b, b elements
    #  doc.root.each('child::node()')  {|e|p e}
    #  #-> Yields <b/>, <c/>, <d/>, <b/>, <c/>, <d/>
    #  XPath.each(doc.root, 'child::node()', &block)
    #  #-> Yields <b/>, <c/>, <d/>, sean, <b/>, <c/>, <d/>
    def each( xpath=nil, &block)
      XPath::each( @element, xpath ) {|e| yield e if e.kind_of? Element }
    end

    def collect( xpath=nil, &block )
      collection = []
      XPath::each( @element, xpath ) {|e| 
        collection << yield(e)  if e.kind_of?(Element) 
      }
      collection
    end

    def inject( xpath=nil, initial=nil, &block )
      first = true
      XPath::each( @element, xpath ) {|e|
        if (e.kind_of? Element)
          if (first and initial == nil)
            initial = e
            first = false
          else
            initial = yield( initial, e ) if e.kind_of? Element
          end
        end
      }
      initial
    end

    # Returns the number of +Element+ children of the parent object.
    #  doc = Document.new '<a>sean<b/>elliott<b/>russell<b/></a>'
    #  doc.root.size            #-> 6, 3 element and 3 text nodes
    #  doc.root.elements.size   #-> 3
    def size
      count = 0
      @element.each {|child| count+=1 if child.kind_of? Element }
      count
    end

    # Returns an Array of Element children.  An XPath may be supplied to
    # filter the children.  Only Element children are returned, even if the
    # supplied XPath matches non-Element children.
    #  doc = Document.new '<a>sean<b/>elliott<c/></a>'
    #  doc.root.elements.to_a                  #-> [ <b/>, <c/> ]
    #  doc.root.elements.to_a("child::node()") #-> [ <b/>, <c/> ] 
    #  XPath.match(doc.root, "child::node()")  #-> [ sean, <b/>, elliott, <c/> ]
    def to_a( xpath=nil )
      rv = XPath.match( @element, xpath )
      return rv.find_all{|e| e.kind_of? Element} if xpath
      rv
    end

    private
    # Private helper class.  Removes quotes from quoted strings
    def literalize name
      name = name[1..-2] if name[0] == ?' or name[0] == ?"               #'
      name
    end
  end

  ########################################################################
  # ATTRIBUTES                                                           #
  ########################################################################

  # A class that defines the set of Attributes of an Element and provides 
  # operations for accessing elements in that set.
  class Attributes < Hash
    # Constructor
    # element:: the Element of which this is an Attribute
    def initialize element
      @element = element
    end

    # Fetches an attribute value.  If you want to get the Attribute itself,
    # use get_attribute()
    # name:: an XPath attribute name.  Namespaces are relevant here.
    # Returns:: 
    #   the String value of the matching attribute, or +nil+ if no
    #   matching attribute was found.  This is the unnormalized value
    #   (with entities expanded).
    # 
    #  doc = Document.new "<a foo:att='1' bar:att='2' att='&lt;'/>"
    #  doc.root.attributes['att']         #-> '<'
    #  doc.root.attributes['bar:att']     #-> '2'
    def [](name)
      attr = get_attribute(name)
      return attr.value unless attr.nil?
      return nil
    end

    def to_a
      values.flatten
    end

    # Returns the number of attributes the owning Element contains.
    #  doc = Document "<a x='1' y='2' foo:x='3'/>"
    #  doc.root.attributes.length        #-> 3
    def length
      c = 0
      each_attribute { c+=1 }
      c
    end
    alias :size :length

    # Iterates over the attributes of an Element.  Yields actual Attribute
    # nodes, not String values.
    # 
    #  doc = Document.new '<a x="1" y="2"/>'
    #  doc.root.attributes.each_attribute {|attr|
    #    p attr.expanded_name+" => "+attr.value
    #  }
    def each_attribute # :yields: attribute
      each_value do |val|
        if val.kind_of? Attribute
          yield val
        else
          val.each_value { |atr| yield atr }
        end
      end
    end

    # Iterates over each attribute of an Element, yielding the expanded name
    # and value as a pair of Strings.
    #
    #  doc = Document.new '<a x="1" y="2"/>'
    #  doc.root.attributes.each {|name, value| p name+" => "+value }
    def each
      each_attribute do |attr|
        yield attr.expanded_name, attr.value
      end
    end

    # Fetches an attribute
    # name:: 
    #   the name by which to search for the attribute.  Can be a
    #   <tt>prefix:name</tt> namespace name.
    # Returns:: The first matching attribute, or nil if there was none.  This
    # value is an Attribute node, not the String value of the attribute.
    #  doc = Document.new '<a x:foo="1" foo="2" bar="3"/>'
    #  doc.root.attributes.get_attribute("foo").value    #-> "2"
    #  doc.root.attributes.get_attribute("x:foo").value  #-> "1"
    def get_attribute( name )
      attr = fetch( name, nil )
      if attr.nil?
        return nil if name.nil?
        # Look for prefix
        name =~ Namespace::NAMESPLIT
        prefix, n = $1, $2
        if prefix
          attr = fetch( n, nil )
          # check prefix
          if attr == nil
          elsif attr.kind_of? Attribute
            return attr if prefix == attr.prefix
          else
            attr = attr[ prefix ]
            return attr
          end
        end
        element_document = @element.document
        if element_document and element_document.doctype
          expn = @element.expanded_name
          expn = element_document.doctype.name if expn.size == 0
          attr_val = element_document.doctype.attribute_of(expn, name)
          return Attribute.new( name, attr_val ) if attr_val
        end
        return nil
      end
      if attr.kind_of? Hash
        attr = attr[ @element.prefix ]
      end
      return attr
    end

    # Sets an attribute, overwriting any existing attribute value by the
    # same name.  Namespace is significant.
    # name:: the name of the attribute
    # value:: 
    #   (optional) If supplied, the value of the attribute.  If
    #   nil, any existing matching attribute is deleted.
    # Returns:: 
    #   Owning element
    #  doc = Document.new "<a x:foo='1' foo='3'/>"
    #  doc.root.attributes['y:foo'] = '2'
    #  doc.root.attributes['foo'] = '4'
    #  doc.root.attributes['x:foo'] = nil
    def []=( name, value )
      if value.nil?		# Delete the named attribute
        attr = get_attribute(name)
        delete attr
        return
      end
      element_document = @element.document
      unless value.kind_of? Attribute
        if @element.document and @element.document.doctype
          value = Text::normalize( value, @element.document.doctype )
        else
          value = Text::normalize( value, nil )
        end
        value = Attribute.new(name, value)
      end
      value.element = @element
      old_attr = fetch(value.name, nil)
      if old_attr.nil?
        store(value.name, value)
      elsif old_attr.kind_of? Hash
        old_attr[value.prefix] = value
      elsif old_attr.prefix != value.prefix
        # Check for conflicting namespaces
        raise ParseException.new( 
          "Namespace conflict in adding attribute \"#{value.name}\": "+
          "Prefix \"#{old_attr.prefix}\" = "+
          "\"#{@element.namespace(old_attr.prefix)}\" and prefix "+
          "\"#{value.prefix}\" = \"#{@element.namespace(value.prefix)}\"") if 
          value.prefix != "xmlns" and old_attr.prefix != "xmlns" and
          @element.namespace( old_attr.prefix ) == 
            @element.namespace( value.prefix )
          store value.name, { old_attr.prefix	=> old_attr,
            value.prefix		=> value }
      else
        store value.name, value
      end
      return @element
    end

    # Returns an array of Strings containing all of the prefixes declared 
    # by this set of # attributes.  The array does not include the default
    # namespace declaration, if one exists.
    #  doc = Document.new("<a xmlns='foo' xmlns:x='bar' xmlns:y='twee' "+
    #        "z='glorp' p:k='gru'/>")
    #  prefixes = doc.root.attributes.prefixes    #-> ['x', 'y']
    def prefixes
      ns = []
      each_attribute do |attribute|
        ns << attribute.name if attribute.prefix == 'xmlns'
      end
      if @element.document and @element.document.doctype
        expn = @element.expanded_name
        expn = @element.document.doctype.name if expn.size == 0
        @element.document.doctype.attributes_of(expn).each {
          |attribute|
          ns << attribute.name if attribute.prefix == 'xmlns'
        }
      end
      ns
    end

    def namespaces
      namespaces = {}
      each_attribute do |attribute|
        namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
      end
      if @element.document and @element.document.doctype
        expn = @element.expanded_name
        expn = @element.document.doctype.name if expn.size == 0
        @element.document.doctype.attributes_of(expn).each {
          |attribute|
          namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
        }
      end
      namespaces
    end

    # Removes an attribute
    # attribute:: 
    #   either a String, which is the name of the attribute to remove --
    #   namespaces are significant here -- or the attribute to remove.
    # Returns:: the owning element
    #  doc = Document.new "<a y:foo='0' x:foo='1' foo='3' z:foo='4'/>"
    #  doc.root.attributes.delete 'foo'   #-> <a y:foo='0' x:foo='1' z:foo='4'/>"
    #  doc.root.attributes.delete 'x:foo' #-> <a y:foo='0' z:foo='4'/>"
    #  attr = doc.root.attributes.get_attribute('y:foo')
    #  doc.root.attributes.delete attr    #-> <a z:foo='4'/>"
    def delete( attribute )
      name = nil
      prefix = nil
      if attribute.kind_of? Attribute
        name = attribute.name
        prefix = attribute.prefix
      else
        attribute =~ Namespace::NAMESPLIT
        prefix, name = $1, $2
        prefix = '' unless prefix
      end
      old = fetch(name, nil)
      attr = nil
      if old.kind_of? Hash # the supplied attribute is one of many
        attr = old.delete(prefix)
        if old.size == 1
          repl = nil
          old.each_value{|v| repl = v}
          store name, repl
        end
      elsif old.nil?
        return @element
      else # the supplied attribute is a top-level one
        attr = old
        res = super(name)
      end
      @element
    end

    # Adds an attribute, overriding any existing attribute by the
    # same name.  Namespaces are significant.
    # attribute:: An Attribute
    def add( attribute )
      self[attribute.name] = attribute
    end

    alias :<< :add

    # Deletes all attributes matching a name.  Namespaces are significant.
    # name:: 
    #   A String; all attributes that match this path will be removed
    # Returns:: an Array of the Attributes that were removed
    def delete_all( name )
      rv = []
      each_attribute { |attribute| 
        rv << attribute if attribute.expanded_name == name
      }
      rv.each{ |attr| attr.remove }
      return rv
    end

    # The +get_attribute_ns+ method retrieves a method by its namespace
    # and name. Thus it is possible to reliably identify an attribute
    # even if an XML processor has changed the prefix.
    # 
    # Method contributed by Henrik Martensson
    def get_attribute_ns(namespace, name)
      each_attribute() { |attribute|
        if name == attribute.name &&
          namespace == attribute.namespace()
          return attribute
        end
      }
      nil
    end
  end
end
PK     Y\Jq|      rexml/cdata.rbnu [        require "rexml/text"

module REXML
	class CData < Text
		START = '<![CDATA['
		STOP = ']]>'
		ILLEGAL = /(\]\]>)/

		#	Constructor.  CData is data between <![CDATA[ ... ]]>
		#
		# _Examples_
		#  CData.new( source )
		#  CData.new( "Here is some CDATA" )
		#  CData.new( "Some unprocessed data", respect_whitespace_TF, parent_element )
		def initialize( first, whitespace=true, parent=nil )
			super( first, whitespace, parent, true, true, ILLEGAL )
		end

		# Make a copy of this object
		# 
		# _Examples_
		#  c = CData.new( "Some text" )
		#  d = c.clone
		#  d.to_s        # -> "Some text"
		def clone
			CData.new self
		end

		# Returns the content of this CData object
		#
		# _Examples_
		#  c = CData.new( "Some text" )
		#  c.to_s        # -> "Some text"
		def to_s
			@string
		end

    def value
      @string
    end

    # == DEPRECATED
    # See the rexml/formatters package
    #
		# Generates XML output of this object
		#
		# output::
		#   Where to write the string.  Defaults to $stdout
		# indent::
    #   The amount to indent this node by
		# transitive::
    #   Ignored
		# ie_hack::
    #   Ignored
		#
		# _Examples_
		#  c = CData.new( " Some text " )
		#  c.write( $stdout )     #->  <![CDATA[ Some text ]]>
		def write( output=$stdout, indent=-1, transitive=false, ie_hack=false )
      Kernel.warn( "#{self.class.name}.write is deprecated" )
			indent( output, indent )
			output << START
			output << @string
			output << STOP
		end
	end
end
PK     Y\      rexml/attribute.rbnu [        require "rexml/namespace"
require 'rexml/text'

module REXML
	# Defines an Element Attribute; IE, a attribute=value pair, as in:
	# <element attribute="value"/>.  Attributes can be in their own
	# namespaces.  General users of REXML will not interact with the
	# Attribute class much.
	class Attribute
		include Node
		include Namespace

		# The element to which this attribute belongs
		attr_reader :element
		# The normalized value of this attribute.  That is, the attribute with
		# entities intact.
		attr_writer :normalized	
		PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\2/um

		# Constructor.
    # FIXME: The parser doesn't catch illegal characters in attributes
    #
    # first:: 
    #   Either: an Attribute, which this new attribute will become a
    #   clone of; or a String, which is the name of this attribute
    # second::
    #   If +first+ is an Attribute, then this may be an Element, or nil.
    #   If nil, then the Element parent of this attribute is the parent
    #   of the +first+ Attribute.  If the first argument is a String, 
    #   then this must also be a String, and is the content of the attribute.  
    #   If this is the content, it must be fully normalized (contain no
    #   illegal characters).
    # parent::
    #   Ignored unless +first+ is a String; otherwise, may be the Element 
    #   parent of this attribute, or nil.
    #
		#
		#  Attribute.new( attribute_to_clone )
		#  Attribute.new( attribute_to_clone, parent_element )
		#  Attribute.new( "attr", "attr_value" )
		#  Attribute.new( "attr", "attr_value", parent_element )
		def initialize( first, second=nil, parent=nil )
			@normalized = @unnormalized = @element = nil
			if first.kind_of? Attribute
				self.name = first.expanded_name
				@unnormalized = first.value
				if second.kind_of? Element
					@element = second
				else
					@element = first.element
				end
			elsif first.kind_of? String
				@element = parent
				self.name = first
				@normalized = second.to_s
			else
				raise "illegal argument #{first.class.name} to Attribute constructor"
			end
		end

		# Returns the namespace of the attribute.
		# 
		#  e = Element.new( "elns:myelement" )
		#  e.add_attribute( "nsa:a", "aval" )
		#  e.add_attribute( "b", "bval" )
		#  e.attributes.get_attribute( "a" ).prefix   # -> "nsa"
		#  e.attributes.get_attribute( "b" ).prefix   # -> "elns"
		#  a = Attribute.new( "x", "y" )
		#  a.prefix                                   # -> ""
		def prefix
			pf = super
			if pf == ""
				pf = @element.prefix if @element
			end
			pf
		end

		# Returns the namespace URL, if defined, or nil otherwise
		# 
		#  e = Element.new("el")
		#  e.add_attributes({"xmlns:ns", "http://url"})
		#  e.namespace( "ns" )              # -> "http://url"
		def namespace arg=nil
			arg = prefix if arg.nil?
			@element.namespace arg
		end

		# Returns true if other is an Attribute and has the same name and value,
		# false otherwise.
		def ==( other )
			other.kind_of?(Attribute) and other.name==name and other.value==value
		end

		# Creates (and returns) a hash from both the name and value
		def hash
			name.hash + value.hash
		end

		# Returns this attribute out as XML source, expanding the name
		#
		#  a = Attribute.new( "x", "y" )
		#  a.to_string     # -> "x='y'"
		#  b = Attribute.new( "ns:x", "y" )
		#  b.to_string     # -> "ns:x='y'"
		def to_string
			if @element and @element.context and @element.context[:attribute_quote] == :quote
				%Q^#@expanded_name="#{to_s().gsub(/"/, '&quote;')}"^
			else
				"#@expanded_name='#{to_s().gsub(/'/, '&apos;')}'"
			end
		end

		# Returns the attribute value, with entities replaced
		def to_s
			return @normalized if @normalized

			doctype = nil
			if @element
				doc = @element.document
				doctype = doc.doctype if doc
			end

			@normalized = Text::normalize( @unnormalized, doctype )
			@unnormalized = nil
      @normalized
		end

		# Returns the UNNORMALIZED value of this attribute.  That is, entities
		# have been expanded to their values
		def value
			return @unnormalized if @unnormalized
			doctype = nil
			if @element
				doc = @element.document
				doctype = doc.doctype if doc
			end
			@unnormalized = Text::unnormalize( @normalized, doctype )
			@normalized = nil
      @unnormalized
		end

		# Returns a copy of this attribute
		def clone
			Attribute.new self
		end

		# Sets the element of which this object is an attribute.  Normally, this
		# is not directly called.
		#
		# Returns this attribute
		def element=( element )
			@element = element
			self
		end

		# Removes this Attribute from the tree, and returns true if successfull
		# 
		# This method is usually not called directly.
		def remove
			@element.attributes.delete self.name unless @element.nil?
		end

		# Writes this attribute (EG, puts 'key="value"' to the output)
		def write( output, indent=-1 )
			output << to_string
		end

    def node_type
      :attribute
    end

    def inspect
      rv = ""
      write( rv )
      rv
    end

    def xpath
      path = @element.xpath
      path += "/@#{self.expanded_name}"
      return path
    end
	end
end
#vim:ts=2 sw=2 noexpandtab:
PK     Y\	  	    rexml/child.rbnu [        require "rexml/node"

module REXML
	##
	# A Child object is something contained by a parent, and this class
	# contains methods to support that.  Most user code will not use this
	# class directly.
	class Child
		include Node
		attr_reader :parent		# The Parent of this object

		# Constructor.  Any inheritors of this class should call super to make
		# sure this method is called.
		# parent::
		#   if supplied, the parent of this child will be set to the
		#   supplied value, and self will be added to the parent
		def initialize( parent = nil )
			@parent = nil  
			# Declare @parent, but don't define it.  The next line sets the 
			# parent.
			parent.add( self ) if parent
		end

		# Replaces this object with another object.  Basically, calls
		# Parent.replace_child
		#
		# Returns:: self
		def replace_with( child )
			@parent.replace_child( self, child )
			self
		end

		# Removes this child from the parent.
		#
		# Returns:: self
		def remove
			unless @parent.nil?
				@parent.delete self
			end
			self
		end

		# Sets the parent of this child to the supplied argument.
		#
		# other::
		#   Must be a Parent object.  If this object is the same object as the
		#   existing parent of this child, no action is taken. Otherwise, this
		#   child is removed from the current parent (if one exists), and is added
		#   to the new parent.
		# Returns:: The parent added
		def parent=( other )
			return @parent if @parent == other
			@parent.delete self if defined? @parent and @parent
			@parent = other
		end

		alias :next_sibling :next_sibling_node
		alias :previous_sibling :previous_sibling_node

		# Sets the next sibling of this child.  This can be used to insert a child
		# after some other child.
		#  a = Element.new("a")
		#  b = a.add_element("b")
		#  c = Element.new("c")
		#  b.next_sibling = c
		#  # => <a><b/><c/></a>
		def next_sibling=( other )
		  parent.insert_after self, other
		end

		# Sets the previous sibling of this child.  This can be used to insert a 
		# child before some other child.
		#  a = Element.new("a")
		#  b = a.add_element("b")
		#  c = Element.new("c")
		#  b.previous_sibling = c
		#  # => <a><b/><c/></a>
		def previous_sibling=(other)
		  parent.insert_before self, other
		end

		# Returns:: the document this child belongs to, or nil if this child
		# belongs to no document
		def document
			return parent.document unless parent.nil?
			nil
		end

		# This doesn't yet handle encodings
		def bytes
			encoding = document.encoding

			to_s
		end
	end
end
PK     Y\d  d    rexml/xpath_parser.rbnu [        require 'rexml/namespace'
require 'rexml/xmltokens'
require 'rexml/attribute'
require 'rexml/syncenumerator'
require 'rexml/parsers/xpathparser'

class Object
  def dclone
    clone
  end
end
class Symbol
  def dclone ; self ; end
end
class Fixnum
  def dclone ; self ; end
end
class Float
  def dclone ; self ; end
end
class Array
  def dclone
    klone = self.clone
    klone.clear
    self.each{|v| klone << v.dclone}
    klone
  end
end

module REXML
  # You don't want to use this class.  Really.  Use XPath, which is a wrapper
  # for this class.  Believe me.  You don't want to poke around in here.
  # There is strange, dark magic at work in this code.  Beware.  Go back!  Go
  # back while you still can!
  class XPathParser
    include XMLTokens
    LITERAL    = /^'([^']*)'|^"([^"]*)"/u

    def initialize( )
      @parser = REXML::Parsers::XPathParser.new
      @namespaces = nil
      @variables = {}
    end

    def namespaces=( namespaces={} )
      Functions::namespace_context = namespaces
      @namespaces = namespaces
    end

    def variables=( vars={} )
      Functions::variables = vars
      @variables = vars
    end

    def parse path, nodeset
     #puts "#"*40
     path_stack = @parser.parse( path )
     #puts "PARSE: #{path} => #{path_stack.inspect}"
     #puts "PARSE: nodeset = #{nodeset.inspect}"
     match( path_stack, nodeset )
    end

    def get_first path, nodeset
     #puts "#"*40
     path_stack = @parser.parse( path )
     #puts "PARSE: #{path} => #{path_stack.inspect}"
     #puts "PARSE: nodeset = #{nodeset.inspect}"
     first( path_stack, nodeset )
    end

    def predicate path, nodeset
      path_stack = @parser.parse( path )
      expr( path_stack, nodeset )
    end

    def []=( variable_name, value )
      @variables[ variable_name ] = value
    end


    # Performs a depth-first (document order) XPath search, and returns the
    # first match.  This is the fastest, lightest way to return a single result.
    #
    # FIXME: This method is incomplete!
    def first( path_stack, node )
      #puts "#{depth}) Entering match( #{path.inspect}, #{tree.inspect} )"
      return nil if path.size == 0

      case path[0]
      when :document
        # do nothing 
        return first( path[1..-1], node )
      when :child
        for c in node.children
          #puts "#{depth}) CHILD checking #{name(c)}"
          r = first( path[1..-1], c )
          #puts "#{depth}) RETURNING #{r.inspect}" if r
          return r if r
        end
      when :qname
        name = path[2]
        #puts "#{depth}) QNAME #{name(tree)} == #{name} (path => #{path.size})"
        if node.name == name
          #puts "#{depth}) RETURNING #{tree.inspect}" if path.size == 3
          return node if path.size == 3
          return first( path[3..-1], node )
        else
          return nil
        end
      when :descendant_or_self
        r = first( path[1..-1], node )
        return r if r
        for c in node.children
          r = first( path, c )
          return r if r
        end
      when :node
        return first( path[1..-1], node )
      when :any
        return first( path[1..-1], node )
      end
      return nil
    end


    def match( path_stack, nodeset ) 
      #puts "MATCH: path_stack = #{path_stack.inspect}"
      #puts "MATCH: nodeset = #{nodeset.inspect}"
      r = expr( path_stack, nodeset )
      #puts "MAIN EXPR => #{r.inspect}"
      r
    end

    private


    # Returns a String namespace for a node, given a prefix
    # The rules are:
    # 
    #  1. Use the supplied namespace mapping first.
    #  2. If no mapping was supplied, use the context node to look up the namespace
    def get_namespace( node, prefix )
      if @namespaces
        return @namespaces[prefix] || ''
      else
        return node.namespace( prefix ) if node.node_type == :element
        return ''
      end
    end


    # Expr takes a stack of path elements and a set of nodes (either a Parent
    # or an Array and returns an Array of matching nodes
    ALL = [ :attribute, :element, :text, :processing_instruction, :comment ]
    ELEMENTS = [ :element ]
    def expr( path_stack, nodeset, context=nil )
      #puts "#"*15
      #puts "In expr with #{path_stack.inspect}"
      #puts "Returning" if path_stack.length == 0 || nodeset.length == 0
      node_types = ELEMENTS
      return nodeset if path_stack.length == 0 || nodeset.length == 0
      while path_stack.length > 0
        #puts "#"*5
        #puts "Path stack = #{path_stack.inspect}"
        #puts "Nodeset is #{nodeset.inspect}"
        if nodeset.length == 0
          path_stack.clear
          return []
        end
        case (op = path_stack.shift)
        when :document
          nodeset = [ nodeset[0].root_node ]
          #puts ":document, nodeset = #{nodeset.inspect}"

        when :qname
          #puts "IN QNAME"
          prefix = path_stack.shift
          name = path_stack.shift
          nodeset.delete_if do |node|
            # FIXME: This DOUBLES the time XPath searches take
            ns = get_namespace( node, prefix )
            #puts "NS = #{ns.inspect}"
            #puts "node.node_type == :element => #{node.node_type == :element}"
            if node.node_type == :element
              #puts "node.name == #{name} => #{node.name == name}"
              if node.name == name
                #puts "node.namespace == #{ns.inspect} => #{node.namespace == ns}"
              end
            end
            !(node.node_type == :element and 
              node.name == name and 
              node.namespace == ns )
          end
          node_types = ELEMENTS

        when :any
          #puts "ANY 1: nodeset = #{nodeset.inspect}"
          #puts "ANY 1: node_types = #{node_types.inspect}"
          nodeset.delete_if { |node| !node_types.include?(node.node_type) }
          #puts "ANY 2: nodeset = #{nodeset.inspect}"

        when :self
          # This space left intentionally blank

        when :processing_instruction
          target = path_stack.shift
          nodeset.delete_if do |node|
            (node.node_type != :processing_instruction) or 
            ( target!='' and ( node.target != target ) )
          end

        when :text
          nodeset.delete_if { |node| node.node_type != :text }

        when :comment
          nodeset.delete_if { |node| node.node_type != :comment }

        when :node
          # This space left intentionally blank
          node_types = ALL

        when :child
          new_nodeset = []
          nt = nil
          for node in nodeset
            nt = node.node_type
            new_nodeset += node.children if nt == :element or nt == :document
          end
          nodeset = new_nodeset
          node_types = ELEMENTS

        when :literal
          return path_stack.shift
        
        when :attribute
          new_nodeset = []
          case path_stack.shift
          when :qname
            prefix = path_stack.shift
            name = path_stack.shift
            for element in nodeset
              if element.node_type == :element
                #puts "Element name = #{element.name}"
                #puts "get_namespace( #{element.inspect}, #{prefix} ) = #{get_namespace(element, prefix)}"
                attrib = element.attribute( name, get_namespace(element, prefix) )
                #puts "attrib = #{attrib.inspect}"
                new_nodeset << attrib if attrib
              end
            end
          when :any
            #puts "ANY"
            for element in nodeset
              if element.node_type == :element
                new_nodeset += element.attributes.to_a
              end
            end
          end
          nodeset = new_nodeset

        when :parent
          #puts "PARENT 1: nodeset = #{nodeset}"
          nodeset = nodeset.collect{|n| n.parent}.compact
          #nodeset = expr(path_stack.dclone, nodeset.collect{|n| n.parent}.compact)
          #puts "PARENT 2: nodeset = #{nodeset.inspect}"
          node_types = ELEMENTS

        when :ancestor
          new_nodeset = []
          for node in nodeset
            while node.parent
              node = node.parent
              new_nodeset << node unless new_nodeset.include? node
            end
          end
          nodeset = new_nodeset
          node_types = ELEMENTS

        when :ancestor_or_self
          new_nodeset = []
          for node in nodeset
            if node.node_type == :element
              new_nodeset << node
              while ( node.parent )
                node = node.parent
                new_nodeset << node unless new_nodeset.include? node
              end
            end
          end
          nodeset = new_nodeset
          node_types = ELEMENTS

        when :predicate
          new_nodeset = []
          subcontext = { :size => nodeset.size }
          pred = path_stack.shift
          nodeset.each_with_index { |node, index|
            subcontext[ :node ] = node
            #puts "PREDICATE SETTING CONTEXT INDEX TO #{index+1}"
            subcontext[ :index ] = index+1
            pc = pred.dclone
            #puts "#{node.hash}) Recursing with #{pred.inspect} and [#{node.inspect}]"
            result = expr( pc, [node], subcontext )
            result = result[0] if result.kind_of? Array and result.length == 1
            #puts "#{node.hash}) Result = #{result.inspect} (#{result.class.name})"
            if result.kind_of? Numeric
              #puts "Adding node #{node.inspect}" if result == (index+1)
              new_nodeset << node if result == (index+1)
            elsif result.instance_of? Array
              if result.size > 0 and result.inject(false) {|k,s| s or k}
                #puts "Adding node #{node.inspect}" if result.size > 0
                new_nodeset << node if result.size > 0
              end
            else
              #puts "Adding node #{node.inspect}" if result
              new_nodeset << node if result
            end
          }
          #puts "New nodeset = #{new_nodeset.inspect}"
          #puts "Path_stack  = #{path_stack.inspect}"
          nodeset = new_nodeset
=begin
          predicate = path_stack.shift
          ns = nodeset.clone
          result = expr( predicate, ns )
          #puts "Result = #{result.inspect} (#{result.class.name})"
          #puts "nodeset = #{nodeset.inspect}"
          if result.kind_of? Array
            nodeset = result.zip(ns).collect{|m,n| n if m}.compact
          else
            nodeset = result ? nodeset : []
          end
          #puts "Outgoing NS = #{nodeset.inspect}"
=end

        when :descendant_or_self
          rv = descendant_or_self( path_stack, nodeset )
          path_stack.clear
          nodeset = rv
          node_types = ELEMENTS

        when :descendant
          results = []
          nt = nil
          for node in nodeset
            nt = node.node_type
            results += expr( path_stack.dclone.unshift( :descendant_or_self ),
              node.children ) if nt == :element or nt == :document
          end
          nodeset = results
          node_types = ELEMENTS

        when :following_sibling
          #puts "FOLLOWING_SIBLING 1: nodeset = #{nodeset}"
          results = []
          nodeset.each do |node|
            next if node.parent.nil?
            all_siblings = node.parent.children
            current_index = all_siblings.index( node )
            following_siblings = all_siblings[ current_index+1 .. -1 ]
            results += expr( path_stack.dclone, following_siblings )
          end
          #puts "FOLLOWING_SIBLING 2: nodeset = #{nodeset}"
          nodeset = results

        when :preceding_sibling
          results = []
          nodeset.each do |node|
            next if node.parent.nil?
            all_siblings = node.parent.children
            current_index = all_siblings.index( node )
            preceding_siblings = all_siblings[ 0, current_index ].reverse
            results += preceding_siblings
          end
          nodeset = results
          node_types = ELEMENTS

        when :preceding
          new_nodeset = []
          for node in nodeset
            new_nodeset += preceding( node )
          end
          #puts "NEW NODESET => #{new_nodeset.inspect}"
          nodeset = new_nodeset
          node_types = ELEMENTS

        when :following
          new_nodeset = []
          for node in nodeset
            new_nodeset += following( node )
          end
          nodeset = new_nodeset
          node_types = ELEMENTS

        when :namespace
          #puts "In :namespace"
          new_nodeset = []
          prefix = path_stack.shift
          for node in nodeset
            if (node.node_type == :element or node.node_type == :attribute)
              if @namespaces
                namespaces = @namespaces
              elsif (node.node_type == :element)
                namespaces = node.namespaces
              else
                namespaces = node.element.namesapces
              end
              #puts "Namespaces = #{namespaces.inspect}"
              #puts "Prefix = #{prefix.inspect}"
              #puts "Node.namespace = #{node.namespace}"
              if (node.namespace == namespaces[prefix])
                new_nodeset << node
              end
            end
          end
          nodeset = new_nodeset

        when :variable
          var_name = path_stack.shift
          return @variables[ var_name ]

        # :and, :or, :eq, :neq, :lt, :lteq, :gt, :gteq
				# TODO: Special case for :or and :and -- not evaluate the right
				# operand if the left alone determines result (i.e. is true for
				# :or and false for :and).
        when :eq, :neq, :lt, :lteq, :gt, :gteq, :and, :or
          left = expr( path_stack.shift, nodeset.dup, context )
          #puts "LEFT => #{left.inspect} (#{left.class.name})"
          right = expr( path_stack.shift, nodeset.dup, context )
          #puts "RIGHT => #{right.inspect} (#{right.class.name})"
          res = equality_relational_compare( left, op, right )
          #puts "RES => #{res.inspect}"
          return res

        when :and
          left = expr( path_stack.shift, nodeset.dup, context )
          #puts "LEFT => #{left.inspect} (#{left.class.name})"
          if left == false || left.nil? || !left.inject(false) {|a,b| a | b}
            return []
          end
          right = expr( path_stack.shift, nodeset.dup, context )
          #puts "RIGHT => #{right.inspect} (#{right.class.name})"
          res = equality_relational_compare( left, op, right )
          #puts "RES => #{res.inspect}"
          return res

        when :div
          left = Functions::number(expr(path_stack.shift, nodeset, context)).to_f
          right = Functions::number(expr(path_stack.shift, nodeset, context)).to_f
          return (left / right)

        when :mod
          left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
          right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
          return (left % right)

        when :mult
          left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
          right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
          return (left * right)

        when :plus
          left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
          right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
          return (left + right)

        when :minus
          left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
          right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
          return (left - right)

        when :union
          left = expr( path_stack.shift, nodeset, context )
          right = expr( path_stack.shift, nodeset, context )
          return (left | right)

        when :neg
          res = expr( path_stack, nodeset, context )
          return -(res.to_f)

        when :not
        when :function
          func_name = path_stack.shift.tr('-','_')
          arguments = path_stack.shift
          #puts "FUNCTION 0: #{func_name}(#{arguments.collect{|a|a.inspect}.join(', ')})" 
          subcontext = context ? nil : { :size => nodeset.size }

          res = []
          cont = context
          nodeset.each_with_index { |n, i| 
            if subcontext
              subcontext[:node]  = n
              subcontext[:index] = i
              cont = subcontext
            end
            arg_clone = arguments.dclone
            args = arg_clone.collect { |arg| 
              #puts "FUNCTION 1: Calling expr( #{arg.inspect}, [#{n.inspect}] )"
              expr( arg, [n], cont ) 
            }
            #puts "FUNCTION 2: #{func_name}(#{args.collect{|a|a.inspect}.join(', ')})" 
            Functions.context = cont
            res << Functions.send( func_name, *args )
            #puts "FUNCTION 3: #{res[-1].inspect}"
          }
          return res

        end
      end # while
      #puts "EXPR returning #{nodeset.inspect}"
      return nodeset
    end


    ##########################################################
    # FIXME
    # The next two methods are BAD MOJO!
    # This is my achilles heel.  If anybody thinks of a better
    # way of doing this, be my guest.  This really sucks, but 
    # it is a wonder it works at all.
    # ########################################################
    
    def descendant_or_self( path_stack, nodeset )
      rs = []
      #puts "#"*80
      #puts "PATH_STACK = #{path_stack.inspect}"
      #puts "NODESET = #{nodeset.collect{|n|n.inspect}.inspect}"
      d_o_s( path_stack, nodeset, rs )
      #puts "RS = #{rs.collect{|n|n.inspect}.inspect}"
      document_order(rs.flatten.compact)
      #rs.flatten.compact
    end

    def d_o_s( p, ns, r )
      #puts "IN DOS with #{ns.inspect}; ALREADY HAVE #{r.inspect}"
      nt = nil
      ns.each_index do |i|
        n = ns[i]
        #puts "P => #{p.inspect}"
        x = expr( p.dclone, [ n ] )
        nt = n.node_type
        d_o_s( p, n.children, x ) if nt == :element or nt == :document and n.children.size > 0
        r.concat(x) if x.size > 0
      end
    end


    # Reorders an array of nodes so that they are in document order
    # It tries to do this efficiently.
    #
    # FIXME: I need to get rid of this, but the issue is that most of the XPath 
    # interpreter functions as a filter, which means that we lose context going
    # in and out of function calls.  If I knew what the index of the nodes was,
    # I wouldn't have to do this.  Maybe add a document IDX for each node?
    # Problems with mutable documents.  Or, rewrite everything.
    def document_order( array_of_nodes )
      new_arry = []
      array_of_nodes.each { |node|
        node_idx = [] 
        np = node.node_type == :attribute ? node.element : node
        while np.parent and np.parent.node_type == :element
          node_idx << np.parent.index( np )
          np = np.parent
        end
        new_arry << [ node_idx.reverse, node ]
      }
      #puts "new_arry = #{new_arry.inspect}"
      new_arry.sort{ |s1, s2| s1[0] <=> s2[0] }.collect{ |s| s[1] }
    end


    def recurse( nodeset, &block )
      for node in nodeset
        yield node
        recurse( node, &block ) if node.node_type == :element
      end
    end



    # Builds a nodeset of all of the preceding nodes of the supplied node,
    # in reverse document order
    # preceding:: includes every element in the document that precedes this node, 
    # except for ancestors
    def preceding( node )
      #puts "IN PRECEDING"
      ancestors = []
      p = node.parent
      while p
        ancestors << p
        p = p.parent
      end

      acc = []
      p = preceding_node_of( node )
      #puts "P = #{p.inspect}"
      while p
        if ancestors.include? p
          ancestors.delete(p)
        else
          acc << p
        end
        p = preceding_node_of( p )
        #puts "P = #{p.inspect}"
      end
      acc
    end

    def preceding_node_of( node )
     #puts "NODE: #{node.inspect}"
     #puts "PREVIOUS NODE: #{node.previous_sibling_node.inspect}"
     #puts "PARENT NODE: #{node.parent}"
      psn = node.previous_sibling_node 
      if psn.nil?
        if node.parent.nil? or node.parent.class == Document 
          return nil
        end
        return node.parent
        #psn = preceding_node_of( node.parent )
      end
      while psn and psn.kind_of? Element and psn.children.size > 0
        psn = psn.children[-1]
      end
      psn
    end

    def following( node )
      #puts "IN PRECEDING"
      acc = []
      p = next_sibling_node( node )
      #puts "P = #{p.inspect}"
      while p
        acc << p
        p = following_node_of( p )
        #puts "P = #{p.inspect}"
      end
      acc
    end

    def following_node_of( node )
      #puts "NODE: #{node.inspect}"
      #puts "PREVIOUS NODE: #{node.previous_sibling_node.inspect}"
      #puts "PARENT NODE: #{node.parent}"
      if node.kind_of? Element and node.children.size > 0
        return node.children[0]
      end
      return next_sibling_node(node)
    end

    def next_sibling_node(node)
      psn = node.next_sibling_node 
      while psn.nil?
        if node.parent.nil? or node.parent.class == Document 
          return nil
        end
        node = node.parent
        psn = node.next_sibling_node
        #puts "psn = #{psn.inspect}"
      end
      return psn
    end

    def norm b
      case b
      when true, false
        return b
      when 'true', 'false'
        return Functions::boolean( b )
      when /^\d+(\.\d+)?$/
        return Functions::number( b )
      else
        return Functions::string( b )
      end
    end

    def equality_relational_compare( set1, op, set2 )
      #puts "EQ_REL_COMP(#{set1.inspect} #{op.inspect} #{set2.inspect})"
      if set1.kind_of? Array and set2.kind_of? Array
			  #puts "#{set1.size} & #{set2.size}"
        if set1.size == 1 and set2.size == 1
          set1 = set1[0]
          set2 = set2[0]
        elsif set1.size == 0 or set2.size == 0
          nd = set1.size==0 ? set2 : set1
          rv = nd.collect { |il| compare( il, op, nil ) }
          #puts "RV = #{rv.inspect}"
          return rv
        else
          res = []
          enum = SyncEnumerator.new( set1, set2 ).each { |i1, i2|
            #puts "i1 = #{i1.inspect} (#{i1.class.name})"
            #puts "i2 = #{i2.inspect} (#{i2.class.name})"
            i1 = norm( i1 )
            i2 = norm( i2 )
            res << compare( i1, op, i2 )
          }
          return res
        end
      end
		  #puts "EQ_REL_COMP: #{set1.inspect} (#{set1.class.name}), #{op}, #{set2.inspect} (#{set2.class.name})"
      #puts "COMPARING VALUES"
      # If one is nodeset and other is number, compare number to each item
      # in nodeset s.t. number op number(string(item))
      # If one is nodeset and other is string, compare string to each item
      # in nodeset s.t. string op string(item)
      # If one is nodeset and other is boolean, compare boolean to each item
      # in nodeset s.t. boolean op boolean(item)
      if set1.kind_of? Array or set2.kind_of? Array
			  #puts "ISA ARRAY"
        if set1.kind_of? Array
          a = set1
          b = set2
        else
          a = set2
          b = set1
        end

        case b
        when true, false
          return a.collect {|v| compare( Functions::boolean(v), op, b ) }
        when Numeric
          return a.collect {|v| compare( Functions::number(v), op, b )}
        when /^\d+(\.\d+)?$/
          b = Functions::number( b )
          #puts "B = #{b.inspect}"
          return a.collect {|v| compare( Functions::number(v), op, b )}
        else
				  #puts "Functions::string( #{b}(#{b.class.name}) ) = #{Functions::string(b)}"
          b = Functions::string( b )
          return a.collect { |v| compare( Functions::string(v), op, b ) }
        end
      else
        # If neither is nodeset,
        #   If op is = or !=
        #     If either boolean, convert to boolean
        #     If either number, convert to number
        #     Else, convert to string
        #   Else
        #     Convert both to numbers and compare
        s1 = set1.to_s
        s2 = set2.to_s
        #puts "EQ_REL_COMP: #{set1}=>#{s1}, #{set2}=>#{s2}"
        if s1 == 'true' or s1 == 'false' or s2 == 'true' or s2 == 'false'
          #puts "Functions::boolean(#{set1})=>#{Functions::boolean(set1)}"
          #puts "Functions::boolean(#{set2})=>#{Functions::boolean(set2)}"
          set1 = Functions::boolean( set1 )
          set2 = Functions::boolean( set2 )
        else
          if op == :eq or op == :neq
            if s1 =~ /^\d+(\.\d+)?$/ or s2 =~ /^\d+(\.\d+)?$/
              set1 = Functions::number( s1 )
              set2 = Functions::number( s2 )
            else
              set1 = Functions::string( set1 )
              set2 = Functions::string( set2 )
            end
          else
            set1 = Functions::number( set1 )
            set2 = Functions::number( set2 )
          end
        end
        #puts "EQ_REL_COMP: #{set1} #{op} #{set2}"
        #puts ">>> #{compare( set1, op, set2 )}"
        return compare( set1, op, set2 )
      end
      return false
    end

    def compare a, op, b
      #puts "COMPARE #{a.inspect}(#{a.class.name}) #{op} #{b.inspect}(#{b.class.name})"
      case op
      when :eq
        a == b
      when :neq
        a != b
      when :lt
        a < b
      when :lteq
        a <= b
      when :gt
        a > b
      when :gteq
        a >= b
      when :and
        a and b
      when :or
        a or b
      else
        false
      end
    end
  end
end
PK     Y\8Fc	  	  
  getopts.rbnu [        #
#               getopts.rb - 
#                       $Release Version: $
#                       $Revision: 11708 $
#                       $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#                       by Yasuo OHBA(SHL Japan Inc. Technology Dept.)
#
# --
# this is obsolete; use getoptlong
#
# 2000-03-21
# modified by Minero Aoki <aamine@dp.u-netsurf.ne.jp>
#
# 2002-03-05
# rewritten by Akinori MUSHA <knu@ruby-lang.org>
#

warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: getopts is deprecated after Ruby 1.8.1; use optparse instead" if caller[0] and $VERBOSE

$RCS_ID=%q$Header$

# getopts is obsolete. Use GetoptLong.

def getopts(single_options, *options)
  boolopts = {}
  valopts = {}

  #
  # set defaults
  #
  single_options.scan(/.:?/) do |opt|
    if opt.size == 1
      boolopts[opt] = false
    else
      valopts[opt[0, 1]] = nil
    end
  end if single_options

  options.each do |arg|
    opt, val = arg.split(':', 2)

    if val
      valopts[opt] = val.empty? ? nil : val
    else
      boolopts[opt] = false
    end
  end

  #
  # scan
  #
  c = 0
  argv = ARGV

  while arg = argv.shift
    case arg
    when /\A--(.*)/
      if $1.empty?			# xinit -- -bpp 24
	break
      end

      opt, val = $1.split('=', 2)

      if opt.size == 1
	argv.unshift arg
	return nil
      elsif valopts.key? opt		# imclean --src +trash
	valopts[opt] = val || argv.shift or return nil
      elsif boolopts.key? opt		# ruby --verbose
	boolopts[opt] = true
      else
	argv.unshift arg
	return nil
      end

      c += 1
    when /\A-(.+)/
      opts = $1

      until opts.empty?
	opt = opts.slice!(0, 1)

	if valopts.key? opt
	  val = opts

	  if val.empty?			# ruby -e 'p $:'
	    valopts[opt] = argv.shift or return nil
	  else				# cc -ohello ...
	    valopts[opt] = val
	  end

	  c += 1
	  break
	elsif boolopts.key? opt
	  boolopts[opt] = true		# ruby -h
	  c += 1
	else
	  argv.unshift arg
	  return nil
	end
      end
    else
      argv.unshift arg
      break
    end
  end

  #
  # set
  #
  $OPT = {}

  boolopts.each do |opt, val|
    $OPT[opt] = val

    sopt = opt.gsub(/[^A-Za-z0-9_]/, '_')
    eval "$OPT_#{sopt} = val"
  end
  valopts.each do |opt, val|
    $OPT[opt] = val

    sopt = opt.gsub(/[^A-Za-z0-9_]/, '_')
    eval "$OPT_#{sopt} = val"
  end

  c
end
PK     Y\?  ?    pp.rbnu [        # == Pretty-printer for Ruby objects.
# 
# = Which seems better?
# 
# non-pretty-printed output by #p is:
#   #<PP:0x81fedf0 @genspace=#<Proc:0x81feda0>, @group_queue=#<PrettyPrint::GroupQueue:0x81fed3c @queue=[[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], []]>, @buffer=[], @newline="\n", @group_stack=[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], @buffer_width=0, @indent=0, @maxwidth=79, @output_width=2, @output=#<IO:0x8114ee4>>
# 
# pretty-printed output by #pp is:
#   #<PP:0x81fedf0
#    @buffer=[],
#    @buffer_width=0,
#    @genspace=#<Proc:0x81feda0>,
#    @group_queue=
#     #<PrettyPrint::GroupQueue:0x81fed3c
#      @queue=
#       [[#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],
#        []]>,
#    @group_stack=
#     [#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],
#    @indent=0,
#    @maxwidth=79,
#    @newline="\n",
#    @output=#<IO:0x8114ee4>,
#    @output_width=2>
# 
# I like the latter.  If you do too, this library is for you.
# 
# = Usage
# 
#   pp(obj)
#
# output +obj+ to +$>+ in pretty printed format.
# 
# It returns +nil+.
# 
# = Output Customization
# To define your customized pretty printing function for your classes,
# redefine a method #pretty_print(+pp+) in the class.
# It takes an argument +pp+ which is an instance of the class PP.
# The method should use PP#text, PP#breakable, PP#nest, PP#group and
# PP#pp to print the object.
#
# = Author
# Tanaka Akira <akr@m17n.org>

require 'prettyprint'

module Kernel
  # returns a pretty printed object as a string.
  def pretty_inspect
    PP.pp(self, '')
  end

  private
  # prints arguments in pretty form.
  #
  # pp returns nil.
  def pp(*objs) # :doc:
    objs.each {|obj|
      PP.pp(obj)
    }
    nil
  end
  module_function :pp
end

class PP < PrettyPrint
  # Outputs +obj+ to +out+ in pretty printed format of
  # +width+ columns in width.
  # 
  # If +out+ is omitted, +$>+ is assumed.
  # If +width+ is omitted, 79 is assumed.
  # 
  # PP.pp returns +out+.
  def PP.pp(obj, out=$>, width=79)
    q = PP.new(out, width)
    q.guard_inspect_key {q.pp obj}
    q.flush
    #$pp = q
    out << "\n"
  end

  # Outputs +obj+ to +out+ like PP.pp but with no indent and
  # newline.
  # 
  # PP.singleline_pp returns +out+.
  def PP.singleline_pp(obj, out=$>)
    q = SingleLine.new(out)
    q.guard_inspect_key {q.pp obj}
    q.flush
    out
  end

  # :stopdoc:
  def PP.mcall(obj, mod, meth, *args, &block)
    mod.instance_method(meth).bind(obj).call(*args, &block)
  end
  # :startdoc:

  @sharing_detection = false
  class << self
    # Returns the sharing detection flag as a boolean value.
    # It is false by default.
    attr_accessor :sharing_detection
  end

  module PPMethods
    InspectKey = :__inspect_key__

    def guard_inspect_key
      if Thread.current[InspectKey] == nil
        Thread.current[InspectKey] = []
      end

      save = Thread.current[InspectKey]

      begin
        Thread.current[InspectKey] = []
        yield
      ensure
        Thread.current[InspectKey] = save
      end
    end

    # Adds +obj+ to the pretty printing buffer
    # using Object#pretty_print or Object#pretty_print_cycle.
    # 
    # Object#pretty_print_cycle is used when +obj+ is already
    # printed, a.k.a the object reference chain has a cycle.
    def pp(obj)
      id = obj.__id__

      if Thread.current[InspectKey].include? id
        group {obj.pretty_print_cycle self}
        return
      end

      begin
        Thread.current[InspectKey] << id
        group {obj.pretty_print self}
      ensure
        Thread.current[InspectKey].pop unless PP.sharing_detection
      end
    end

    # A convenience method which is same as follows:
    # 
    #   group(1, '#<' + obj.class.name, '>') { ... }
    def object_group(obj, &block) # :yield:
      group(1, '#<' + obj.class.name, '>', &block)
    end

    def object_address_group(obj, &block)
      id = "%x" % (obj.__id__ * 2)
      id.sub!(/\Af(?=[[:xdigit:]]{2}+\z)/, '') if id.sub!(/\A\.\./, '')
      group(1, "\#<#{obj.class}:0x#{id}", '>', &block)
    end

    # A convenience method which is same as follows:
    # 
    #   text ','
    #   breakable
    def comma_breakable
      text ','
      breakable
    end

    # Adds a separated list.
    # The list is separated by comma with breakable space, by default.
    # 
    # #seplist iterates the +list+ using +iter_method+.
    # It yields each object to the block given for #seplist.
    # The procedure +separator_proc+ is called between each yields.
    # 
    # If the iteration is zero times, +separator_proc+ is not called at all.
    # 
    # If +separator_proc+ is nil or not given,
    # +lambda { comma_breakable }+ is used.
    # If +iter_method+ is not given, :each is used.
    # 
    # For example, following 3 code fragments has similar effect.
    # 
    #   q.seplist([1,2,3]) {|v| xxx v }
    # 
    #   q.seplist([1,2,3], lambda { comma_breakable }, :each) {|v| xxx v }
    # 
    #   xxx 1
    #   q.comma_breakable
    #   xxx 2
    #   q.comma_breakable
    #   xxx 3
    def seplist(list, sep=nil, iter_method=:each) # :yield: element
      sep ||= lambda { comma_breakable }
      first = true
      list.__send__(iter_method) {|*v|
        if first
          first = false
        else
          sep.call
        end
        yield(*v)
      }
    end

    def pp_object(obj)
      object_address_group(obj) {
        seplist(obj.pretty_print_instance_variables, lambda { text ',' }) {|v|
          breakable
          v = v.to_s if Symbol === v
          text v
          text '='
          group(1) {
            breakable ''
            pp(obj.instance_eval(v))
          }
        }
      }
    end

    def pp_hash(obj)
      group(1, '{', '}') {
        seplist(obj, nil, :each_pair) {|k, v|
          group {
            pp k
            text '=>'
            group(1) {
              breakable ''
              pp v
            }
          }
        }
      }
    end
  end

  include PPMethods

  class SingleLine < PrettyPrint::SingleLine
    include PPMethods
  end

  module ObjectMixin
    # 1. specific pretty_print
    # 2. specific inspect
    # 3. specific to_s if instance variable is empty
    # 4. generic pretty_print

    # A default pretty printing method for general objects.
    # It calls #pretty_print_instance_variables to list instance variables.
    # 
    # If +self+ has a customized (redefined) #inspect method,
    # the result of self.inspect is used but it obviously has no
    # line break hints.
    # 
    # This module provides predefined #pretty_print methods for some of
    # the most commonly used built-in classes for convenience.
    def pretty_print(q)
      if /\(Kernel\)#/ !~ Object.instance_method(:method).bind(self).call(:inspect).inspect
        q.text self.inspect
      elsif /\(Kernel\)#/ !~ Object.instance_method(:method).bind(self).call(:to_s).inspect && instance_variables.empty?
        q.text self.to_s
      else
        q.pp_object(self)
      end
    end

    # A default pretty printing method for general objects that are
    # detected as part of a cycle.
    def pretty_print_cycle(q)
      q.object_address_group(self) {
        q.breakable
        q.text '...'
      }
    end

    # Returns a sorted array of instance variable names.
    # 
    # This method should return an array of names of instance variables as symbols or strings as:
    # +[:@a, :@b]+.
    def pretty_print_instance_variables
      instance_variables.sort
    end

    # Is #inspect implementation using #pretty_print.
    # If you implement #pretty_print, it can be used as follows.
    # 
    #   alias inspect pretty_print_inspect
    #
    # However, doing this requires that every class that #inspect is called on
    # implement #pretty_print, or a RuntimeError will be raised.
    def pretty_print_inspect
      if /\(PP::ObjectMixin\)#/ =~ Object.instance_method(:method).bind(self).call(:pretty_print).inspect
        raise "pretty_print is not overridden for #{self.class}"
      end
      PP.singleline_pp(self, '')
    end
  end
end

class Array
  def pretty_print(q)
    q.group(1, '[', ']') {
      q.seplist(self) {|v|
        q.pp v
      }
    }
  end

  def pretty_print_cycle(q)
    q.text(empty? ? '[]' : '[...]')
  end
end

class Hash
  def pretty_print(q)
    q.pp_hash self
  end

  def pretty_print_cycle(q)
    q.text(empty? ? '{}' : '{...}')
  end
end

class << ENV
  def pretty_print(q)
    q.pp_hash self
  end
end

class Struct
  def pretty_print(q)
    q.group(1, '#<struct ' + PP.mcall(self, Kernel, :class).name, '>') {
      q.seplist(PP.mcall(self, Struct, :members), lambda { q.text "," }) {|member|
        q.breakable
        q.text member.to_s
        q.text '='
        q.group(1) {
          q.breakable ''
          q.pp self[member]
        }
      }
    }
  end

  def pretty_print_cycle(q)
    q.text sprintf("#<struct %s:...>", PP.mcall(self, Kernel, :class).name)
  end
end

class Range
  def pretty_print(q)
    q.pp self.begin
    q.breakable ''
    q.text(self.exclude_end? ? '...' : '..')
    q.breakable ''
    q.pp self.end
  end
end

class File
  class Stat
    def pretty_print(q)
      require 'etc.so'
      q.object_group(self) {
        q.breakable
        q.text sprintf("dev=0x%x", self.dev); q.comma_breakable
        q.text "ino="; q.pp self.ino; q.comma_breakable
        q.group {
          m = self.mode
          q.text sprintf("mode=0%o", m)
          q.breakable
          q.text sprintf("(%s %c%c%c%c%c%c%c%c%c)",
            self.ftype,
            (m & 0400 == 0 ? ?- : ?r),
            (m & 0200 == 0 ? ?- : ?w),
            (m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) :
                             (m & 04000 == 0 ? ?x : ?s)),
            (m & 0040 == 0 ? ?- : ?r),
            (m & 0020 == 0 ? ?- : ?w),
            (m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) :
                             (m & 02000 == 0 ? ?x : ?s)),
            (m & 0004 == 0 ? ?- : ?r),
            (m & 0002 == 0 ? ?- : ?w),
            (m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) :
                             (m & 01000 == 0 ? ?x : ?t)))
        }
        q.comma_breakable
        q.text "nlink="; q.pp self.nlink; q.comma_breakable
        q.group {
          q.text "uid="; q.pp self.uid
          begin
            pw = Etc.getpwuid(self.uid)
          rescue ArgumentError
          end
          if pw
            q.breakable; q.text "(#{pw.name})"
          end
        }
        q.comma_breakable
        q.group {
          q.text "gid="; q.pp self.gid
          begin
            gr = Etc.getgrgid(self.gid)
          rescue ArgumentError
          end
          if gr
            q.breakable; q.text "(#{gr.name})"
          end
        }
        q.comma_breakable
        q.group {
          q.text sprintf("rdev=0x%x", self.rdev)
          q.breakable
          q.text sprintf('(%d, %d)', self.rdev_major, self.rdev_minor)
        }
        q.comma_breakable
        q.text "size="; q.pp self.size; q.comma_breakable
        q.text "blksize="; q.pp self.blksize; q.comma_breakable
        q.text "blocks="; q.pp self.blocks; q.comma_breakable
        q.group {
          t = self.atime
          q.text "atime="; q.pp t
          q.breakable; q.text "(#{t.tv_sec})"
        }
        q.comma_breakable
        q.group {
          t = self.mtime
          q.text "mtime="; q.pp t
          q.breakable; q.text "(#{t.tv_sec})"
        }
        q.comma_breakable
        q.group {
          t = self.ctime
          q.text "ctime="; q.pp t
          q.breakable; q.text "(#{t.tv_sec})"
        }
      }
    end
  end
end

class MatchData
  def pretty_print(q)
    q.object_group(self) {
      q.breakable
      q.seplist(1..self.size, lambda { q.breakable }) {|i|
        q.pp self[i-1]
      }
    }
  end
end

class Object
  include PP::ObjectMixin
end

[Numeric, Symbol, FalseClass, TrueClass, NilClass, Module].each {|c|
  c.class_eval {
    def pretty_print_cycle(q)
      q.text inspect
    end
  }
}

[Numeric, FalseClass, TrueClass, Module].each {|c|
  c.class_eval {
    def pretty_print(q)
      q.text inspect
    end
  }
}

# :enddoc:
if __FILE__ == $0
  require 'test/unit'

  class PPTest < Test::Unit::TestCase
    def test_list0123_12
      assert_equal("[0, 1, 2, 3]\n", PP.pp([0,1,2,3], '', 12))
    end

    def test_list0123_11
      assert_equal("[0,\n 1,\n 2,\n 3]\n", PP.pp([0,1,2,3], '', 11))
    end

    OverriddenStruct = Struct.new("OverriddenStruct", :members, :class)
    def test_struct_override_members # [ruby-core:7865]
      a = OverriddenStruct.new(1,2)
      assert_equal("#<struct Struct::OverriddenStruct members=1, class=2>\n", PP.pp(a, ''))
    end

    def test_redefined_method
      o = ""
      def o.method
      end
      assert_equal(%(""\n), PP.pp(o, ""))
    end
  end

  class HasInspect
    def initialize(a)
      @a = a
    end

    def inspect
      return "<inspect:#{@a.inspect}>"
    end
  end

  class HasPrettyPrint
    def initialize(a)
      @a = a
    end

    def pretty_print(q)
      q.text "<pretty_print:"
      q.pp @a
      q.text ">"
    end
  end

  class HasBoth
    def initialize(a)
      @a = a
    end

    def inspect
      return "<inspect:#{@a.inspect}>"
    end

    def pretty_print(q)
      q.text "<pretty_print:"
      q.pp @a
      q.text ">"
    end
  end

  class PrettyPrintInspect < HasPrettyPrint
    alias inspect pretty_print_inspect
  end

  class PrettyPrintInspectWithoutPrettyPrint
    alias inspect pretty_print_inspect
  end

  class PPInspectTest < Test::Unit::TestCase
    def test_hasinspect
      a = HasInspect.new(1)
      assert_equal("<inspect:1>\n", PP.pp(a, ''))
    end

    def test_hasprettyprint
      a = HasPrettyPrint.new(1)
      assert_equal("<pretty_print:1>\n", PP.pp(a, ''))
    end

    def test_hasboth
      a = HasBoth.new(1)
      assert_equal("<pretty_print:1>\n", PP.pp(a, ''))
    end

    def test_pretty_print_inspect
      a = PrettyPrintInspect.new(1)
      assert_equal("<pretty_print:1>", a.inspect)
      a = PrettyPrintInspectWithoutPrettyPrint.new
      assert_raise(RuntimeError) { a.inspect }
    end

    def test_proc
      a = proc {1}
      assert_equal("#{a.inspect}\n", PP.pp(a, ''))
    end

    def test_to_s_with_iv
      a = Object.new
      def a.to_s() "aaa" end
      a.instance_eval { @a = nil }
      result = PP.pp(a, '')
      assert_equal("#{a.inspect}\n", result)
      assert_match(/\A#<Object.*>\n\z/m, result)
      a = 1.0
      a.instance_eval { @a = nil }
      result = PP.pp(a, '')
      assert_equal("#{a.inspect}\n", result)
    end
    
    def test_to_s_without_iv
      a = Object.new
      def a.to_s() "aaa" end
      result = PP.pp(a, '')
      assert_equal("#{a.inspect}\n", result)
      assert_equal("aaa\n", result)
    end
  end

  class PPCycleTest < Test::Unit::TestCase
    def test_array
      a = []
      a << a
      assert_equal("[[...]]\n", PP.pp(a, ''))
      assert_equal("#{a.inspect}\n", PP.pp(a, ''))
    end

    def test_hash
      a = {}
      a[0] = a
      assert_equal("{0=>{...}}\n", PP.pp(a, ''))
      assert_equal("#{a.inspect}\n", PP.pp(a, ''))
    end

    S = Struct.new("S", :a, :b)
    def test_struct
      a = S.new(1,2)
      a.b = a
      assert_equal("#<struct Struct::S a=1, b=#<struct Struct::S:...>>\n", PP.pp(a, ''))
      assert_equal("#{a.inspect}\n", PP.pp(a, ''))
    end

    def test_object
      a = Object.new
      a.instance_eval {@a = a}
      assert_equal(a.inspect + "\n", PP.pp(a, ''))
    end

    def test_anonymous
      a = Class.new.new
      assert_equal(a.inspect + "\n", PP.pp(a, ''))
    end

    def test_withinspect
      a = []
      a << HasInspect.new(a)
      assert_equal("[<inspect:[...]>]\n", PP.pp(a, ''))
      assert_equal("#{a.inspect}\n", PP.pp(a, ''))
    end

    def test_share_nil
      begin
        PP.sharing_detection = true
        a = [nil, nil]
        assert_equal("[nil, nil]\n", PP.pp(a, ''))
      ensure
        PP.sharing_detection = false
      end
    end
  end

  class PPSingleLineTest < Test::Unit::TestCase
    def test_hash
      assert_equal("{1=>1}", PP.singleline_pp({ 1 => 1}, '')) # [ruby-core:02699]
      assert_equal("[1#{', 1'*99}]", PP.singleline_pp([1]*100, ''))
    end
  end
end
PK     Y\Fb      shell.rbnu [        #
#   shell.rb - 
#   	$Release Version: 0.6.0 $
#   	$Revision: 1.8 $
#   	$Date: 2001/03/19 09:01:11 $
#   	by Keiju ISHITSUKA(Nippon Rational Inc.)
#
# --
#
#   
#

require "e2mmap"
require "thread"

require "shell/error"
require "shell/command-processor"
require "shell/process-controller"

class Shell
  @RCS_ID='-$Id: shell.rb,v 1.8 2001/03/19 09:01:11 keiju Exp keiju $-'

  include Error
  extend Exception2MessageMapper

#  @cascade = true
  # debug: true -> normal debug
  # debug: 1    -> eval definition debug
  # debug: 2    -> detail inspect debug
  @debug = false
  @verbose = true

  class << Shell
    attr :cascade, true
    attr :debug, true
    attr :verbose, true

#    alias cascade? cascade
    alias debug? debug
    alias verbose? verbose
    @verbose = true

    def debug=(val)
      @debug = val
      @verbose = val if val
    end

    def cd(path)
      sh = new
      sh.cd path
      sh
    end

    def default_system_path
      if @default_system_path
	@default_system_path
      else
	ENV["PATH"].split(":")
      end
    end

    def default_system_path=(path)
      @default_system_path = path
    end

    def default_record_separator
      if @default_record_separator
	@default_record_separator
      else
	$/
      end
    end

    def default_record_separator=(rs)
      @default_record_separator = rs
    end
  end

  def initialize
    @cwd = Dir.pwd
    @dir_stack = []
    @umask = nil

    @system_path = Shell.default_system_path
    @record_separator = Shell.default_record_separator

    @command_processor = CommandProcessor.new(self)
    @process_controller = ProcessController.new(self)

    @verbose = Shell.verbose
    @debug = Shell.debug
  end

  attr_reader :system_path

  def system_path=(path)
    @system_path = path
    rehash
  end

  attr :umask, true
  attr :record_separator, true

  attr :verbose, true
  attr :debug, true

  def debug=(val)
    @debug = val
    @verbose = val if val
  end

  alias verbose? verbose
  alias debug? debug

  attr_reader :command_processor
  attr_reader :process_controller

  def expand_path(path)
    File.expand_path(path, @cwd)
  end

  # Most Shell commands are defined via CommandProcessor

  #
  # Dir related methods
  #
  # Shell#cwd/dir/getwd/pwd
  # Shell#chdir/cd
  # Shell#pushdir/pushd
  # Shell#popdir/popd
  # Shell#mkdir
  # Shell#rmdir

  attr :cwd
  alias dir cwd
  alias getwd cwd
  alias pwd cwd

  attr :dir_stack
  alias dirs dir_stack

  # If called as iterator, it restores the current directory when the
  # block ends.
  def chdir(path = nil)
    if iterator?
      cwd_old = @cwd
      begin
	chdir(path)
	yield
      ensure
	chdir(cwd_old)
      end
    else
      path = "~" unless path
      @cwd = expand_path(path)
      notify "current dir: #{@cwd}"
      rehash
      self
    end
  end
  alias cd chdir

  def pushdir(path = nil)
    if iterator?
      pushdir(path)
      begin
	yield
      ensure
	popdir
      end
    elsif path
      @dir_stack.push @cwd
      chdir path
      notify "dir stack: [#{@dir_stack.join ', '}]"
      self
    else
      if pop = @dir_stack.pop
	@dir_stack.push @cwd
	chdir pop
	notify "dir stack: [#{@dir_stack.join ', '}]"
	self
      else
	Shell.Fail DirStackEmpty
      end
    end
  end
  alias pushd pushdir

  def popdir
    if pop = @dir_stack.pop
      chdir pop
      notify "dir stack: [#{@dir_stack.join ', '}]"
      self
    else
      Shell.Fail DirStackEmpty
    end
  end
  alias popd popdir


  #
  # process management
  #
  def jobs
    @process_controller.jobs
  end

  def kill(sig, command)
    @process_controller.kill_job(sig, command)
  end

  #
  # command definitions
  #
  def Shell.def_system_command(command, path = command)
    CommandProcessor.def_system_command(command, path)
  end

  def Shell.undef_system_command(command)
    CommandProcessor.undef_system_command(command)
  end

  def Shell.alias_command(ali, command, *opts, &block)
    CommandProcessor.alias_command(ali, command, *opts, &block)
  end

  def Shell.unalias_command(ali)
    CommandProcessor.unalias_command(ali)
  end

  def Shell.install_system_commands(pre = "sys_")
    CommandProcessor.install_system_commands(pre)
  end

  #
  def inspect
    if debug.kind_of?(Integer) && debug > 2
      super
    else
      to_s
    end
  end

  def self.notify(*opts, &block)
    Thread.exclusive do
    if opts[-1].kind_of?(String)
      yorn = verbose?
    else
      yorn = opts.pop
    end
    return unless yorn

    _head = true
    print opts.collect{|mes|
      mes = mes.dup
      yield mes if iterator?
      if _head
	_head = false
	"shell: " + mes
      else
	"       " + mes
      end
    }.join("\n")+"\n"
    end
  end

  CommandProcessor.initialize
  CommandProcessor.run_config
end
PK     Y\C    	  eregex.rbnu [        # this is just a proof of concept toy.

class RegOr
  def initialize(re1, re2)
    @re1 = re1
    @re2 = re2
  end

  def =~ (str)
    @re1 =~ str or @re2 =~ str
  end
end

class RegAnd
  def initialize(re1, re2)
    @re1 = re1
    @re2 = re2
  end

  def =~ (str)
    @re1 =~ str and @re2 =~ str
  end
end

class Regexp
  def |(other)
    RegOr.new(self, other)
  end
  def &(other)
    RegAnd.new(self, other)
  end
end

if __FILE__ == $0
  p "abc" =~ /b/|/c/
  p "abc" =~ /b/&/c/
end
PK     Y\ԌI        kconv.rbnu [        #
# kconv.rb - Kanji Converter.
#
# $Id: kconv.rb 11708 2007-02-12 23:01:19Z shyouhei $
#
# ----
#
# kconv.rb implements the Kconv class for Kanji Converter.  Additionally,
# some methods in String classes are added to allow easy conversion.
#

require 'nkf'

#
# Kanji Converter for Ruby.
#
module Kconv
  #
  # Public Constants
  #
  
  #Constant of Encoding
  
  # Auto-Detect
  AUTO = NKF::AUTO
  # ISO-2022-JP
  JIS = NKF::JIS
  # EUC-JP
  EUC = NKF::EUC
  # Shift_JIS
  SJIS = NKF::SJIS
  # BINARY
  BINARY = NKF::BINARY
  # NOCONV
  NOCONV = NKF::NOCONV
  # ASCII
  ASCII = NKF::ASCII
  # UTF-8
  UTF8 = NKF::UTF8
  # UTF-16
  UTF16 = NKF::UTF16
  # UTF-32
  UTF32 = NKF::UTF32
  # UNKNOWN
  UNKNOWN = NKF::UNKNOWN

  #
  # Private Constants
  #
  
  # Revision of kconv.rb
  REVISION = %q$Revision: 11708 $
  
  #Regexp of Encoding
  
  # Regexp of Shift_JIS string (private constant)
  RegexpShiftjis = /\A(?:
		       [\x00-\x7f\xa1-\xdf] |
		       [\x81-\x9f\xe0-\xfc][\x40-\x7e\x80-\xfc] 
		      )*\z/nx

  # Regexp of EUC-JP string (private constant)
  RegexpEucjp = /\A(?:
		    [\x00-\x7f]                         |
		    \x8e        [\xa1-\xdf]             |
		    \x8f        [\xa1-\xfe] [\xa1-\xfe] |
		    [\xa1-\xfe] [\xa1-\xfe]
		   )*\z/nx

  # Regexp of UTF-8 string (private constant)
  RegexpUtf8  = /\A(?:
		    [\x00-\x7f]                                     |
		    [\xc2-\xdf] [\x80-\xbf]                         |
		    \xe0        [\xa0-\xbf] [\x80-\xbf]             |
		    [\xe1-\xef] [\x80-\xbf] [\x80-\xbf]             |
		    \xf0        [\x90-\xbf] [\x80-\xbf] [\x80-\xbf] |
		    [\xf1-\xf3] [\x80-\xbf] [\x80-\xbf] [\x80-\xbf] |
		    \xf4        [\x80-\x8f] [\x80-\xbf] [\x80-\xbf]
		   )*\z/nx

  #
  # Public Methods
  #
  
  # call-seq:
  #    Kconv.kconv(str, out_code, in_code = Kconv::AUTO)
  #
  # Convert <code>str</code> to out_code.
  # <code>out_code</code> and <code>in_code</code> are given as constants of Kconv.
  #
  # *Note*
  # This method decode MIME encoded string and
  # convert halfwidth katakana to fullwidth katakana.
  # If you don't want to decode them, use NKF.nkf.
  def kconv(str, out_code, in_code = AUTO)
    opt = '-'
    case in_code
    when ::NKF::JIS
      opt << 'J'
    when ::NKF::EUC
      opt << 'E'
    when ::NKF::SJIS
      opt << 'S'
    when ::NKF::UTF8
      opt << 'W'
    when ::NKF::UTF16
      opt << 'W16'
    end

    case out_code
    when ::NKF::JIS
      opt << 'j'
    when ::NKF::EUC
      opt << 'e'
    when ::NKF::SJIS
      opt << 's'
    when ::NKF::UTF8
      opt << 'w'
    when ::NKF::UTF16
      opt << 'w16'
    when ::NKF::NOCONV
      return str
    end

    opt = '' if opt == '-'

    ::NKF::nkf(opt, str)
  end
  module_function :kconv

  #
  # Encode to
  #

  # call-seq:
  #    Kconv.tojis(str)   -> string
  #
  # Convert <code>str</code> to ISO-2022-JP
  #
  # *Note*
  # This method decode MIME encoded string and
  # convert halfwidth katakana to fullwidth katakana.
  # If you don't want it, use NKF.nkf('-jxm0', str).
  def tojis(str)
    ::NKF::nkf('-jm', str)
  end
  module_function :tojis

  # call-seq:
  #    Kconv.toeuc(str)   -> string
  #
  # Convert <code>str</code> to EUC-JP
  #
  # *Note*
  # This method decode MIME encoded string and
  # convert halfwidth katakana to fullwidth katakana.
  # If you don't want it, use NKF.nkf('-exm0', str).
  def toeuc(str)
    ::NKF::nkf('-em', str)
  end
  module_function :toeuc

  # call-seq:
  #    Kconv.tosjis(str)   -> string
  #
  # Convert <code>str</code> to Shift_JIS
  #
  # *Note*
  # This method decode MIME encoded string and
  # convert halfwidth katakana to fullwidth katakana.
  # If you don't want it, use NKF.nkf('-sxm0', str).
  def tosjis(str)
    ::NKF::nkf('-sm', str)
  end
  module_function :tosjis

  # call-seq:
  #    Kconv.toutf8(str)   -> string
  #
  # Convert <code>str</code> to UTF-8
  #
  # *Note*
  # This method decode MIME encoded string and
  # convert halfwidth katakana to fullwidth katakana.
  # If you don't want it, use NKF.nkf('-wxm0', str).
  def toutf8(str)
    ::NKF::nkf('-wm', str)
  end
  module_function :toutf8

  # call-seq:
  #    Kconv.toutf16(str)   -> string
  #
  # Convert <code>str</code> to UTF-16
  #
  # *Note*
  # This method decode MIME encoded string and
  # convert halfwidth katakana to fullwidth katakana.
  # If you don't want it, use NKF.nkf('-w16xm0', str).
  def toutf16(str)
    ::NKF::nkf('-w16m', str)
  end
  module_function :toutf16

  #
  # guess
  #

  # call-seq:
  #    Kconv.guess(str)   -> integer
  #
  # Guess input encoding by NKF.guess2
  def guess(str)
    ::NKF::guess(str)
  end
  module_function :guess

  # call-seq:
  #    Kconv.guess_old(str)   -> integer
  #
  # Guess input encoding by NKF.guess1
  def guess_old(str)
    ::NKF::guess1(str)
  end
  module_function :guess_old

  #
  # isEncoding
  #

  # call-seq:
  #    Kconv.iseuc(str)   -> obj or nil
  #
  # Returns whether input encoding is EUC-JP or not.
  #
  # *Note* don't expect this return value is MatchData.
  def iseuc(str)
    RegexpEucjp.match( str )
  end
  module_function :iseuc

  # call-seq:
  #    Kconv.issjis(str)   -> obj or nil
  #
  # Returns whether input encoding is Shift_JIS or not.
  #
  # *Note* don't expect this return value is MatchData.
  def issjis(str)
    RegexpShiftjis.match( str )
  end
  module_function :issjis

  # call-seq:
  #    Kconv.isutf8(str)   -> obj or nil
  #
  # Returns whether input encoding is UTF-8 or not.
  #
  # *Note* don't expect this return value is MatchData.
  def isutf8(str)
    RegexpUtf8.match( str )
  end
  module_function :isutf8

end

class String
  # call-seq:
  #    String#kconv(out_code, in_code = Kconv::AUTO)
  #
  # Convert <code>self</code> to out_code.
  # <code>out_code</code> and <code>in_code</code> are given as constants of Kconv.
  #
  # *Note*
  # This method decode MIME encoded string and
  # convert halfwidth katakana to fullwidth katakana.
  # If you don't want to decode them, use NKF.nkf.
  def kconv(out_code, in_code=Kconv::AUTO)
    Kconv::kconv(self, out_code, in_code)
  end
  
  #
  # to Encoding
  #
  
  # call-seq:
  #    String#tojis   -> string
  #
  # Convert <code>self</code> to ISO-2022-JP
  #
  # *Note*
  # This method decode MIME encoded string and
  # convert halfwidth katakana to fullwidth katakana.
  # If you don't want it, use NKF.nkf('-jxm0', str).
  def tojis; Kconv.tojis(self) end

  # call-seq:
  #    String#toeuc   -> string
  #
  # Convert <code>self</code> to EUC-JP
  #
  # *Note*
  # This method decode MIME encoded string and
  # convert halfwidth katakana to fullwidth katakana.
  # If you don't want it, use NKF.nkf('-exm0', str).
  def toeuc; Kconv.toeuc(self) end

  # call-seq:
  #    String#tosjis   -> string
  #
  # Convert <code>self</code> to Shift_JIS
  #
  # *Note*
  # This method decode MIME encoded string and
  # convert halfwidth katakana to fullwidth katakana.
  # If you don't want it, use NKF.nkf('-sxm0', str).
  def tosjis; Kconv.tosjis(self) end

  # call-seq:
  #    String#toutf8   -> string
  #
  # Convert <code>self</code> to UTF-8
  #
  # *Note*
  # This method decode MIME encoded string and
  # convert halfwidth katakana to fullwidth katakana.
  # If you don't want it, use NKF.nkf('-wxm0', str).
  def toutf8; Kconv.toutf8(self) end

  # call-seq:
  #    String#toutf16   -> string
  #
  # Convert <code>self</code> to UTF-16
  #
  # *Note*
  # This method decode MIME encoded string and
  # convert halfwidth katakana to fullwidth katakana.
  # If you don't want it, use NKF.nkf('-w16xm0', str).
  def toutf16; Kconv.toutf16(self) end

  #
  # is Encoding
  #

  # call-seq:
  #    String#iseuc   -> obj or nil
  #
  # Returns whether <code>self</code>'s encoding is EUC-JP or not.
  #
  # *Note* don't expect this return value is MatchData.
  def iseuc;	Kconv.iseuc(self) end

  # call-seq:
  #    String#issjis   -> obj or nil
  #
  # Returns whether <code>self</code>'s encoding is Shift_JIS or not.
  #
  # *Note* don't expect this return value is MatchData.
  def issjis;	Kconv.issjis(self) end

  # call-seq:
  #    String#isutf8   -> obj or nil
  #
  # Returns whether <code>self</code>'s encoding is UTF-8 or not.
  #
  # *Note* don't expect this return value is MatchData.
  def isutf8;	Kconv.isutf8(self) end
end
PK     Y\N7Nl  Nl    set.rbnu [        #!/usr/bin/env ruby
#--
# set.rb - defines the Set class
#++
# Copyright (c) 2002-2008 Akinori MUSHA <knu@iDaemons.org>
#
# Documentation by Akinori MUSHA and Gavin Sinclair. 
#
# All rights reserved.  You can redistribute and/or modify it under the same
# terms as Ruby.
#
#   $Id: set.rb 17051 2008-06-09 09:20:43Z knu $
#
# == Overview 
# 
# This library provides the Set class, which deals with a collection
# of unordered values with no duplicates.  It is a hybrid of Array's
# intuitive inter-operation facilities and Hash's fast lookup.  If you
# need to keep values ordered, use the SortedSet class.
#
# The method +to_set+ is added to Enumerable for convenience.
#
# See the Set class for an example of usage.


#
# Set implements a collection of unordered values with no duplicates.
# This is a hybrid of Array's intuitive inter-operation facilities and
# Hash's fast lookup.
#
# Several methods accept any Enumerable object (implementing +each+)
# for greater flexibility: new, replace, merge, subtract, |, &, -, ^.
#
# The equality of each couple of elements is determined according to
# Object#eql? and Object#hash, since Set uses Hash as storage.
#
# Finally, if you are using class Set, you can also use Enumerable#to_set
# for convenience.
#
# == Example
#
#   require 'set'
#   s1 = Set.new [1, 2]                   # -> #<Set: {1, 2}>
#   s2 = [1, 2].to_set                    # -> #<Set: {1, 2}>
#   s1 == s2                              # -> true
#   s1.add("foo")                         # -> #<Set: {1, 2, "foo"}>
#   s1.merge([2, 6])                      # -> #<Set: {6, 1, 2, "foo"}>
#   s1.subset? s2                         # -> false
#   s2.subset? s1                         # -> true
#
# == Contact
#
#   - Akinori MUSHA <knu@iDaemons.org> (current maintainer)
#
class Set
  include Enumerable

  # Creates a new set containing the given objects.
  def self.[](*ary)
    new(ary)
  end

  # Creates a new set containing the elements of the given enumerable
  # object.
  #
  # If a block is given, the elements of enum are preprocessed by the
  # given block.
  def initialize(enum = nil, &block) # :yields: o
    @hash ||= Hash.new

    enum.nil? and return

    if block
      enum.each { |o| add(block[o]) }
    else
      merge(enum)
    end
  end

  # Copy internal hash.
  def initialize_copy(orig)
    @hash = orig.instance_eval{@hash}.dup
  end

  # Returns the number of elements.
  def size
    @hash.size
  end
  alias length size

  # Returns true if the set contains no elements.
  def empty?
    @hash.empty?
  end

  # Removes all elements and returns self.
  def clear
    @hash.clear
    self
  end

  # Replaces the contents of the set with the contents of the given
  # enumerable object and returns self.
  def replace(enum)
    if enum.class == self.class
      @hash.replace(enum.instance_eval { @hash })
    else
      enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
      clear
      enum.each { |o| add(o) }
    end

    self
  end

  # Converts the set to an array.  The order of elements is uncertain.
  def to_a
    @hash.keys
  end

  def flatten_merge(set, seen = Set.new)
    set.each { |e|
      if e.is_a?(Set)
	if seen.include?(e_id = e.object_id)
	  raise ArgumentError, "tried to flatten recursive Set"
	end

	seen.add(e_id)
	flatten_merge(e, seen)
	seen.delete(e_id)
      else
	add(e)
      end
    }

    self
  end
  protected :flatten_merge

  # Returns a new set that is a copy of the set, flattening each
  # containing set recursively.
  def flatten
    self.class.new.flatten_merge(self)
  end

  # Equivalent to Set#flatten, but replaces the receiver with the
  # result in place.  Returns nil if no modifications were made.
  def flatten!
    if detect { |e| e.is_a?(Set) }
      replace(flatten())
    else
      nil
    end
  end

  # Returns true if the set contains the given object.
  def include?(o)
    @hash.include?(o)
  end
  alias member? include?

  # Returns true if the set is a superset of the given set.
  def superset?(set)
    set.is_a?(Set) or raise ArgumentError, "value must be a set"
    return false if size < set.size
    set.all? { |o| include?(o) }
  end

  # Returns true if the set is a proper superset of the given set.
  def proper_superset?(set)
    set.is_a?(Set) or raise ArgumentError, "value must be a set"
    return false if size <= set.size
    set.all? { |o| include?(o) }
  end

  # Returns true if the set is a subset of the given set.
  def subset?(set)
    set.is_a?(Set) or raise ArgumentError, "value must be a set"
    return false if set.size < size
    all? { |o| set.include?(o) }
  end

  # Returns true if the set is a proper subset of the given set.
  def proper_subset?(set)
    set.is_a?(Set) or raise ArgumentError, "value must be a set"
    return false if set.size <= size
    all? { |o| set.include?(o) }
  end

  # Calls the given block once for each element in the set, passing
  # the element as parameter.  Returns an enumerator if no block is
  # given.
  def each
    block_given? or return enum_for(__method__)
    @hash.each_key { |o| yield(o) }
    self
  end

  # Adds the given object to the set and returns self.  Use +merge+ to
  # add several elements at once.
  def add(o)
    @hash[o] = true
    self
  end
  alias << add

  # Adds the given object to the set and returns self.  If the
  # object is already in the set, returns nil.
  def add?(o)
    if include?(o)
      nil
    else
      add(o)
    end
  end

  # Deletes the given object from the set and returns self.  Use +subtract+ to
  # delete several items at once.
  def delete(o)
    @hash.delete(o)
    self
  end

  # Deletes the given object from the set and returns self.  If the
  # object is not in the set, returns nil.
  def delete?(o)
    if include?(o)
      delete(o)
    else
      nil
    end
  end

  # Deletes every element of the set for which block evaluates to
  # true, and returns self.
  def delete_if
    to_a.each { |o| @hash.delete(o) if yield(o) }
    self
  end

  # Do collect() destructively.
  def collect!
    set = self.class.new
    each { |o| set << yield(o) }
    replace(set)
  end
  alias map! collect!

  # Equivalent to Set#delete_if, but returns nil if no changes were
  # made.
  def reject!
    n = size
    delete_if { |o| yield(o) }
    size == n ? nil : self
  end

  # Merges the elements of the given enumerable object to the set and
  # returns self.
  def merge(enum)
    if enum.is_a?(Set)
      @hash.update(enum.instance_eval { @hash })
    else
      enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
      enum.each { |o| add(o) }
    end

    self
  end

  # Deletes every element that appears in the given enumerable object
  # and returns self.
  def subtract(enum)
    enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
    enum.each { |o| delete(o) }
    self
  end

  # Returns a new set built by merging the set and the elements of the
  # given enumerable object.
  def |(enum)
    enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
    dup.merge(enum)
  end
  alias + |		##
  alias union |		##

  # Returns a new set built by duplicating the set, removing every
  # element that appears in the given enumerable object.
  def -(enum)
    enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
    dup.subtract(enum)
  end
  alias difference -	##

  # Returns a new set containing elements common to the set and the
  # given enumerable object.
  def &(enum)
    enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
    n = self.class.new
    enum.each { |o| n.add(o) if include?(o) }
    n
  end
  alias intersection &	##

  # Returns a new set containing elements exclusive between the set
  # and the given enumerable object.  (set ^ enum) is equivalent to
  # ((set | enum) - (set & enum)).
  def ^(enum)
    enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
    n = Set.new(enum)
    each { |o| if n.include?(o) then n.delete(o) else n.add(o) end }
    n
  end

  # Returns true if two sets are equal.  The equality of each couple
  # of elements is defined according to Object#eql?.
  def ==(set)
    equal?(set) and return true

    set.is_a?(Set) && size == set.size or return false

    hash = @hash.dup
    set.all? { |o| hash.include?(o) }
  end

  def hash	# :nodoc:
    @hash.hash
  end

  def eql?(o)	# :nodoc:
    return false unless o.is_a?(Set)
    @hash.eql?(o.instance_eval{@hash})
  end

  # Classifies the set by the return value of the given block and
  # returns a hash of {value => set of elements} pairs.  The block is
  # called once for each element of the set, passing the element as
  # parameter.
  #
  # e.g.:
  #
  #   require 'set'
  #   files = Set.new(Dir.glob("*.rb"))
  #   hash = files.classify { |f| File.mtime(f).year }
  #   p hash    # => {2000=>#<Set: {"a.rb", "b.rb"}>,
  #             #     2001=>#<Set: {"c.rb", "d.rb", "e.rb"}>,
  #             #     2002=>#<Set: {"f.rb"}>}
  def classify # :yields: o
    h = {}

    each { |i|
      x = yield(i)
      (h[x] ||= self.class.new).add(i)
    }

    h
  end

  # Divides the set into a set of subsets according to the commonality
  # defined by the given block.
  #
  # If the arity of the block is 2, elements o1 and o2 are in common
  # if block.call(o1, o2) is true.  Otherwise, elements o1 and o2 are
  # in common if block.call(o1) == block.call(o2).
  #
  # e.g.:
  #
  #   require 'set'
  #   numbers = Set[1, 3, 4, 6, 9, 10, 11]
  #   set = numbers.divide { |i,j| (i - j).abs == 1 }
  #   p set     # => #<Set: {#<Set: {1}>,
  #             #            #<Set: {11, 9, 10}>,
  #             #            #<Set: {3, 4}>,
  #             #            #<Set: {6}>}>
  def divide(&func)
    if func.arity == 2
      require 'tsort'

      class << dig = {}		# :nodoc:
	include TSort

	alias tsort_each_node each_key
	def tsort_each_child(node, &block)
	  fetch(node).each(&block)
	end
      end

      each { |u|
	dig[u] = a = []
	each{ |v| func.call(u, v) and a << v }
      }

      set = Set.new()
      dig.each_strongly_connected_component { |css|
	set.add(self.class.new(css))
      }
      set
    else
      Set.new(classify(&func).values)
    end
  end

  InspectKey = :__inspect_key__         # :nodoc:

  # Returns a string containing a human-readable representation of the
  # set. ("#<Set: {element1, element2, ...}>")
  def inspect
    ids = (Thread.current[InspectKey] ||= [])

    if ids.include?(object_id)
      return sprintf('#<%s: {...}>', self.class.name)
    end

    begin
      ids << object_id
      return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2])
    ensure
      ids.pop
    end
  end

  def pretty_print(pp)	# :nodoc:
    pp.text sprintf('#<%s: {', self.class.name)
    pp.nest(1) {
      pp.seplist(self) { |o|
	pp.pp o
      }
    }
    pp.text "}>"
  end

  def pretty_print_cycle(pp)	# :nodoc:
    pp.text sprintf('#<%s: {%s}>', self.class.name, empty? ? '' : '...')
  end
end

# SortedSet implements a set which elements are sorted in order.  See Set.
class SortedSet < Set
  @@setup = false

  class << self
    def [](*ary)	# :nodoc:
      new(ary)
    end

    def setup	# :nodoc:
      @@setup and return

      module_eval {
        # a hack to shut up warning
        alias old_init initialize
        remove_method :old_init
      }
      begin
	require 'rbtree'

	module_eval %{
	  def initialize(*args, &block)
	    @hash = RBTree.new
	    super
	  end
	}
      rescue LoadError
	module_eval %{
	  def initialize(*args, &block)
	    @keys = nil
	    super
	  end

	  def clear
	    @keys = nil
	    super
	  end

	  def replace(enum)
	    @keys = nil
	    super
	  end

	  def add(o)
	    @keys = nil
	    @hash[o] = true
	    self
	  end
	  alias << add

	  def delete(o)
	    @keys = nil
	    @hash.delete(o)
	    self
	  end

	  def delete_if
	    n = @hash.size
	    super
	    @keys = nil if @hash.size != n
	    self
	  end

	  def merge(enum)
	    @keys = nil
	    super
	  end

	  def each
	    block_given? or return enum_for(__method__)
	    to_a.each { |o| yield(o) }
	    self
	  end

	  def to_a
	    (@keys = @hash.keys).sort! unless @keys
	    @keys
	  end
	}
      end

      @@setup = true
    end
  end

  def initialize(*args, &block)	# :nodoc:
    SortedSet.setup
    initialize(*args, &block)
  end
end

module Enumerable
  # Makes a set from the enumerable object with given arguments.
  # Needs to +require "set"+ to use this method.
  def to_set(klass = Set, *args, &block)
    klass.new(self, *args, &block)
  end
end

# =begin
# == RestricedSet class
# RestricedSet implements a set with restrictions defined by a given
# block.
# 
# === Super class
#     Set
# 
# === Class Methods
# --- RestricedSet::new(enum = nil) { |o| ... }
# --- RestricedSet::new(enum = nil) { |rset, o| ... }
#     Creates a new restricted set containing the elements of the given
#     enumerable object.  Restrictions are defined by the given block.
# 
#     If the block's arity is 2, it is called with the RestrictedSet
#     itself and an object to see if the object is allowed to be put in
#     the set.
# 
#     Otherwise, the block is called with an object to see if the object
#     is allowed to be put in the set.
# 
# === Instance Methods
# --- restriction_proc
#     Returns the restriction procedure of the set.
# 
# =end
# 
# class RestricedSet < Set
#   def initialize(*args, &block)
#     @proc = block or raise ArgumentError, "missing a block"
# 
#     if @proc.arity == 2
#       instance_eval %{
# 	def add(o)
# 	  @hash[o] = true if @proc.call(self, o)
# 	  self
# 	end
# 	alias << add
# 
# 	def add?(o)
# 	  if include?(o) || !@proc.call(self, o)
# 	    nil
# 	  else
# 	    @hash[o] = true
# 	    self
# 	  end
# 	end
# 
# 	def replace(enum)
# 	  enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
# 	  clear
# 	  enum.each { |o| add(o) }
# 
# 	  self
# 	end
# 
# 	def merge(enum)
# 	  enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
# 	  enum.each { |o| add(o) }
# 
# 	  self
# 	end
#       }
#     else
#       instance_eval %{
# 	def add(o)
#         if @proc.call(o)
# 	    @hash[o] = true 
#         end
# 	  self
# 	end
# 	alias << add
# 
# 	def add?(o)
# 	  if include?(o) || !@proc.call(o)
# 	    nil
# 	  else
# 	    @hash[o] = true
# 	    self
# 	  end
# 	end
#       }
#     end
# 
#     super(*args)
#   end
# 
#   def restriction_proc
#     @proc
#   end
# end

if $0 == __FILE__
  eval DATA.read, nil, $0, __LINE__+4
end

__END__

require 'test/unit'

class TC_Set < Test::Unit::TestCase
  def test_aref
    assert_nothing_raised {
      Set[]
      Set[nil]
      Set[1,2,3]
    }

    assert_equal(0, Set[].size)
    assert_equal(1, Set[nil].size)
    assert_equal(1, Set[[]].size)
    assert_equal(1, Set[[nil]].size)

    set = Set[2,4,6,4]
    assert_equal(Set.new([2,4,6]), set)
  end

  def test_s_new
    assert_nothing_raised {
      Set.new()
      Set.new(nil)
      Set.new([])
      Set.new([1,2])
      Set.new('a'..'c')
      Set.new('XYZ')
    }
    assert_raises(ArgumentError) {
      Set.new(false)
    }
    assert_raises(ArgumentError) {
      Set.new(1)
    }
    assert_raises(ArgumentError) {
      Set.new(1,2)
    }

    assert_equal(0, Set.new().size)
    assert_equal(0, Set.new(nil).size)
    assert_equal(0, Set.new([]).size)
    assert_equal(1, Set.new([nil]).size)

    ary = [2,4,6,4]
    set = Set.new(ary)
    ary.clear
    assert_equal(false, set.empty?)
    assert_equal(3, set.size)

    ary = [1,2,3]

    s = Set.new(ary) { |o| o * 2 }
    assert_equal([2,4,6], s.sort)
  end

  def test_clone
    set1 = Set.new
    set2 = set1.clone
    set1 << 'abc'
    assert_equal(Set.new, set2)
  end

  def test_dup
    set1 = Set[1,2]
    set2 = set1.dup

    assert_not_same(set1, set2)

    assert_equal(set1, set2)

    set1.add(3)

    assert_not_equal(set1, set2)
  end

  def test_size
    assert_equal(0, Set[].size)
    assert_equal(2, Set[1,2].size)
    assert_equal(2, Set[1,2,1].size)
  end

  def test_empty?
    assert_equal(true, Set[].empty?)
    assert_equal(false, Set[1, 2].empty?)
  end

  def test_clear
    set = Set[1,2]
    ret = set.clear

    assert_same(set, ret)
    assert_equal(true, set.empty?)
  end

  def test_replace
    set = Set[1,2]
    ret = set.replace('a'..'c')

    assert_same(set, ret)
    assert_equal(Set['a','b','c'], set)
  end

  def test_to_a
    set = Set[1,2,3,2]
    ary = set.to_a

    assert_equal([1,2,3], ary.sort)
  end

  def test_flatten
    # test1
    set1 = Set[
      1,
      Set[
	5,
	Set[7,
	  Set[0]
	],
	Set[6,2],
	1
      ],
      3,
      Set[3,4]
    ]

    set2 = set1.flatten
    set3 = Set.new(0..7)

    assert_not_same(set2, set1)
    assert_equal(set3, set2)

    # test2; destructive
    orig_set1 = set1
    set1.flatten!

    assert_same(orig_set1, set1)
    assert_equal(set3, set1)

    # test3; multiple occurrences of a set in an set
    set1 = Set[1, 2]
    set2 = Set[set1, Set[set1, 4], 3]

    assert_nothing_raised {
      set2.flatten!
    }

    assert_equal(Set.new(1..4), set2)

    # test4; recursion
    set2 = Set[]
    set1 = Set[1, set2]
    set2.add(set1)

    assert_raises(ArgumentError) {
      set1.flatten!
    }

    # test5; miscellaneous
    empty = Set[]
    set =  Set[Set[empty, "a"],Set[empty, "b"]]

    assert_nothing_raised {
      set.flatten
    }

    set1 = empty.merge(Set["no_more", set])

    assert_nil(Set.new(0..31).flatten!)

    x = Set[Set[],Set[1,2]].flatten!
    y = Set[1,2]

    assert_equal(x, y)
  end

  def test_include?
    set = Set[1,2,3]

    assert_equal(true, set.include?(1))
    assert_equal(true, set.include?(2))
    assert_equal(true, set.include?(3))
    assert_equal(false, set.include?(0))
    assert_equal(false, set.include?(nil))

    set = Set["1",nil,"2",nil,"0","1",false]
    assert_equal(true, set.include?(nil))
    assert_equal(true, set.include?(false))
    assert_equal(true, set.include?("1"))
    assert_equal(false, set.include?(0))
    assert_equal(false, set.include?(true))
  end

  def test_superset?
    set = Set[1,2,3]

    assert_raises(ArgumentError) {
      set.superset?()
    }

    assert_raises(ArgumentError) {
      set.superset?(2)
    }

    assert_raises(ArgumentError) {
      set.superset?([2])
    }

    assert_equal(true, set.superset?(Set[]))
    assert_equal(true, set.superset?(Set[1,2]))
    assert_equal(true, set.superset?(Set[1,2,3]))
    assert_equal(false, set.superset?(Set[1,2,3,4]))
    assert_equal(false, set.superset?(Set[1,4]))

    assert_equal(true, Set[].superset?(Set[]))
  end

  def test_proper_superset?
    set = Set[1,2,3]

    assert_raises(ArgumentError) {
      set.proper_superset?()
    }

    assert_raises(ArgumentError) {
      set.proper_superset?(2)
    }

    assert_raises(ArgumentError) {
      set.proper_superset?([2])
    }

    assert_equal(true, set.proper_superset?(Set[]))
    assert_equal(true, set.proper_superset?(Set[1,2]))
    assert_equal(false, set.proper_superset?(Set[1,2,3]))
    assert_equal(false, set.proper_superset?(Set[1,2,3,4]))
    assert_equal(false, set.proper_superset?(Set[1,4]))

    assert_equal(false, Set[].proper_superset?(Set[]))
  end

  def test_subset?
    set = Set[1,2,3]

    assert_raises(ArgumentError) {
      set.subset?()
    }

    assert_raises(ArgumentError) {
      set.subset?(2)
    }

    assert_raises(ArgumentError) {
      set.subset?([2])
    }

    assert_equal(true, set.subset?(Set[1,2,3,4]))
    assert_equal(true, set.subset?(Set[1,2,3]))
    assert_equal(false, set.subset?(Set[1,2]))
    assert_equal(false, set.subset?(Set[]))

    assert_equal(true, Set[].subset?(Set[1]))
    assert_equal(true, Set[].subset?(Set[]))
  end

  def test_proper_subset?
    set = Set[1,2,3]

    assert_raises(ArgumentError) {
      set.proper_subset?()
    }

    assert_raises(ArgumentError) {
      set.proper_subset?(2)
    }

    assert_raises(ArgumentError) {
      set.proper_subset?([2])
    }

    assert_equal(true, set.proper_subset?(Set[1,2,3,4]))
    assert_equal(false, set.proper_subset?(Set[1,2,3]))
    assert_equal(false, set.proper_subset?(Set[1,2]))
    assert_equal(false, set.proper_subset?(Set[]))

    assert_equal(false, Set[].proper_subset?(Set[]))
  end

  def test_each
    ary = [1,3,5,7,10,20]
    set = Set.new(ary)

    ret = set.each { |o| }
    assert_same(set, ret)

    e = set.each
    assert_instance_of(Enumerable::Enumerator, e)

    assert_nothing_raised {
      set.each { |o|
	ary.delete(o) or raise "unexpected element: #{o}"
      }

      ary.empty? or raise "forgotten elements: #{ary.join(', ')}"
    }
  end

  def test_add
    set = Set[1,2,3]

    ret = set.add(2)
    assert_same(set, ret)
    assert_equal(Set[1,2,3], set)

    ret = set.add?(2)
    assert_nil(ret)
    assert_equal(Set[1,2,3], set)

    ret = set.add(4)
    assert_same(set, ret)
    assert_equal(Set[1,2,3,4], set)

    ret = set.add?(5)
    assert_same(set, ret)
    assert_equal(Set[1,2,3,4,5], set)
  end

  def test_delete
    set = Set[1,2,3]

    ret = set.delete(4)
    assert_same(set, ret)
    assert_equal(Set[1,2,3], set)

    ret = set.delete?(4)
    assert_nil(ret)
    assert_equal(Set[1,2,3], set)

    ret = set.delete(2)
    assert_equal(set, ret)
    assert_equal(Set[1,3], set)

    ret = set.delete?(1)
    assert_equal(set, ret)
    assert_equal(Set[3], set)
  end

  def test_delete_if
    set = Set.new(1..10)
    ret = set.delete_if { |i| i > 10 }
    assert_same(set, ret)
    assert_equal(Set.new(1..10), set)

    set = Set.new(1..10)
    ret = set.delete_if { |i| i % 3 == 0 }
    assert_same(set, ret)
    assert_equal(Set[1,2,4,5,7,8,10], set)
  end

  def test_collect!
    set = Set[1,2,3,'a','b','c',-1..1,2..4]

    ret = set.collect! { |i|
      case i
      when Numeric
	i * 2
      when String
	i.upcase
      else
	nil
      end
    }

    assert_same(set, ret)
    assert_equal(Set[2,4,6,'A','B','C',nil], set)
  end

  def test_reject!
    set = Set.new(1..10)

    ret = set.reject! { |i| i > 10 }
    assert_nil(ret)
    assert_equal(Set.new(1..10), set)

    ret = set.reject! { |i| i % 3 == 0 }
    assert_same(set, ret)
    assert_equal(Set[1,2,4,5,7,8,10], set)
  end

  def test_merge
    set = Set[1,2,3]

    ret = set.merge([2,4,6])
    assert_same(set, ret)
    assert_equal(Set[1,2,3,4,6], set)
  end

  def test_subtract
    set = Set[1,2,3]

    ret = set.subtract([2,4,6])
    assert_same(set, ret)
    assert_equal(Set[1,3], set)
  end

  def test_plus
    set = Set[1,2,3]

    ret = set + [2,4,6]
    assert_not_same(set, ret)
    assert_equal(Set[1,2,3,4,6], ret)
  end

  def test_minus
    set = Set[1,2,3]

    ret = set - [2,4,6]
    assert_not_same(set, ret)
    assert_equal(Set[1,3], ret)
  end

  def test_and
    set = Set[1,2,3,4]

    ret = set & [2,4,6]
    assert_not_same(set, ret)
    assert_equal(Set[2,4], ret)
  end

  def test_xor
    set = Set[1,2,3,4]
    ret = set ^ [2,4,5,5]
    assert_not_same(set, ret)
    assert_equal(Set[1,3,5], ret)
  end

  def test_eq
    set1 = Set[2,3,1]
    set2 = Set[1,2,3]

    assert_equal(set1, set1)
    assert_equal(set1, set2)
    assert_not_equal(Set[1], [1])

    set1 = Class.new(Set)["a", "b"]
    set2 = Set["a", "b", set1]
    set1 = set1.add(set1.clone)

#    assert_equal(set1, set2)
#    assert_equal(set2, set1)
    assert_equal(set2, set2.clone)
    assert_equal(set1.clone, set1)

    assert_not_equal(Set[Exception.new,nil], Set[Exception.new,Exception.new], "[ruby-dev:26127]")
  end

  # def test_hash
  # end

  # def test_eql?
  # end

  def test_classify
    set = Set.new(1..10)
    ret = set.classify { |i| i % 3 }

    assert_equal(3, ret.size)
    assert_instance_of(Hash, ret)
    ret.each_value { |value| assert_instance_of(Set, value) }
    assert_equal(Set[3,6,9], ret[0])
    assert_equal(Set[1,4,7,10], ret[1])
    assert_equal(Set[2,5,8], ret[2])
  end

  def test_divide
    set = Set.new(1..10)
    ret = set.divide { |i| i % 3 }

    assert_equal(3, ret.size)
    n = 0
    ret.each { |s| n += s.size }
    assert_equal(set.size, n)
    assert_equal(set, ret.flatten)

    set = Set[7,10,5,11,1,3,4,9,0]
    ret = set.divide { |a,b| (a - b).abs == 1 }

    assert_equal(4, ret.size)
    n = 0
    ret.each { |s| n += s.size }
    assert_equal(set.size, n)
    assert_equal(set, ret.flatten)
    ret.each { |s|
      if s.include?(0)
	assert_equal(Set[0,1], s)
      elsif s.include?(3)
	assert_equal(Set[3,4,5], s)
      elsif s.include?(7)
	assert_equal(Set[7], s)
      elsif s.include?(9)
	assert_equal(Set[9,10,11], s)
      else
	raise "unexpected group: #{s.inspect}"
      end
    }
  end

  def test_inspect
    set1 = Set[1]

    assert_equal('#<Set: {1}>', set1.inspect)

    set2 = Set[Set[0], 1, 2, set1]
    assert_equal(false, set2.inspect.include?('#<Set: {...}>'))

    set1.add(set2)
    assert_equal(true, set1.inspect.include?('#<Set: {...}>'))
  end

  # def test_pretty_print
  # end

  # def test_pretty_print_cycle
  # end
end

class TC_SortedSet < Test::Unit::TestCase
  def test_sortedset
    s = SortedSet[4,5,3,1,2]

    assert_equal([1,2,3,4,5], s.to_a)

    prev = nil
    s.each { |o| assert(prev < o) if prev; prev = o }
    assert_not_nil(prev)

    s.map! { |o| -2 * o }

    assert_equal([-10,-8,-6,-4,-2], s.to_a)

    prev = nil
    ret = s.each { |o| assert(prev < o) if prev; prev = o }
    assert_not_nil(prev)
    assert_same(s, ret)

    s = SortedSet.new([2,1,3]) { |o| o * -2 }
    assert_equal([-6,-4,-2], s.to_a)

    s = SortedSet.new(['one', 'two', 'three', 'four'])
    a = []
    ret = s.delete_if { |o| a << o; o.start_with?('t') }
    assert_same(s, ret)
    assert_equal(['four', 'one'], s.to_a)
    assert_equal(['four', 'one', 'three', 'two'], a)

    s = SortedSet.new(['one', 'two', 'three', 'four'])
    a = []
    ret = s.reject! { |o| a << o; o.start_with?('t') }
    assert_same(s, ret)
    assert_equal(['four', 'one'], s.to_a)
    assert_equal(['four', 'one', 'three', 'two'], a)

    s = SortedSet.new(['one', 'two', 'three', 'four'])
    a = []
    ret = s.reject! { |o| a << o; false }
    assert_same(nil, ret)
    assert_equal(['four', 'one', 'three', 'two'], s.to_a)
    assert_equal(['four', 'one', 'three', 'two'], a)
  end
end

class TC_Enumerable < Test::Unit::TestCase
  def test_to_set
    ary = [2,5,4,3,2,1,3]

    set = ary.to_set
    assert_instance_of(Set, set)
    assert_equal([1,2,3,4,5], set.sort)

    set = ary.to_set { |o| o * -2 }
    assert_instance_of(Set, set)
    assert_equal([-10,-8,-6,-4,-2], set.sort)

    set = ary.to_set(SortedSet)
    assert_instance_of(SortedSet, set)
    assert_equal([1,2,3,4,5], set.to_a)

    set = ary.to_set(SortedSet) { |o| o * -2 }
    assert_instance_of(SortedSet, set)
    assert_equal([-10,-8,-6,-4,-2], set.sort)
  end
end

# class TC_RestricedSet < Test::Unit::TestCase
#   def test_s_new
#     assert_raises(ArgumentError) { RestricedSet.new }
# 
#     s = RestricedSet.new([-1,2,3]) { |o| o > 0 }
#     assert_equal([2,3], s.sort)
#   end
# 
#   def test_restriction_proc
#     s = RestricedSet.new([-1,2,3]) { |o| o > 0 }
# 
#     f = s.restriction_proc
#     assert_instance_of(Proc, f)
#     assert(f[1])
#     assert(!f[0])
#   end
# 
#   def test_replace
#     s = RestricedSet.new(-3..3) { |o| o > 0 }
#     assert_equal([1,2,3], s.sort)
# 
#     s.replace([-2,0,3,4,5])
#     assert_equal([3,4,5], s.sort)
#   end
# 
#   def test_merge
#     s = RestricedSet.new { |o| o > 0 }
#     s.merge(-5..5)
#     assert_equal([1,2,3,4,5], s.sort)
# 
#     s.merge([10,-10,-8,8])
#     assert_equal([1,2,3,4,5,8,10], s.sort)
#   end
# end
PK     Y\N>el1  l1    yaml.rbnu [        # -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
# $Id: yaml.rb 16084 2008-04-19 11:45:39Z knu $
#
# = yaml.rb: top-level module with methods for loading and parsing YAML documents
#
# Author:: why the lucky stiff
# 

require 'stringio'
require 'yaml/error'
require 'yaml/syck'
require 'yaml/tag'
require 'yaml/stream'
require 'yaml/constants'

# == YAML
#
# YAML(tm) (rhymes with 'camel') is a
# straightforward machine parsable data serialization format designed for
# human readability and interaction with scripting languages such as Perl
# and Python. YAML is optimized for data serialization, formatted
# dumping, configuration files, log files, Internet messaging and
# filtering. This specification describes the YAML information model and
# serialization format. Together with the Unicode standard for characters, it
# provides all the information necessary to understand YAML Version 1.0
# and construct computer programs to process it.
#                         
# See http://yaml.org/ for more information.  For a quick tutorial, please
# visit YAML In Five Minutes (http://yaml.kwiki.org/?YamlInFiveMinutes).
#                              
# == About This Library
#                         
# The YAML 1.0 specification outlines four stages of YAML loading and dumping.
# This library honors all four of those stages, although data is really only
# available to you in three stages.
#     
# The four stages are: native, representation, serialization, and presentation.
#     
# The native stage refers to data which has been loaded completely into Ruby's
# own types. (See +YAML::load+.)
#
# The representation stage means data which has been composed into
# +YAML::BaseNode+ objects.  In this stage, the document is available as a
# tree of node objects.  You can perform YPath queries and transformations
# at this level.  (See +YAML::parse+.)
#   
# The serialization stage happens inside the parser.  The YAML parser used in
# Ruby is called Syck.  Serialized nodes are available in the extension as
# SyckNode structs.
#       
# The presentation stage is the YAML document itself.  This is accessible
# to you as a string.  (See +YAML::dump+.)
#   
# For more information about the various information models, see Chapter
# 3 of the YAML 1.0 Specification (http://yaml.org/spec/#id2491269).
#
# The YAML module provides quick access to the most common loading (YAML::load)
# and dumping (YAML::dump) tasks.  This module also provides an API for registering
# global types (YAML::add_domain_type).
#
# == Example
#
# A simple round-trip (load and dump) of an object.
#
#     require "yaml"
#
#     test_obj = ["dogs", "cats", "badgers"]
#
#     yaml_obj = YAML::dump( test_obj )
#                         # -> ---
#                              - dogs
#                              - cats
#                              - badgers
#     ruby_obj = YAML::load( yaml_obj )
#                         # => ["dogs", "cats", "badgers"]
#     ruby_obj == test_obj
#                         # => true
#
# To register your custom types with the global resolver, use +add_domain_type+.
#
#     YAML::add_domain_type( "your-site.com,2004", "widget" ) do |type, val|
#         Widget.new( val )
#     end
#
module YAML

    Resolver = YAML::Syck::Resolver
    DefaultResolver = YAML::Syck::DefaultResolver
    DefaultResolver.use_types_at( @@tagged_classes )
    GenericResolver = YAML::Syck::GenericResolver
    Parser = YAML::Syck::Parser
    Emitter = YAML::Syck::Emitter

    # Returns a new default parser
    def YAML.parser; Parser.new.set_resolver( YAML.resolver ); end
    # Returns a new generic parser
    def YAML.generic_parser; Parser.new.set_resolver( GenericResolver ); end
    # Returns the default resolver
    def YAML.resolver; DefaultResolver; end
    # Returns a new default emitter
    def YAML.emitter; Emitter.new.set_resolver( YAML.resolver ); end

	#
	# Converts _obj_ to YAML and writes the YAML result to _io_.
    #     
    #   File.open( 'animals.yaml', 'w' ) do |out|
    #     YAML.dump( ['badger', 'elephant', 'tiger'], out )
    #   end
    #
    # If no _io_ is provided, a string containing the dumped YAML
    # is returned.
	#
    #   YAML.dump( :locked )
    #      #=> "--- :locked"
    #
	def YAML.dump( obj, io = nil )
        obj.to_yaml( io || io2 = StringIO.new )
        io || ( io2.rewind; io2.read )
	end

	#
	# Load a document from the current _io_ stream.
	#
    #   File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) }
    #      #=> ['badger', 'elephant', 'tiger']
    #
    # Can also load from a string.
    #
    #   YAML.load( "--- :locked" )
    #      #=> :locked
    #
	def YAML.load( io )
		yp = parser.load( io )
	end

    #
    # Load a document from the file located at _filepath_.
    #
    #   YAML.load_file( 'animals.yaml' )
    #      #=> ['badger', 'elephant', 'tiger']
    #
    def YAML.load_file( filepath )
        File.open( filepath ) do |f|
            load( f )
        end
    end

	#
	# Parse the first document from the current _io_ stream
	#
    #   File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) }
    #      #=> #<YAML::Syck::Node:0x82ccce0
    #           @kind=:seq,
    #           @value=
    #            [#<YAML::Syck::Node:0x82ccd94
    #              @kind=:scalar,
    #              @type_id="str",
    #              @value="badger">,
    #             #<YAML::Syck::Node:0x82ccd58
    #              @kind=:scalar,
    #              @type_id="str",
    #              @value="elephant">,
    #             #<YAML::Syck::Node:0x82ccd1c
    #              @kind=:scalar,
    #              @type_id="str",
    #              @value="tiger">]>
    #
    # Can also load from a string.
    #
    #   YAML.parse( "--- :locked" )
    #      #=> #<YAML::Syck::Node:0x82edddc 
    #            @type_id="tag:ruby.yaml.org,2002:sym", 
    #            @value=":locked", @kind=:scalar>
    #
	def YAML.parse( io )
		yp = generic_parser.load( io )
	end

    #
    # Parse a document from the file located at _filepath_.
    #
    #   YAML.parse_file( 'animals.yaml' )
    #      #=> #<YAML::Syck::Node:0x82ccce0
    #           @kind=:seq,
    #           @value=
    #            [#<YAML::Syck::Node:0x82ccd94
    #              @kind=:scalar,
    #              @type_id="str",
    #              @value="badger">,
    #             #<YAML::Syck::Node:0x82ccd58
    #              @kind=:scalar,
    #              @type_id="str",
    #              @value="elephant">,
    #             #<YAML::Syck::Node:0x82ccd1c
    #              @kind=:scalar,
    #              @type_id="str",
    #              @value="tiger">]>
    #
    def YAML.parse_file( filepath )
        File.open( filepath ) do |f|
            parse( f )
        end
    end

	#
	# Calls _block_ with each consecutive document in the YAML
    # stream contained in _io_.
    #
    #   File.open( 'many-docs.yaml' ) do |yf|
    #     YAML.each_document( yf ) do |ydoc|
    #       ## ydoc contains the single object
    #       ## from the YAML document
    #     end
    #   end
	#
	def YAML.each_document( io, &block )
		yp = parser.load_documents( io, &block )
    end

	#
	# Calls _block_ with each consecutive document in the YAML
    # stream contained in _io_.
    #
    #   File.open( 'many-docs.yaml' ) do |yf|
    #     YAML.load_documents( yf ) do |ydoc|
    #       ## ydoc contains the single object
    #       ## from the YAML document
    #     end
    #   end
	#
	def YAML.load_documents( io, &doc_proc )
		YAML.each_document( io, &doc_proc )
    end

	#
	# Calls _block_ with a tree of +YAML::BaseNodes+, one tree for
    # each consecutive document in the YAML stream contained in _io_.
    #
    #   File.open( 'many-docs.yaml' ) do |yf|
    #     YAML.each_node( yf ) do |ydoc|
    #       ## ydoc contains a tree of nodes
    #       ## from the YAML document
    #     end
    #   end
	#
	def YAML.each_node( io, &doc_proc )
		yp = generic_parser.load_documents( io, &doc_proc )
    end

	#
	# Calls _block_ with a tree of +YAML::BaseNodes+, one tree for
    # each consecutive document in the YAML stream contained in _io_.
    #
    #   File.open( 'many-docs.yaml' ) do |yf|
    #     YAML.parse_documents( yf ) do |ydoc|
    #       ## ydoc contains a tree of nodes
    #       ## from the YAML document
    #     end
    #   end
	#
	def YAML.parse_documents( io, &doc_proc )
		YAML.each_node( io, &doc_proc )
    end

	#
	# Loads all documents from the current _io_ stream, 
    # returning a +YAML::Stream+ object containing all
    # loaded documents.
	#
	def YAML.load_stream( io )
		d = nil
		parser.load_documents( io ) do |doc|
			d = YAML::Stream.new if not d
			d.add( doc ) 
        end
		return d
	end

	#
    # Returns a YAML stream containing each of the items in +objs+,
    # each having their own document.
    #
    #   YAML.dump_stream( 0, [], {} )
    #     #=> --- 0
    #         --- []
    #         --- {}
    #
	def YAML.dump_stream( *objs )
		d = YAML::Stream.new
        objs.each do |doc|
			d.add( doc ) 
        end
        d.emit
	end

	#
	# Add a global handler for a YAML domain type.
	#
	def YAML.add_domain_type( domain, type_tag, &transfer_proc )
        resolver.add_type( "tag:#{ domain }:#{ type_tag }", transfer_proc )
	end

	#
	# Add a transfer method for a builtin type
	#
	def YAML.add_builtin_type( type_tag, &transfer_proc )
	    resolver.add_type( "tag:yaml.org,2002:#{ type_tag }", transfer_proc )
	end

	#
	# Add a transfer method for a builtin type
	#
	def YAML.add_ruby_type( type_tag, &transfer_proc )
	    resolver.add_type( "tag:ruby.yaml.org,2002:#{ type_tag }", transfer_proc )
	end

	#
	# Add a private document type
	#
	def YAML.add_private_type( type_re, &transfer_proc )
	    resolver.add_type( "x-private:" + type_re, transfer_proc )
	end

    #
    # Detect typing of a string
    #
    def YAML.detect_implicit( val )
        resolver.detect_implicit( val )
    end

    #
    # Convert a type_id to a taguri
    #
    def YAML.tagurize( val )
        resolver.tagurize( val )
    end

    #
    # Apply a transfer method to a Ruby object
    #
    def YAML.transfer( type_id, obj )
        resolver.transfer( YAML.tagurize( type_id ), obj )
    end

	#
	# Apply any implicit a node may qualify for
	#
	def YAML.try_implicit( obj )
		YAML.transfer( YAML.detect_implicit( obj ), obj )
	end

    #
    # Method to extract colon-seperated type and class, returning
    # the type and the constant of the class
    #
    def YAML.read_type_class( type, obj_class )
        scheme, domain, type, tclass = type.split( ':', 4 )
        tclass.split( "::" ).each { |c| obj_class = obj_class.const_get( c ) } if tclass
        return [ type, obj_class ]
    end

    #
    # Allocate blank object
    #
    def YAML.object_maker( obj_class, val )
        if Hash === val
            o = obj_class.allocate
            val.each_pair { |k,v|
                o.instance_variable_set("@#{k}", v)
            }
            o
        else
            raise YAML::Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect
        end
    end

	#
	# Allocate an Emitter if needed
	#
	def YAML.quick_emit( oid, opts = {}, &e )
        out = 
            if opts.is_a? YAML::Emitter
                opts
            else
                emitter.reset( opts )
            end
        oid =
            case oid when Fixnum, NilClass; oid
            else oid = "#{oid.object_id}-#{oid.hash}"
            end
        out.emit( oid, &e )
	end
	
end

require 'yaml/rubytypes'
require 'yaml/types'

module Kernel
    #
    # ryan:: You know how Kernel.p is a really convenient way to dump ruby
    #        structures?  The only downside is that it's not as legible as
    #        YAML.
    #
    # _why:: (listening)
    #
    # ryan:: I know you don't want to urinate all over your users' namespaces.
    #        But, on the other hand, convenience of dumping for debugging is,
    #        IMO, a big YAML use case.
    #
    # _why:: Go nuts!  Have a pony parade!
    #
    # ryan:: Either way, I certainly will have a pony parade.
    #

    # Prints any supplied _objects_ out in YAML.  Intended as
    # a variation on +Kernel::p+.
    #
    #   S = Struct.new(:name, :state)
    #   s = S['dave', 'TX']
    #   y s
    #
    # _produces:_
    #
    #   --- !ruby/struct:S 
    #   name: dave
    #   state: TX
    #
    def y( object, *objects )
        objects.unshift object
        puts( if objects.length == 1
                  YAML::dump( *objects )
              else
                  YAML::dump_stream( *objects )
              end )
    end
    private :y
end


PK     Y\Q        rubyunit.rbnu [        # Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'runit/testcase'
require 'test/unit'
PK     Y\8h   h   	  thread.rbnu [        unless defined? Thread
  fail "Thread not available for this ruby interpreter"
end

require 'thread.so'
PK     Y\V	    
  cgi-lib.rbnu [        warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: cgi-lib is deprecated after Ruby 1.8.1; use cgi instead"

=begin

= simple CGI support library

= example

== get form values

	require "cgi-lib.rb"
	query = CGI.new
	query['field']   # <== value of 'field'
	query.keys       # <== array of fields

and query has Hash class methods


== get cookie values

	require "cgi-lib.rb"
	query = CGI.new
	query.cookie['name']  # <== cookie value of 'name'
	query.cookie.keys     # <== all cookie names

and query.cookie has Hash class methods


== print HTTP header and HTML string to $>

	require "cgi-lib.rb"
	CGI::print{
	  CGI::tag("HTML"){
	    CGI::tag("HEAD"){ CGI::tag("TITLE"){"TITLE"} } +
	    CGI::tag("BODY"){
	      CGI::tag("FORM", {"ACTION"=>"test.rb", "METHOD"=>"POST"}){
	        CGI::tag("INPUT", {"TYPE"=>"submit", "VALUE"=>"submit"})
	      } +
	      CGI::tag("HR")
	    }
	  }
	}


== make raw cookie string

	require "cgi-lib.rb"
	cookie1 = CGI::cookie({'name'    => 'name',
	                       'value'   => 'value',
	                       'path'    => 'path',   # optional
	                       'domain'  => 'domain', # optional
	                       'expires' => Time.now, # optional
	                       'secure'  => true      # optional
	                      })

	CGI::print("Content-Type: text/html", cookie1, cookie2){ "string" }


== print HTTP header and string to $>

	require "cgi-lib.rb"
	CGI::print{ "string" }
	  # == CGI::print("Content-Type: text/html"){ "string" }
	CGI::print("Content-Type: text/html", cookie1, cookie2){ "string" }


=== NPH (no-parse-header) mode

	require "cgi-lib.rb"
	CGI::print("nph"){ "string" }
	  # == CGI::print("nph", "Content-Type: text/html"){ "string" }
	CGI::print("nph", "Content-Type: text/html", cookie1, cookie2){ "string" }


== make HTML tag string

	require "cgi-lib.rb"
	CGI::tag("element", {"attribute_name"=>"attribute_value"}){"content"}


== make HTTP header string

	require "cgi-lib.rb"
	CGI::header # == CGI::header("Content-Type: text/html")
	CGI::header("Content-Type: text/html", cookie1, cookie2)


=== NPH (no-parse-header) mode

	CGI::header("nph") # == CGI::header("nph", "Content-Type: text/html")
	CGI::header("nph", "Content-Type: text/html", cookie1, cookie2)


== escape url encode

	require "cgi-lib.rb"
	url_encoded_string = CGI::escape("string")


== unescape url encoded

	require "cgi-lib.rb"
	string = CGI::unescape("url encoded string")


== escape HTML &"<>

	require "cgi-lib.rb"
	CGI::escapeHTML("string")


=end

require "delegate"

class CGI < SimpleDelegator

  CR  = "\015"
  LF  = "\012"
  EOL = CR + LF

  RFC822_DAYS = %w[ Sun Mon Tue Wed Thu Fri Sat ]
  RFC822_MONTHS = %w[ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ]

  # make rfc1123 date string
  def CGI::rfc1123_date(time)
    t = time.clone.gmtime
    return format("%s, %.2d %s %d %.2d:%.2d:%.2d GMT",
                RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year,
                t.hour, t.min, t.sec)
  end

  # escape url encode
  def CGI::escape(str)
    str.gsub(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) }
  end

  # unescape url encoded
  def CGI::unescape(str)
    str.gsub(/\+/, ' ').gsub(/%([0-9a-fA-F]{2})/){ [$1.hex].pack("c") }
  end

  # escape HTML
  def CGI::escapeHTML(str)
    str.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
  end

  # offline mode. read name=value pairs on standard input.
  def read_from_cmdline
    require "shellwords.rb"
    words = Shellwords.shellwords(
              if not ARGV.empty?
                ARGV.join(' ')
              else
                STDERR.print "(offline mode: enter name=value pairs on standard input)\n" if STDIN.tty?
                readlines.join(' ').gsub(/\n/, '')
              end.gsub(/\\=/, '%3D').gsub(/\\&/, '%26'))

    if words.find{|x| x =~ /=/} then words.join('&') else words.join('+') end
  end

  def initialize(input = $stdin)

    @inputs = {}
    @cookie = {}

    case ENV['REQUEST_METHOD']
    when "GET"
      ENV['QUERY_STRING'] or ""
    when "POST"
      input.read(Integer(ENV['CONTENT_LENGTH'])) or ""
    else
      read_from_cmdline
    end.split(/[&;]/).each do |x|
      key, val = x.split(/=/,2).collect{|x|CGI::unescape(x)}
      if @inputs.include?(key)
        @inputs[key] += "\0" + (val or "")
      else
        @inputs[key] = (val or "")
      end
    end

    super(@inputs)

    if ENV.has_key?('HTTP_COOKIE') or ENV.has_key?('COOKIE')
      (ENV['HTTP_COOKIE'] or ENV['COOKIE']).split(/; /).each do |x|
        key, val = x.split(/=/,2)
        key = CGI::unescape(key)
        val = val.split(/&/).collect{|x|CGI::unescape(x)}.join("\0")
        if @cookie.include?(key)
          @cookie[key] += "\0" + val
        else
          @cookie[key] = val
        end
      end
    end
  end

  attr("inputs")
  attr("cookie")

  # make HTML tag string
  def CGI::tag(element, attributes = {})
    "<" + escapeHTML(element) + attributes.collect{|name, value|
      " " + escapeHTML(name) + '="' + escapeHTML(value) + '"'
    }.to_s + ">" +
    (iterator? ? yield.to_s + "</" + escapeHTML(element) + ">" : "")
  end

  # make raw cookie string
  def CGI::cookie(options)
    "Set-Cookie: " + options['name'] + '=' + escape(options['value']) +
    (options['domain']  ? '; domain='  + options['domain'] : '') +
    (options['path']    ? '; path='    + options['path']   : '') +
    (options['expires'] ? '; expires=' + rfc1123_date(options['expires']) : '') +
    (options['secure']  ? '; secure' : '')
  end

  # make HTTP header string
  def CGI::header(*options)
    if defined?(MOD_RUBY)
      options.each{|option|
        option.sub(/(.*?): (.*)/){
          Apache::request.headers_out[$1] = $2
        }
      }
      Apache::request.send_http_header
      ''
    else
      if options.delete("nph") or (ENV['SERVER_SOFTWARE'] =~ /IIS/)
        [(ENV['SERVER_PROTOCOL'] or "HTTP/1.0") + " 200 OK",
         "Date: " + rfc1123_date(Time.now),
         "Server: " + (ENV['SERVER_SOFTWARE'] or ""),
         "Connection: close"] +
        (options.empty? ? ["Content-Type: text/html"] : options)
      else
        options.empty? ? ["Content-Type: text/html"] : options
      end.join(EOL) + EOL + EOL
    end
  end

  # print HTTP header and string to $>
  def CGI::print(*options)
    $>.print CGI::header(*options) + yield.to_s
  end

  # print message to $>
  def CGI::message(message, title = "", header = ["Content-Type: text/html"])
    if message.kind_of?(Hash)
      title   = message['title']
      header  = message['header']
      message = message['body']
    end
    CGI::print(*header){
      CGI::tag("HTML"){
        CGI::tag("HEAD"){ CGI.tag("TITLE"){ title } } +
        CGI::tag("BODY"){ message }
      }
    }
    true
  end

  # print error message to $> and exit
  def CGI::error
    CGI::message({'title'=>'ERROR', 'body'=>
      CGI::tag("PRE"){
        "ERROR: " + CGI::tag("STRONG"){ escapeHTML($!.to_s) } + "\n" + escapeHTML($@.join("\n"))
      }
    })
    exit
  end
end
PK     Y\:      digest/sha2.rbnu [        #--
# sha2.rb - defines Digest::SHA2 class which wraps up the SHA256,
#           SHA384, and SHA512 classes.
#++
# Copyright (c) 2006 Akinori MUSHA <knu@iDaemons.org>
#
# All rights reserved.  You can redistribute and/or modify it under the same
# terms as Ruby.
#
#   $Id: sha2.rb 11708 2007-02-12 23:01:19Z shyouhei $

require 'digest'

module Digest
  #
  # A meta digest provider class for SHA256, SHA384 and SHA512.
  #
  class SHA2 < Digest::Class
    # call-seq:
    #     Digest::SHA2.new(bitlen = 256) -> digest_obj
    #
    # Creates a new SHA2 hash object with a given bit length.
    def initialize(bitlen = 256)
      case bitlen
      when 256
        @sha2 = Digest::SHA256.new
      when 384
        @sha2 = Digest::SHA384.new
      when 512
        @sha2 = Digest::SHA512.new
      else
        raise ArgumentError, "unsupported bit length: %s" % bitlen.inspect
      end
      @bitlen = bitlen
    end

    # :nodoc:
    def reset
      @sha2.reset
      self
    end

    # :nodoc:
    def update(str)
      @sha2.update(str)
      self
    end
    alias << update

    def finish
      @sha2.digest!
    end
    private :finish

    def block_length
      @sha2.block_length
    end

    def digest_length
      @sha2.digest_length
    end

    # :nodoc:
    def initialize_copy(other)
      @sha2 = other.instance_eval { @sha2.clone }
    end

    # :nodoc:
    def inspect
      "#<%s:%d %s>" % [self.class.name, @bitlen, hexdigest]
    end
  end
end
PK     Y\?  ?  
  openssl.rbnu [        =begin
= $RCSfile$ -- Loader for all OpenSSL C-space and Ruby-space definitions

= Info
  'OpenSSL for Ruby 2' project
  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>
  All rights reserved.

= Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

= Version
  $Id: openssl.rb 29856 2010-11-22 07:21:45Z shyouhei $
=end

require 'openssl.so'

require 'openssl/bn'
require 'openssl/cipher'
require 'openssl/config'
require 'openssl/digest'
require 'openssl/pkcs7'
require 'openssl/ssl-internal'
require 'openssl/x509-internal'

PK     Y\1w      rss.rbnu [        # Copyright (c) 2003-2007 Kouhei Sutou.  You can redistribute it and/or
# modify it under the same terms as Ruby.
#
# Author:: Kouhei Sutou <kou@cozmixng.org>
# Tutorial:: http://www.cozmixng.org/~rwiki/?cmd=view;name=RSS+Parser%3A%3ATutorial.en

require 'rss/1.0'
require 'rss/2.0'
require 'rss/atom'
require 'rss/content'
require 'rss/dublincore'
require 'rss/image'
require 'rss/itunes'
require 'rss/slash'
require 'rss/syndication'
require 'rss/taxonomy'
require 'rss/trackback'

require "rss/maker"
PK     Y\xCR  R    scanf.rbnu [        # scanf for Ruby
#
# $Revision: 21682 $
# $Id: scanf.rb 21682 2009-01-20 03:23:46Z shyouhei $
# $Author: shyouhei $
# $Date: 2009-01-20 12:23:46 +0900 (Tue, 20 Jan 2009) $
#
# A product of the Austin Ruby Codefest (Austin, Texas, August 2002)

=begin

=scanf for Ruby

==Description

scanf for Ruby is an implementation of the C function scanf(3),
modified as necessary for Ruby compatibility.

The methods provided are String#scanf, IO#scanf, and
Kernel#scanf. Kernel#scanf is a wrapper around STDIN.scanf.  IO#scanf
can be used on any IO stream, including file handles and sockets.
scanf can be called either with or without a block.

scanf for Ruby scans an input string or stream according to a
<b>format</b>, as described below ("Conversions"), and returns an
array of matches between the format and the input.  The format is
defined in a string, and is similar (though not identical) to the
formats used in Kernel#printf and Kernel#sprintf.

The format may contain <b>conversion specifiers</b>, which tell scanf
what form (type) each particular matched substring should be converted
to (e.g., decimal integer, floating point number, literal string,
etc.)  The matches and conversions take place from left to right, and
the conversions themselves are returned as an array.

The format string may also contain characters other than those in the
conversion specifiers.  White space (blanks, tabs, or newlines) in the
format string matches any amount of white space, including none, in
the input.  Everything else matches only itself.

Scanning stops, and scanf returns, when any input character fails to
match the specifications in the format string, or when input is
exhausted, or when everything in the format string has been
matched. All matches found up to the stopping point are returned in
the return array (or yielded to the block, if a block was given).


==Basic usage

   require 'scanf.rb'

   # String#scanf and IO#scanf take a single argument (a format string)
   array = aString.scanf("%d%s")
   array = anIO.scanf("%d%s")

   # Kernel#scanf reads from STDIN
   array = scanf("%d%s")

==Block usage

When called with a block, scanf keeps scanning the input, cycling back
to the beginning of the format string, and yields a new array of
conversions to the block every time the format string is matched
(including partial matches, but not including complete failures).  The
actual return value of scanf when called with a block is an array
containing the results of all the executions of the block. 

   str = "123 abc 456 def 789 ghi"
   str.scanf("%d%s") { |num,str| [ num * 2, str.upcase ] }
     # => [[246, "ABC"], [912, "DEF"], [1578, "GHI"]]

==Conversions

The single argument to scanf is a format string, which generally
includes one or more conversion specifiers. Conversion specifiers
begin with the percent character ('%') and include information about
what scanf should next scan for (string, decimal number, single
character, etc.).

There may be an optional maximum field width, expressed as a decimal
integer, between the % and the conversion. If no width is given, a
default of `infinity' is used (with the exception of the %c specifier;
see below).  Otherwise, given a field width of <em>n</em> for a given
conversion, at most <em>n</em> characters are scanned in processing
that conversion.  Before conversion begins, most conversions skip
white space in the input string; this white space is not counted
against the field width.

The following conversions are available. (See the files EXAMPLES
and <tt>tests/scanftests.rb</tt> for examples.)

[%]
  Matches a literal `%'. That is, `%%' in the format string matches a
  single input `%' character. No conversion is done, and the resulting
  '%' is not included in the return array.

[d]
  Matches an optionally signed decimal integer.

[u]
  Same as d.

[i] 
  Matches an optionally signed integer. The integer is read in base
  16 if it begins with `0x' or `0X', in base 8 if it begins with `0',
  and in base 10 other- wise. Only characters that correspond to the
  base are recognized.

[o]
  Matches an optionally signed octal integer.

[x,X]
  Matches an optionally signed hexadecimal integer,

[f,g,e,E]
  Matches an optionally signed floating-point number.

[s]
  Matches a sequence of non-white-space character. The input string stops at
  white space or at the maximum field width, whichever occurs first.

[c]
  Matches a single character, or a sequence of <em>n</em> characters if a
  field width of <em>n</em> is specified. The usual skip of leading white
  space is suppressed. To skip white space first, use an explicit space in
  the format.

[<tt>[</tt>]
  Matches a nonempty sequence of characters from the specified set
  of accepted characters.  The usual skip of leading white space is
  suppressed.  This bracketed sub-expression is interpreted exactly like a
  character class in a Ruby regular expression.  (In fact, it is placed as-is
  in a regular expression.)  The matching against the input string ends with
  the appearance of a character not in (or, with a circumflex, in) the set,
  or when the field width runs out, whichever comes first.

===Assignment suppression

To require that a particular match occur, but without including the result
in the return array, place the <b>assignment suppression flag</b>, which is
the star character ('*'), immediately after the leading '%' of a format
specifier (just before the field width, if any).

==Examples

See the files <tt>EXAMPLES</tt> and <tt>tests/scanftests.rb</tt>.

==scanf for Ruby compared with scanf in C

scanf for Ruby is based on the C function scanf(3), but with modifications,
dictated mainly by the underlying differences between the languages.

===Unimplemented flags and specifiers

* The only flag implemented in scanf for Ruby is '<tt>*</tt>' (ignore
  upcoming conversion). Many of the flags available in C versions of scanf(4)
  have to do with the type of upcoming pointer arguments, and are literally
  meaningless in Ruby.

* The <tt>n</tt> specifier (store number of characters consumed so far in
  next pointer) is not implemented.

* The <tt>p</tt> specifier (match a pointer value) is not implemented.

===Altered specifiers

[o,u,x,X]
  In scanf for Ruby, all of these specifiers scan for an optionally signed
  integer, rather than for an unsigned integer like their C counterparts.

===Return values

scanf for Ruby returns an array of successful conversions, whereas
scanf(3) returns the number of conversions successfully
completed. (See below for more details on scanf for Ruby's return
values.)

==Return values

Without a block, scanf returns an array containing all the conversions
it has found. If none are found, scanf will return an empty array. An
unsuccesful match is never ignored, but rather always signals the end
of the scanning operation. If the first unsuccessful match takes place
after one or more successful matches have already taken place, the
returned array will contain the results of those successful matches.

With a block scanf returns a 'map'-like array of transformations from
the block -- that is, an array reflecting what the block did with each
yielded result from the iterative scanf operation.  (See "Block
usage", above.)

==Test suite

scanf for Ruby includes a suite of unit tests (requiring the
<tt>TestUnit</tt> package), which can be run with the command <tt>ruby
tests/scanftests.rb</tt> or the command <tt>make test</tt>.

==Current limitations and bugs

When using IO#scanf under Windows, make sure you open your files in
binary mode:

    File.open("filename", "rb")

so that scanf can keep track of characters correctly.

Support for character classes is reasonably complete (since it
essentially piggy-backs on Ruby's regular expression handling of
character classes), but users are advised that character class testing
has not been exhaustive, and that they should exercise some caution
in using any of the more complex and/or arcane character class
idioms.


==Technical notes

===Rationale behind scanf for Ruby

The impetus for a scanf implementation in Ruby comes chiefly from the fact
that existing pattern matching operations, such as Regexp#match and
String#scan, return all results as strings, which have to be converted to
integers or floats explicitly in cases where what's ultimately wanted are
integer or float values.

===Design of scanf for Ruby

scanf for Ruby is essentially a <format string>-to-<regular
expression> converter.

When scanf is called, a FormatString object is generated from the
format string ("%d%s...") argument. The FormatString object breaks the
format string down into atoms ("%d", "%5f", "blah", etc.), and from
each atom it creates a FormatSpecifier object, which it
saves.

Each FormatSpecifier has a regular expression fragment and a "handler"
associated with it. For example, the regular expression fragment
associated with the format "%d" is "([-+]?\d+)", and the handler
associated with it is a wrapper around String#to_i. scanf itself calls
FormatString#match, passing in the input string. FormatString#match
iterates through its FormatSpecifiers; for each one, it matches the
corresponding regular expression fragment against the string. If
there's a match, it sends the matched string to the handler associated
with the FormatSpecifier.

Thus, to follow up the "%d" example: if "123" occurs in the input
string when a FormatSpecifier consisting of "%d" is reached, the "123"
will be matched against "([-+]?\d+)", and the matched string will be
rendered into an integer by a call to to_i.

The rendered match is then saved to an accumulator array, and the
input string is reduced to the post-match substring. Thus the string
is "eaten" from the left as the FormatSpecifiers are applied in
sequence.  (This is done to a duplicate string; the original string is
not altered.)

As soon as a regular expression fragment fails to match the string, or
when the FormatString object runs out of FormatSpecifiers, scanning
stops and results accumulated so far are returned in an array.

==License and copyright

Copyright:: (c) 2002-2003 David Alan Black
License:: Distributed on the same licensing terms as Ruby itself

==Warranty disclaimer

This software is provided "as is" and without any express or implied
warranties, including, without limitation, the implied warranties of
merchantibility and fitness for a particular purpose.

==Credits and acknowledgements

scanf for Ruby was developed as the major activity of the Austin
Ruby Codefest (Austin, Texas, August 2002).

Principal author:: David Alan Black (mailto:dblack@superlink.net)
Co-author:: Hal Fulton (mailto:hal9000@hypermetrics.com)
Project contributors:: Nolan Darilek, Jason Johnston

Thanks to Hal Fulton for hosting the Codefest.

Thanks to Matz for suggestions about the class design.  

Thanks to Gavin Sinclair for some feedback on the documentation.

The text for parts of this document, especially the Description and
Conversions sections, above, were adapted from the Linux Programmer's
Manual manpage for scanf(3), dated 1995-11-01.

==Bugs and bug reports

scanf for Ruby is based on something of an amalgam of C scanf
implementations and documentation, rather than on a single canonical
description. Suggestions for features and behaviors which appear in
other scanfs, and would be meaningful in Ruby, are welcome, as are
reports of suspicious behaviors and/or bugs. (Please see "Credits and
acknowledgements", above, for email addresses.)

=end

module Scanf

  class FormatSpecifier

    attr_reader :re_string, :matched_string, :conversion, :matched

    private

    def skip;  /^\s*%\*/.match(@spec_string); end

    def extract_float(s); s.to_f if s &&! skip; end
    def extract_decimal(s); s.to_i if s &&! skip; end
    def extract_hex(s); s.hex if s &&! skip; end
    def extract_octal(s); s.oct if s &&! skip; end
    def extract_integer(s); Integer(s) if s &&! skip; end
    def extract_plain(s); s unless skip; end

    def nil_proc(s); nil; end

    public

    def to_s
      @spec_string
    end

    def count_space?
      /(?:\A|\S)%\*?\d*c|\[/.match(@spec_string)
    end

    def initialize(str)
      @spec_string = str
      h = '[A-Fa-f0-9]'

      @re_string, @handler = 
        case @spec_string

          # %[[:...:]]
        when /%\*?(\[\[:[a-z]+:\]\])/
          [ "(#{$1}+)", :extract_plain ]

          # %5[[:...:]]
        when /%\*?(\d+)(\[\[:[a-z]+:\]\])/
          [ "(#{$2}{1,#{$1}})", :extract_plain ]

          # %[...]
        when /%\*?\[([^\]]*)\]/
          yes = $1
          if /^\^/.match(yes) then no = yes[1..-1] else no = '^' + yes end
          [ "([#{yes}]+)(?=[#{no}]|\\z)", :extract_plain ]

          # %5[...]
        when /%\*?(\d+)\[([^\]]*)\]/
          yes = $2
          w = $1
          [ "([#{yes}]{1,#{w}})", :extract_plain ]

          # %i
        when /%\*?i/
          [ "([-+]?(?:(?:0[0-7]+)|(?:0[Xx]#{h}+)|(?:[1-9]\\d*)))", :extract_integer ]

          # %5i
        when /%\*?(\d+)i/
          n = $1.to_i
          s = "("
          if n > 1 then s += "[1-9]\\d{1,#{n-1}}|" end
          if n > 1 then s += "0[0-7]{1,#{n-1}}|" end
          if n > 2 then s += "[-+]0[0-7]{1,#{n-2}}|" end
          if n > 2 then s += "[-+][1-9]\\d{1,#{n-2}}|" end
          if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end
          if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end
          s += "\\d"
          s += ")"
          [ s, :extract_integer ]

          # %d, %u
        when /%\*?[du]/
          [ '([-+]?\d+)', :extract_decimal ]

          # %5d, %5u
        when /%\*?(\d+)[du]/
          n = $1.to_i
          s = "("
          if n > 1 then s += "[-+]\\d{1,#{n-1}}|" end
          s += "\\d{1,#{$1}})"
          [ s, :extract_decimal ]

          # %x
        when /%\*?[Xx]/
          [ "([-+]?(?:0[Xx])?#{h}+)", :extract_hex ]

          # %5x
        when /%\*?(\d+)[Xx]/
          n = $1.to_i
          s = "("
          if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end
          if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end
          if n > 1 then s += "[-+]#{h}{1,#{n-1}}|" end
          s += "#{h}{1,#{n}}"
          s += ")"
          [ s, :extract_hex ]

          # %o
        when /%\*?o/
          [ '([-+]?[0-7]+)', :extract_octal ]

          # %5o
        when /%\*?(\d+)o/
          [ "([-+][0-7]{1,#{$1.to_i-1}}|[0-7]{1,#{$1}})", :extract_octal ]

          # %f
        when /%\*?f/
          [ '([-+]?((\d+(?>(?=[^\d.]|$)))|(\d*(\.(\d*([eE][-+]?\d+)?)))))', :extract_float ]

          # %5f
        when /%\*?(\d+)f/
          [ "(\\S{1,#{$1}})", :extract_float ]

          # %5s
        when /%\*?(\d+)s/
          [ "(\\S{1,#{$1}})", :extract_plain ]

          # %s
        when /%\*?s/
          [ '(\S+)', :extract_plain ]

          # %c
        when /\s%\*?c/
          [ "\\s*(.)", :extract_plain ]

          # %c
        when /%\*?c/
          [ "(.)", :extract_plain ]

          # %5c (whitespace issues are handled by the count_*_space? methods)
        when /%\*?(\d+)c/
          [ "(.{1,#{$1}})", :extract_plain ]

          # %%
        when /%%/
          [ '(\s*%)', :nil_proc ]

          # literal characters
        else
          [ "(#{Regexp.escape(@spec_string)})", :nil_proc ]
        end

      @re_string = '\A' + @re_string
    end

    def to_re
      Regexp.new(@re_string,Regexp::MULTILINE)
    end

    def match(str)
      @matched = false
      s = str.dup
      s.sub!(/\A\s+/,'') unless count_space?
      res = to_re.match(s)
      if res
        @conversion = send(@handler, res[1])
        @matched_string = @conversion.to_s
        @matched = true
      end
      res
    end

    def letter
      /%\*?\d*([a-z\[])/.match(@spec_string).to_a[1]
    end

    def width
      w = /%\*?(\d+)/.match(@spec_string).to_a[1]
      w && w.to_i
    end

    def mid_match?
      return false unless @matched
      cc_no_width    = letter == '[' &&! width
      c_or_cc_width  = (letter == 'c' || letter == '[') && width
      width_left     = c_or_cc_width && (matched_string.size < width)

      return width_left || cc_no_width
    end
    
  end

  class FormatString

    attr_reader :string_left, :last_spec_tried,
                :last_match_tried, :matched_count, :space

    SPECIFIERS = 'diuXxofeEgsc'
    REGEX = /
        # possible space, followed by...
          (?:\s*
          # percent sign, followed by...
            %
            # another percent sign, or...
              (?:%|
        	 # optional assignment suppression flag
        	 \*?
        	 # optional maximum field width
        	 \d*
        	   # named character class, ...
        	   (?:\[\[:\w+:\]\]|
        	   # traditional character class, or...
        	      \[[^\]]*\]|
        	   # specifier letter.
        	      [#{SPECIFIERS}])))|
            # or miscellaneous characters
              [^%\s]+/ix

    def initialize(str)
      @specs = []
      @i = 1
      s = str.to_s
      return unless /\S/.match(s)
      @space = true if /\s\z/.match(s)
      @specs.replace s.scan(REGEX).map {|spec| FormatSpecifier.new(spec) }
    end

    def to_s
      @specs.join('')
    end

    def prune(n=matched_count)
      n.times { @specs.shift }
    end

    def spec_count
      @specs.size
    end

    def last_spec
      @i == spec_count - 1
    end

    def match(str)
      accum = []
      @string_left = str
      @matched_count = 0

      @specs.each_with_index do |spec,@i|
        @last_spec_tried = spec
        @last_match_tried = spec.match(@string_left)
        break unless @last_match_tried
        @matched_count += 1

        accum << spec.conversion

        @string_left = @last_match_tried.post_match
        break if @string_left.empty?
      end
      return accum.compact
    end
  end
end

class IO

# The trick here is doing a match where you grab one *line*
# of input at a time.  The linebreak may or may not occur
# at the boundary where the string matches a format specifier.
# And if it does, some rule about whitespace may or may not
# be in effect...
#
# That's why this is much more elaborate than the string
# version.
#
# For each line:
# Match succeeds (non-emptily)
# and the last attempted spec/string sub-match succeeded:
#
#   could the last spec keep matching?
#     yes: save interim results and continue (next line)
#
# The last attempted spec/string did not match:
#
# are we on the next-to-last spec in the string?
#   yes:
#     is fmt_string.string_left all spaces?
#       yes: does current spec care about input space?
#         yes: fatal failure
#         no: save interim results and continue
#   no: continue  [this state could be analyzed further]
#
#

  def scanf(str,&b)
    return block_scanf(str,&b) if b
    return [] unless str.size > 0

    start_position = pos rescue 0
    matched_so_far = 0
    source_buffer = ""
    result_buffer = []
    final_result = []

    fstr = Scanf::FormatString.new(str)

    loop do
      if eof || (tty? &&! fstr.match(source_buffer))
        final_result.concat(result_buffer)
        break
      end

      source_buffer << gets

      current_match = fstr.match(source_buffer)

      spec = fstr.last_spec_tried

      if spec.matched
        if spec.mid_match?
          result_buffer.replace(current_match)
          next
        end

      elsif (fstr.matched_count == fstr.spec_count - 1)
        if /\A\s*\z/.match(fstr.string_left)
          break if spec.count_space?
          result_buffer.replace(current_match)
          next
        end
      end

      final_result.concat(current_match)

      matched_so_far += source_buffer.size
      source_buffer.replace(fstr.string_left)
      matched_so_far -= source_buffer.size
      break if fstr.last_spec
      fstr.prune
    end
    seek(start_position + matched_so_far, IO::SEEK_SET) rescue Errno::ESPIPE
    soak_up_spaces if fstr.last_spec && fstr.space

    return final_result
  end

  private

  def soak_up_spaces
    c = getc
    ungetc(c) if c
    until eof ||! c || /\S/.match(c.chr)
      c = getc
    end
    ungetc(c) if (c && /\S/.match(c.chr))
  end

  def block_scanf(str)
    final = []
# Sub-ideal, since another FS gets created in scanf.
# But used here to determine the number of specifiers.
    fstr = Scanf::FormatString.new(str)
    last_spec = fstr.last_spec
    begin
      current = scanf(str)
      break if current.empty?
      final.push(yield(current))
    end until eof || fstr.last_spec_tried == last_spec
    return final
  end
end

class String

  def scanf(fstr,&b)
    if b
      block_scanf(fstr,&b)
    else
      fs = 
        if fstr.is_a? Scanf::FormatString
          fstr 
        else 
          Scanf::FormatString.new(fstr)
        end
      fs.match(self)
    end
  end

  def block_scanf(fstr,&b)
    fs = Scanf::FormatString.new(fstr)
    str = self.dup
    final = []
    begin
      current = str.scanf(fs)
      final.push(yield(current)) unless current.empty?
      str = fs.string_left
    end until current.empty? || str.empty?
    return final
  end
end

module Kernel
  private
  def scanf(fs,&b)
    STDIN.scanf(fs,&b)
  end
end
PK     Y\R      yaml/basenode.rbnu [        #
# YAML::BaseNode class
#
require 'yaml/ypath'

module YAML

    #
    # YAML Generic Model container
    #
    module BaseNode

        #
        # Search for YPath entry and return
        # qualified nodes.
        #
        def select( ypath_str )
            matches = match_path( ypath_str )

            #
            # Create a new generic view of the elements selected
            #
            if matches
                result = []
                matches.each { |m|
                    result.push m.last
                }
                YAML.transfer( 'seq', result )
            end
        end

        #
        # Search for YPath entry and return
        # transformed nodes.
        #
        def select!( ypath_str )
            matches = match_path( ypath_str )

            #
            # Create a new generic view of the elements selected
            #
            if matches
                result = []
                matches.each { |m|
                    result.push m.last.transform
                }
                result
            end
        end

        #
        # Search for YPath entry and return a list of
        # qualified paths.
        #
        def search( ypath_str )
            matches = match_path( ypath_str )

            if matches
                matches.collect { |m|
                    path = []
                    m.each_index { |i|
                        path.push m[i] if ( i % 2 ).zero?
                    }
                    "/" + path.compact.join( "/" )
                }
            end
        end

        def at( seg )
            if Hash === @value
                self[seg]
            elsif Array === @value and seg =~ /\A\d+\Z/ and @value[seg.to_i]
                @value[seg.to_i]
            end
        end

        #
        # YPath search returning a complete depth array
        #
        def match_path( ypath_str )
            depth = 0
            matches = []
            YPath.each_path( ypath_str ) do |ypath|
                seg = match_segment( ypath, 0 )
                matches += seg if seg
            end
            matches.uniq
        end

        #
        # Search a node for a single YPath segment
        #
        def match_segment( ypath, depth )
            deep_nodes = []
            seg = ypath.segments[ depth ]
            if seg == "/"
                unless String === @value
                    idx = -1
                    @value.collect { |v|
                        idx += 1
                        if Hash === @value
                            match_init = [v[0].transform, v[1]]
                            match_deep = v[1].match_segment( ypath, depth )
                        else
                            match_init = [idx, v]
                            match_deep = v.match_segment( ypath, depth )
                        end
                        if match_deep
                            match_deep.each { |m|
                                deep_nodes.push( match_init + m )
                            }
                        end
                    }
                end
                depth += 1
                seg = ypath.segments[ depth ]
            end
            match_nodes =
                case seg
                when "."
                    [[nil, self]]
                when ".."
                    [["..", nil]]
                when "*"
                    if @value.is_a? Enumerable
                        idx = -1
                        @value.collect { |h|
                            idx += 1
                            if Hash === @value
                                [h[0].transform, h[1]]
                            else
                                [idx, h]
                            end
                        }
                    end
                else
                    if seg =~ /^"(.*)"$/
                        seg = $1
                    elsif seg =~ /^'(.*)'$/
                        seg = $1
                    end
                    if ( v = at( seg ) )
                        [[ seg, v ]]
                    end
                end
            return deep_nodes unless match_nodes
            pred = ypath.predicates[ depth ]
            if pred
                case pred
                when /^\.=/
                    pred = $'   # '
                    match_nodes.reject! { |n|
                        n.last.value != pred
                    }
                else
                    match_nodes.reject! { |n|
                        n.last.at( pred ).nil?
                    }
                end
            end
            return match_nodes + deep_nodes unless ypath.segments.length > depth + 1

            #puts "DEPTH: #{depth + 1}"
            deep_nodes = []
            match_nodes.each { |n|
                if n[1].is_a? BaseNode
                    match_deep = n[1].match_segment( ypath, depth + 1 )
                    if match_deep
                        match_deep.each { |m|
                            deep_nodes.push( n + m )
                        }
                    end
                else
                    deep_nodes = []
                end
            }
            deep_nodes = nil if deep_nodes.length == 0
            deep_nodes
        end

        #
        # We want the node to act like as Hash
        # if it is.
        #
        def []( *key )
            if Hash === @value
                v = @value.detect { |k,| k.transform == key.first }
                v[1] if v
            elsif Array === @value
                @value.[]( *key )
            end
        end

        def children
            if Hash === @value
                @value.values.collect { |c| c[1] }
            elsif Array === @value
                @value
            end
        end

        def children_with_index
            if Hash === @value
                @value.keys.collect { |i| [self[i], i] }
            elsif Array === @value
                i = -1; @value.collect { |v| i += 1; [v, i] }
            end
        end

        def emit
            transform.to_yaml
        end
    end

end

PK     Y\3v      yaml/stream.rbnu [        module YAML

	#
	# YAML::Stream -- for emitting many documents
	#
	class Stream

		attr_accessor :documents, :options

		def initialize( opts = {} )
			@options = opts
			@documents = []
		end
		
        def []( i )
            @documents[ i ]
        end

		def add( doc )
			@documents << doc
		end

		def edit( doc_num, doc )
			@documents[ doc_num ] = doc
		end

		def emit( io = nil )
            # opts = @options.dup
			# opts[:UseHeader] = true if @documents.length > 1
            out = YAML.emitter
            out.reset( io || io2 = StringIO.new )
            @documents.each { |v|
                v.to_yaml( out )
            }
            io || ( io2.rewind; io2.read )
		end

	end

end
PK     Y\      yaml/syck.rbnu [        #
# YAML::Syck module
# .. glues syck and yaml.rb together ..
#
require 'syck'
require 'yaml/basenode'

module YAML
    module Syck

        #
        # Mixin BaseNode functionality
        #
        class Node
            include YAML::BaseNode
        end

    end
end
PK     Y\]      yaml/constants.rbnu [        #
# Constants used throughout the library
#
module YAML

	#
	# Constants
	#
	VERSION = '0.60'
	SUPPORTED_YAML_VERSIONS = ['1.0']

	#
	# Parser tokens
	#
	WORD_CHAR = 'A-Za-z0-9'
	PRINTABLE_CHAR = '-_A-Za-z0-9!?/()$\'". ' 
	NOT_PLAIN_CHAR = '\x7f\x0-\x1f\x80-\x9f'
	ESCAPE_CHAR = '[\\x00-\\x09\\x0b-\\x1f]'
	INDICATOR_CHAR = '*&!|\\\\^@%{}[]='
	SPACE_INDICATORS = '-#:,?'
	RESTRICTED_INDICATORS = '#:,}]'
	DNS_COMP_RE = "\\w(?:[-\\w]*\\w)?"
	DNS_NAME_RE = "(?:(?:#{DNS_COMP_RE}\\.)+#{DNS_COMP_RE}|#{DNS_COMP_RE})"
	ESCAPES = %w{\x00   \x01	\x02	\x03	\x04	\x05	\x06	\a
			     \x08	\t		\n		\v		\f		\r		\x0e	\x0f
				 \x10	\x11	\x12	\x13	\x14	\x15	\x16	\x17
				 \x18	\x19	\x1a	\e		\x1c	\x1d	\x1e	\x1f
			    }
	UNESCAPES = {
				'a' => "\x07", 'b' => "\x08", 't' => "\x09", 
				'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c",
				'r' => "\x0d", 'e' => "\x1b", '\\' => '\\',
			    }

	#
	# Default settings
	#
	DEFAULTS = {
		:Indent => 2, :UseHeader => false, :UseVersion => false, :Version => '1.0',
		:SortKeys => false, :AnchorFormat => 'id%03d', :ExplicitTypes => false,
		:WidthType => 'absolute', :BestWidth => 80,
		:UseBlock => false, :UseFold => false, :Encoding => :None
	}

end
PK     Y\7O  O    yaml/tag.rbnu [        # -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
# $Id: tag.rb 16084 2008-04-19 11:45:39Z knu $
#
# = yaml/tag.rb: methods for associating a taguri to a class.
#
# Author:: why the lucky stiff
# 
module YAML
    # A dictionary of taguris which map to
    # Ruby classes.
    @@tagged_classes = {}
    
    # 
    # Associates a taguri _tag_ with a Ruby class _cls_.  The taguri is used to give types
    # to classes when loading YAML.  Taguris are of the form:
    #
    #   tag:authorityName,date:specific
    #
    # The +authorityName+ is a domain name or email address.  The +date+ is the date the type
    # was issued in YYYY or YYYY-MM or YYYY-MM-DD format.  The +specific+ is a name for
    # the type being added.
    # 
    # For example, built-in YAML types have 'yaml.org' as the +authorityName+ and '2002' as the
    # +date+.  The +specific+ is simply the name of the type:
    #
    #  tag:yaml.org,2002:int
    #  tag:yaml.org,2002:float
    #  tag:yaml.org,2002:timestamp
    #
    # The domain must be owned by you on the +date+ declared.  If you don't own any domains on the
    # date you declare the type, you can simply use an e-mail address.
    #
    #  tag:why@ruby-lang.org,2004:notes/personal
    #
    def YAML.tag_class( tag, cls )
        if @@tagged_classes.has_key? tag
            warn "class #{ @@tagged_classes[tag] } held ownership of the #{ tag } tag"
        end
        @@tagged_classes[tag] = cls
    end

    # Returns the complete dictionary of taguris, paired with classes.  The key for
    # the dictionary is the full taguri.  The value for each key is the class constant
    # associated to that taguri.
    #
    #  YAML.tagged_classes["tag:yaml.org,2002:int"] => Integer
    #
    def YAML.tagged_classes
        @@tagged_classes
    end
end

class Module
    # :stopdoc:

    # Adds a taguri _tag_ to a class, used when dumping or loading the class
    # in YAML.  See YAML::tag_class for detailed information on typing and
    # taguris.
    def yaml_as( tag, sc = true )
        verbose, $VERBOSE = $VERBOSE, nil
        class_eval <<-"end;", __FILE__, __LINE__+1
            attr_writer :taguri
            def taguri
                if respond_to? :to_yaml_type
                    YAML::tagurize( to_yaml_type[1..-1] )
                else
                    return @taguri if defined?(@taguri) and @taguri
                    tag = #{ tag.dump }
                    if self.class.yaml_tag_subclasses? and self.class != YAML::tagged_classes[tag]
                        tag = "\#{ tag }:\#{ self.class.yaml_tag_class_name }"
                    end
                    tag
                end
            end
            def self.yaml_tag_subclasses?; #{ sc ? 'true' : 'false' }; end
        end;
        YAML::tag_class tag, self
    ensure
        $VERBOSE = verbose
    end
    # Transforms the subclass name into a name suitable for display
    # in a subclassed tag.
    def yaml_tag_class_name
        self.name
    end
    # Transforms the subclass name found in the tag into a Ruby
    # constant name.
    def yaml_tag_read_class( name )
        name
    end
end
PK     Y\k"u(  (    yaml/loader.rbnu [        #
# YAML::Loader class
# .. type handling ..
#
module YAML
    class Loader
        TRANSFER_DOMAINS = {
            'yaml.org,2002' => {},
            'ruby.yaml.org,2002' => {}
        }
        PRIVATE_TYPES = {}
        IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ]
    end
end
PK     Y\b\1      yaml/types.rbnu [        # -*- mode: ruby; ruby-indent-level: 4 -*- vim: sw=4
#
# Classes required by the full core typeset
#

module YAML

    #
    # Default private type
    #
    class PrivateType
        def self.tag_subclasses?; false; end
        verbose, $VERBOSE = $VERBOSE, nil
        def initialize( type, val )
            @type_id = type; @value = val
            @value.taguri = "x-private:#{ @type_id }"
        end
        def to_yaml( opts = {} )
            @value.to_yaml( opts )
        end
    ensure
        $VERBOSE = verbose
    end

    #
    # Default domain type
    #
    class DomainType
        def self.tag_subclasses?; false; end
        verbose, $VERBOSE = $VERBOSE, nil
        def initialize( domain, type, val )
            @domain = domain; @type_id = type; @value = val
            @value.taguri = "tag:#{ @domain }:#{ @type_id }"
        end
        def to_yaml( opts = {} )
            @value.to_yaml( opts )
        end
    ensure
        $VERBOSE = verbose
    end

    #
    # Unresolved objects
    #
    class Object
        def self.tag_subclasses?; false; end
        def to_yaml( opts = {} )
            YAML::quick_emit( self, opts ) do |out|
                out.map( "tag:ruby.yaml.org,2002:object:#{ @class }", to_yaml_style ) do |map|
                    @ivars.each do |k,v|
                        map.add( k, v )
                    end
                end
            end
        end
    end

    #
    # YAML Hash class to support comments and defaults
    #
    class SpecialHash < ::Hash 
        attr_accessor :default
        def inspect
            self.default.to_s
        end
        def to_s
            self.default.to_s
        end
        def update( h )
            if YAML::SpecialHash === h
                @default = h.default if h.default
            end
            super( h )
        end
        def to_yaml( opts = {} )
            opts[:DefaultKey] = self.default
            super( opts )
        end
    end

    #
    # Builtin collection: !omap
    #
    class Omap < ::Array
        yaml_as "tag:yaml.org,2002:omap"
        def yaml_initialize( tag, val )
            if Array === val
                val.each do |v|
                    if Hash === v
                        concat( v.to_a )		# Convert the map to a sequence
                    else
                        raise YAML::Error, "Invalid !omap entry: " + val.inspect
                    end
                end
            else
                raise YAML::Error, "Invalid !omap: " + val.inspect
            end
            self
        end
        def self.[]( *vals )
            o = Omap.new
            0.step( vals.length - 1, 2 ) do |i|
                o[vals[i]] = vals[i+1]
            end
            o
        end
        def []( k )
            self.assoc( k ).to_a[1]
        end
        def []=( k, *rest )
            val, set = rest.reverse
            if ( tmp = self.assoc( k ) ) and not set
                tmp[1] = val
            else
                self << [ k, val ] 
            end
            val
        end
        def has_key?( k )
            self.assoc( k ) ? true : false
        end
        def is_complex_yaml?
            true
        end
        def to_yaml( opts = {} )
            YAML::quick_emit( self, opts ) do |out|
                out.seq( taguri, to_yaml_style ) do |seq|
                    self.each do |v|
                        seq.add( Hash[ *v ] )
                    end
                end
            end
        end
    end

    #
    # Builtin collection: !pairs
    #
    class Pairs < ::Array
        yaml_as "tag:yaml.org,2002:pairs"
        def yaml_initialize( tag, val )
            if Array === val
                val.each do |v|
                    if Hash === v
                        concat( v.to_a )		# Convert the map to a sequence
                    else
                        raise YAML::Error, "Invalid !pairs entry: " + val.inspect
                    end
                end
            else
                raise YAML::Error, "Invalid !pairs: " + val.inspect
            end
            self
        end
        def self.[]( *vals )
            p = Pairs.new
            0.step( vals.length - 1, 2 ) { |i|
                p[vals[i]] = vals[i+1]
            }
            p
        end
        def []( k )
            self.assoc( k ).to_a
        end
        def []=( k, val )
            self << [ k, val ] 
            val
        end
        def has_key?( k )
            self.assoc( k ) ? true : false
        end
        def is_complex_yaml?
            true
        end
        def to_yaml( opts = {} )
            YAML::quick_emit( self, opts ) do |out|
                out.seq( taguri, to_yaml_style ) do |seq|
                    self.each do |v|
                        seq.add( Hash[ *v ] )
                    end
                end
            end
        end
    end

    #
    # Builtin collection: !set
    #
    class Set < ::Hash
        yaml_as "tag:yaml.org,2002:set"
    end
end
PK     Y\C0  0    yaml/ypath.rbnu [        #
# YAML::YPath
#

module YAML

    class YPath
        attr_accessor :segments, :predicates, :flags
        def initialize( str )
            @segments = []
            @predicates = []
            @flags = nil
            while str =~ /^\/?(\/|[^\/\[]+)(?:\[([^\]]+)\])?/
                @segments.push $1
                @predicates.push $2
                str = $'
            end
            unless str.to_s.empty?
                @segments += str.split( "/" )
            end
            if @segments.length == 0
                @segments.push "."
            end
        end
        def YPath.each_path( str )
            #
            # Find choices
            #
            paths = []
            str = "(#{ str })"
            while str.sub!( /\(([^()]+)\)/, "\n#{ paths.length }\n" )
                paths.push $1.split( '|' )
            end

            #
            # Construct all possible paths
            #
            all = [ str ]
            ( paths.length - 1 ).downto( 0 ) do |i|
                all = all.collect do |a|
                    paths[i].collect do |p|
                        a.gsub( /\n#{ i }\n/, p )
                    end
                end.flatten.uniq
            end
            all.collect do |path|
                yield YPath.new( path )
            end
        end
    end

end
PK     Y\Uy  y    yaml/baseemitter.rbnu [        #
# BaseEmitter
#

require 'yaml/constants'
require 'yaml/encoding'
require 'yaml/error'

module YAML

    module BaseEmitter

        def options( opt = nil )
            if opt
                @options[opt] || YAML::DEFAULTS[opt]
            else
                @options
            end
        end

        def options=( opt )
            @options = opt
        end

        #
        # Emit binary data
        #
        def binary_base64( value )
            self << "!binary "
            self.node_text( [value].pack("m"), '|' )
        end

		#
		# Emit plain, normal flowing text
		#
		def node_text( value, block = nil )
            @seq_map = false
			valx = value.dup
            unless block
            block =
                if options(:UseBlock)
                    '|'
                elsif not options(:UseFold) and valx =~ /\n[ \t]/ and not valx =~ /#{YAML::ESCAPE_CHAR}/
                    '|'
                else
                    '>'
                end 

                indt = $&.to_i if block =~ /\d+/
                if valx =~ /(\A\n*[ \t#]|^---\s+)/
                    indt = options(:Indent) unless indt.to_i > 0
                    block += indt.to_s
                end

            block +=
                if valx =~ /\n\Z\n/
                    "+"
                elsif valx =~ /\Z\n/
                    ""
                else
                    "-"
                end
            end
            block += "\n"
            if block[0] == ?"
                esc_skip = ( "\t\n" unless valx =~ /^[ \t]/ ) || ""
                valx = fold( YAML::escape( valx, esc_skip ) + "\"" ).chomp
                self << '"' + indent_text( valx, indt, false )
            else
                if block[0] == ?> 
                    valx = fold( valx ) 
                end
                #p [block, indt]
                self << block + indent_text( valx, indt )
            end
		end

		#
		# Emit a simple, unqouted string
		#
		def simple( value )
            @seq_map = false
            self << value.to_s
		end

		#
		# Emit double-quoted string
		#
		def double( value )
			"\"#{YAML.escape( value )}\"" 
		end

		#
		# Emit single-quoted string
		#
		def single( value )
			"'#{value}'"
		end

		#
		# Write a text block with the current indent
		#
		def indent_text( text, mod, first_line = true )
			return "" if text.to_s.empty?
            spacing = indent( mod )
            text = text.gsub( /\A([^\n])/, "#{ spacing }\\1" ) if first_line
			return text.gsub( /\n^([^\n])/, "\n#{spacing}\\1" )
		end

		#
		# Write a current indent
		#
        def indent( mod = nil )
            #p [ self.id, level, mod, :INDENT ]
            if level <= 0
                mod ||= 0
            else
                mod ||= options(:Indent)
                mod += ( level - 1 ) * options(:Indent)
            end
            return " " * mod
		end

		#
		# Add indent to the buffer
		#
		def indent!
			self << indent
		end

		#
		# Folding paragraphs within a column
		#
		def fold( value )
            value.gsub( /(^[ \t]+.*$)|(\S.{0,#{options(:BestWidth) - 1}})(?:[ \t]+|(\n+(?=[ \t]|\Z))|$)/ ) do
                $1 || $2 + ( $3 || "\n" )
            end
		end

        #
        # Quick mapping
        #
        def map( type, &e )
            val = Mapping.new
            e.call( val )
			self << "#{type} " if type.length.nonzero?

			#
			# Empty hashes
			#
			if val.length.zero?
				self << "{}"
                @seq_map = false
			else
                # FIXME
                # if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero? 
			    #     @headless = 1 
                # end

                defkey = @options.delete( :DefaultKey )
                if defkey
                    seq_map_shortcut
                    self << "= : "
                    defkey.to_yaml( :Emitter => self )
                end

				#
				# Emit the key and value
				#
                val.each { |v|
                    seq_map_shortcut
                    if v[0].is_complex_yaml?
                        self << "? "
                    end
                    v[0].to_yaml( :Emitter => self )
                    if v[0].is_complex_yaml?
                        self << "\n"
                        indent!
                    end
                    self << ": " 
                    v[1].to_yaml( :Emitter => self )
                }
			end
        end

        def seq_map_shortcut
            # FIXME: seq_map needs to work with the new anchoring system
            # if @seq_map
            #     @anchor_extras[@buffer.length - 1] = "\n" + indent
            #     @seq_map = false
            # else
                self << "\n"
                indent! 
            # end
        end

        #
        # Quick sequence
        #
        def seq( type, &e )
            @seq_map = false
            val = Sequence.new
            e.call( val )
			self << "#{type} " if type.length.nonzero?

			#
			# Empty arrays
			#
			if val.length.zero?
				self << "[]"
			else
                # FIXME
                # if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero? 
			    #     @headless = 1 
                # end

				#
				# Emit the key and value
				#
                val.each { |v|
                    self << "\n"
                    indent!
                    self << "- "
                    @seq_map = true if v.class == Hash
                    v.to_yaml( :Emitter => self )
                }
			end
        end

    end

    #
    # Emitter helper classes
    #
    class Mapping < Array
        def add( k, v )
            push [k, v]
        end
    end

    class Sequence < Array
        def add( v )
            push v
        end
    end

end
PK     Y\׏      yaml/stringio.rbnu [        #
# Limited StringIO if no core lib is available
#
begin
require 'stringio'
rescue LoadError
    # StringIO based on code by MoonWolf
    class StringIO
        def initialize(string="")
            @string=string
            @pos=0
            @eof=(string.size==0)
        end
        def pos
            @pos
        end    
        def eof
            @eof
        end
        alias eof? eof
        def readline(rs=$/)
            if @eof
                raise EOFError
            else
                if p = @string[@pos..-1]=~rs
                    line = @string[@pos,p+1]
                else
                    line = @string[@pos..-1]
                end
                @pos+=line.size
                @eof =true if @pos==@string.size
                $_ = line
            end
        end
        def rewind
            seek(0,0)
        end
        def seek(offset,whence)
            case whence
            when 0
                @pos=offset
            when 1
                @pos+=offset
            when 2
                @pos=@string.size+offset
            end
            @eof=(@pos>=@string.size)
            0
        end
    end

	#
	# Class method for creating streams
	#
	def YAML.make_stream( io )
        if String === io
            io = StringIO.new( io )
        elsif not IO === io
            raise YAML::Error, "YAML stream must be an IO or String object."
        end
        if YAML::unicode
            def io.readline
                YAML.utf_to_internal( readline( @ln_sep ), @utf_encoding )
            end
            def io.check_unicode
                @utf_encoding = YAML.sniff_encoding( read( 4 ) )
                @ln_sep = YAML.enc_separator( @utf_encoding )
                seek( -4, IO::SEEK_CUR )
            end
		    def io.utf_encoding
		    	@utf_encoding
		    end
            io.check_unicode
        else
            def io.utf_encoding
                :None
            end
        end
        io
	end

end

PK     Y\uo]  ]    yaml/encoding.rbnu [        #
# Handle Unicode-to-Internal conversion
#

module YAML

	#
	# Escape the string, condensing common escapes
	#
	def YAML.escape( value, skip = "" )
		value.gsub( /\\/, "\\\\\\" ).
              gsub( /"/, "\\\"" ).
              gsub( /([\x00-\x1f])/ ) do
                 skip[$&] || ESCAPES[ $&.unpack("C")[0] ]
             end
	end

	#
	# Unescape the condenses escapes
	#
	def YAML.unescape( value )
		value.gsub( /\\(?:([nevfbart\\])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) {
			if $3
				["#$3".hex ].pack('U*')
			elsif $2
				[$2].pack( "H2" ) 
			else
				UNESCAPES[$1] 
			end
		}
	end

end
PK     Y\!      yaml/store.rbnu [        #
# YAML::Store
#
require 'yaml'
require 'pstore'

class YAML::Store < PStore
  def initialize( *o )
    @opt = YAML::DEFAULTS.dup
    if String === o.first
      super(o.shift)
    end
    if o.last.is_a? Hash
      @opt.update(o.pop)
    end
  end

  def dump(table)
    @table.to_yaml(@opt)
  end

  def load(content)
    table = YAML::load(content)
    if table == false
      {}
    else
      table
    end
  end

  def marshal_dump_supports_canonical_option?
    false
  end

  EMPTY_MARSHAL_DATA = {}.to_yaml
  EMPTY_MARSHAL_CHECKSUM = Digest::MD5.digest(EMPTY_MARSHAL_DATA)
  def empty_marshal_data
    EMPTY_MARSHAL_DATA
  end
  def empty_marshal_checksum
    EMPTY_MARSHAL_CHECKSUM
  end
end
PK     Y\t      yaml/yamlnode.rbnu [        #
# YAML::YamlNode class
#
require 'yaml/basenode'

module YAML

    #
    # YAML Generic Model container
    #
    class YamlNode
        include BaseNode
        attr_accessor :kind, :type_id, :value, :anchor
        def initialize( t, v )
            @type_id = t
            if Hash === v
                @kind = 'map'
                @value = {}
                v.each { |k,v|
                    @value[ k.transform ] = [ k, v ]
                }
            elsif Array === v
                @kind = 'seq'
                @value = v
            elsif String === v
                @kind = 'scalar'
                @value = v
            end
        end

        #
        # Transform this node fully into a native type
        #
        def transform
            t = nil
            if @value.is_a? Hash
                t = {}
                @value.each { |k,v|
                    t[ k ] = v[1].transform
                }
            elsif @value.is_a? Array
                t = []
                @value.each { |v|
                    t.push v.transform
                }
            else
                t = @value
            end
            YAML.transfer_method( @type_id, t )
        end

    end

end
PK     Y\g\2  2    yaml/rubytypes.rbnu [        # -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
require 'date'

class Class
	def to_yaml( opts = {} )
		raise TypeError, "can't dump anonymous class %s" % self.class
	end
end

class Object
    yaml_as "tag:ruby.yaml.org,2002:object"
    def to_yaml_style; end
    def to_yaml_properties; instance_variables.sort; end
	def to_yaml( opts = {} )
		YAML::quick_emit( self, opts ) do |out|
            out.map( taguri, to_yaml_style ) do |map|
				to_yaml_properties.each do |m|
                    map.add( m[1..-1], instance_variable_get( m ) )
                end
            end
        end
	end
end

class Hash
    yaml_as "tag:ruby.yaml.org,2002:hash"
    yaml_as "tag:yaml.org,2002:map"
    def yaml_initialize( tag, val )
        if Array === val
            update Hash.[]( *val )		# Convert the map to a sequence
        elsif Hash === val
            update val
        else
            raise YAML::TypeError, "Invalid map explicitly tagged #{ tag }: " + val.inspect
        end
    end
	def to_yaml( opts = {} )
		YAML::quick_emit( self, opts ) do |out|
            out.map( taguri, to_yaml_style ) do |map|
                each do |k, v|
                    map.add( k, v )
                end
            end
        end
	end
end

class Struct
    yaml_as "tag:ruby.yaml.org,2002:struct"
    def self.yaml_tag_class_name; self.name.gsub( "Struct::", "" ); end
    def self.yaml_tag_read_class( name ); "Struct::#{ name }"; end
    def self.yaml_new( klass, tag, val )
        if Hash === val
            struct_type = nil

            #
            # Use existing Struct if it exists
            #
            props = {}
            val.delete_if { |k,v| props[k] = v if k =~ /^@/ }
            begin
                struct_name, struct_type = YAML.read_type_class( tag, Struct )
            rescue NameError
            end
            if not struct_type
                struct_def = [ tag.split( ':', 4 ).last ]
                struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) ) 
            end

            #
            # Set the Struct properties
            #
            st = YAML::object_maker( struct_type, {} )
            st.members.each do |m|
                st.send( "#{m}=", val[m] )
            end
            props.each do |k,v|
                st.instance_variable_set(k, v)
            end
            st
        else
            raise YAML::TypeError, "Invalid Ruby Struct: " + val.inspect
        end
    end
	def to_yaml( opts = {} )
		YAML::quick_emit( self, opts ) do |out|
			#
			# Basic struct is passed as a YAML map
			#
            out.map( taguri, to_yaml_style ) do |map|
				self.members.each do |m|
                    map.add( m, self[m] )
                end
				self.to_yaml_properties.each do |m|
                    map.add( m, instance_variable_get( m ) )
                end
            end
        end
	end
end

class Array
    yaml_as "tag:ruby.yaml.org,2002:array"
    yaml_as "tag:yaml.org,2002:seq"
    def yaml_initialize( tag, val ); concat( val.to_a ); end
	def to_yaml( opts = {} )
		YAML::quick_emit( self, opts ) do |out|
            out.seq( taguri, to_yaml_style ) do |seq|
                each do |x|
                    seq.add( x )
                end
            end
        end
	end
end

class Exception
    yaml_as "tag:ruby.yaml.org,2002:exception"
    def Exception.yaml_new( klass, tag, val )
        o = YAML.object_maker( klass, { 'mesg' => val.delete( 'message' ) } )
        val.each_pair do |k,v|
            o.instance_variable_set("@#{k}", v)
        end
        o
    end
	def to_yaml( opts = {} )
		YAML::quick_emit( self, opts ) do |out|
            out.map( taguri, to_yaml_style ) do |map|
                map.add( 'message', message )
				to_yaml_properties.each do |m|
                    map.add( m[1..-1], instance_variable_get( m ) )
                end
            end
        end
	end
end

class String
    yaml_as "tag:ruby.yaml.org,2002:string"
    yaml_as "tag:yaml.org,2002:binary"
    yaml_as "tag:yaml.org,2002:str"
    def is_complex_yaml?
        to_yaml_style or not to_yaml_properties.empty? or self =~ /\n.+/
    end
    def is_binary_data?
        ( self.count( "^ -~", "^\r\n" ).fdiv(self.size) > 0.3 || self.index( "\x00" ) ) unless empty?
    end
    def String.yaml_new( klass, tag, val )
        val = val.unpack("m")[0] if tag == "tag:yaml.org,2002:binary"
        val = { 'str' => val } if String === val
        if Hash === val
            s = klass.allocate
            # Thank you, NaHi
            String.instance_method(:initialize).
                  bind(s).
                  call( val.delete( 'str' ) )
            val.each { |k,v| s.instance_variable_set( k, v ) }
            s
        else
            raise YAML::TypeError, "Invalid String: " + val.inspect
        end
    end
	def to_yaml( opts = {} )
		YAML::quick_emit( is_complex_yaml? ? self : nil, opts ) do |out|
            if is_binary_data?
                out.scalar( "tag:yaml.org,2002:binary", [self].pack("m"), :literal )
            elsif to_yaml_properties.empty?
                out.scalar( taguri, self, self =~ /^:/ ? :quote2 : to_yaml_style )
            else
                out.map( taguri, to_yaml_style ) do |map|
                    map.add( 'str', "#{self}" )
                    to_yaml_properties.each do |m|
                        map.add( m, instance_variable_get( m ) )
                    end
                end
            end
        end
	end
end

class Symbol
    yaml_as "tag:ruby.yaml.org,2002:symbol"
    yaml_as "tag:ruby.yaml.org,2002:sym"
    def Symbol.yaml_new( klass, tag, val )
        if String === val
            val = YAML::load( val ) if val =~ /\A(["']).*\1\z/
            val.intern
        else
            raise YAML::TypeError, "Invalid Symbol: " + val.inspect
        end
    end
	def to_yaml( opts = {} )
		YAML::quick_emit( nil, opts ) do |out|
            out.scalar( "tag:yaml.org,2002:str", self.inspect, :plain )
        end
	end
end

class Range
    yaml_as "tag:ruby.yaml.org,2002:range"
    def Range.yaml_new( klass, tag, val )
        inr = %r'(\w+|[+-]?\d+(?:\.\d+)?(?:e[+-]\d+)?|"(?:[^\\"]|\\.)*")'
        opts = {}
        if String === val and val =~ /^#{inr}(\.{2,3})#{inr}$/o
            r1, rdots, r2 = $1, $2, $3
            opts = {
                'begin' => YAML.load( "--- #{r1}" ),
                'end' => YAML.load( "--- #{r2}" ),
                'excl' => rdots.length == 3
            }
            val = {}
        elsif Hash === val
            opts['begin'] = val.delete('begin')
            opts['end'] = val.delete('end')
            opts['excl'] = val.delete('excl')
        end
        if Hash === opts
            r = YAML::object_maker( klass, {} )
            # Thank you, NaHi
            Range.instance_method(:initialize).
                  bind(r).
                  call( opts['begin'], opts['end'], opts['excl'] )
            val.each { |k,v| r.instance_variable_set( k, v ) }
            r
        else
            raise YAML::TypeError, "Invalid Range: " + val.inspect
        end
    end
	def to_yaml( opts = {} )
		YAML::quick_emit( self, opts ) do |out|
            # if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or
            #   self.end.is_complex_yaml? or self.end.respond_to? :to_str or
            #   not to_yaml_properties.empty?
                out.map( taguri, to_yaml_style ) do |map|
                    map.add( 'begin', self.begin )
                    map.add( 'end', self.end )
                    map.add( 'excl', self.exclude_end? )
                    to_yaml_properties.each do |m|
                        map.add( m, instance_variable_get( m ) )
                    end
                end
            # else
            #     out.scalar( taguri ) do |sc|
            #         sc.embed( self.begin )
            #         sc.concat( self.exclude_end? ? "..." : ".." )
            #         sc.embed( self.end )
            #     end
            # end
        end
	end
end

class Regexp
    yaml_as "tag:ruby.yaml.org,2002:regexp"
    def Regexp.yaml_new( klass, tag, val )
        if String === val and val =~ /^\/(.*)\/([mix]*)$/
            val = { 'regexp' => $1, 'mods' => $2 }
        end
        if Hash === val
            mods = nil
            unless val['mods'].to_s.empty?
                mods = 0x00
                mods |= Regexp::EXTENDED if val['mods'].include?( 'x' )
                mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' )
                mods |= Regexp::MULTILINE if val['mods'].include?( 'm' )
            end
            val.delete( 'mods' )
            r = YAML::object_maker( klass, {} )
            Regexp.instance_method(:initialize).
                  bind(r).
                  call( val.delete( 'regexp' ), mods )
            val.each { |k,v| r.instance_variable_set( k, v ) }
            r
        else
            raise YAML::TypeError, "Invalid Regular expression: " + val.inspect
        end
    end
	def to_yaml( opts = {} )
		YAML::quick_emit( nil, opts ) do |out|
            if to_yaml_properties.empty?
                out.scalar( taguri, self.inspect, :plain )
            else
                out.map( taguri, to_yaml_style ) do |map|
                    src = self.inspect
                    if src =~ /\A\/(.*)\/([a-z]*)\Z/
                        map.add( 'regexp', $1 )
                        map.add( 'mods', $2 )
                    else
		                raise YAML::TypeError, "Invalid Regular expression: " + src
                    end
                    to_yaml_properties.each do |m|
                        map.add( m, instance_variable_get( m ) )
                    end
                end
            end
        end
	end
end

class Time
    yaml_as "tag:ruby.yaml.org,2002:time"
    yaml_as "tag:yaml.org,2002:timestamp"
    def Time.yaml_new( klass, tag, val )
        if Hash === val
            t = val.delete( 'at' )
            val.each { |k,v| t.instance_variable_set( k, v ) }
            t
        else
            raise YAML::TypeError, "Invalid Time: " + val.inspect
        end
    end
	def to_yaml( opts = {} )
		YAML::quick_emit( self, opts ) do |out|
            tz = "Z"
            # from the tidy Tobias Peters <t-peters@gmx.de> Thanks!
            unless self.utc?
                utc_same_instant = self.dup.utc
                utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)
                difference_to_utc = utc_same_writing - utc_same_instant
                if (difference_to_utc < 0) 
                    difference_sign = '-'
                    absolute_difference = -difference_to_utc
                else
                    difference_sign = '+'
                    absolute_difference = difference_to_utc
                end
                difference_minutes = (absolute_difference/60).round
                tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
            end
            standard = self.strftime( "%Y-%m-%d %H:%M:%S" )
            standard += ".%06d" % [usec] if usec.nonzero?
            standard += " %s" % [tz]
            if to_yaml_properties.empty?
                out.scalar( taguri, standard, :plain )
            else
                out.map( taguri, to_yaml_style ) do |map|
                    map.add( 'at', standard )
                    to_yaml_properties.each do |m|
                        map.add( m, instance_variable_get( m ) )
                    end
                end
            end
        end
	end
end

class Date
    yaml_as "tag:yaml.org,2002:timestamp#ymd"
	def to_yaml( opts = {} )
		YAML::quick_emit( self, opts ) do |out|
            out.scalar( "tag:yaml.org,2002:timestamp", self.to_s, :plain )
        end
	end
end

class Integer
    yaml_as "tag:yaml.org,2002:int"
	def to_yaml( opts = {} )
		YAML::quick_emit( nil, opts ) do |out|
            out.scalar( "tag:yaml.org,2002:int", self.to_s, :plain )
        end
	end
end

class Float
    yaml_as "tag:yaml.org,2002:float"
	def to_yaml( opts = {} )
		YAML::quick_emit( nil, opts ) do |out|
            str = self.to_s
            if str == "Infinity"
                str = ".Inf"
            elsif str == "-Infinity"
                str = "-.Inf"
            elsif str == "NaN"
                str = ".NaN"
            end
            out.scalar( "tag:yaml.org,2002:float", str, :plain )
        end
	end
end

class TrueClass
    yaml_as "tag:yaml.org,2002:bool#yes"
	def to_yaml( opts = {} )
		YAML::quick_emit( nil, opts ) do |out|
            out.scalar( taguri, "true", :plain )
        end
	end
end

class FalseClass
    yaml_as "tag:yaml.org,2002:bool#no"
	def to_yaml( opts = {} )
		YAML::quick_emit( nil, opts ) do |out|
            out.scalar( taguri, "false", :plain )
        end
	end
end

class NilClass 
    yaml_as "tag:yaml.org,2002:null"
	def to_yaml( opts = {} )
		YAML::quick_emit( nil, opts ) do |out|
            out.scalar( taguri, "", :plain )
        end
	end
end

PK     Y\;N-  -    yaml/error.rbnu [        #
# Error messages and exception class
#

module YAML

	#
	# Error messages
	#

	ERROR_NO_HEADER_NODE = "With UseHeader=false, the node Array or Hash must have elements"
	ERROR_NEED_HEADER = "With UseHeader=false, the node must be an Array or Hash"
	ERROR_BAD_EXPLICIT = "Unsupported explicit transfer: '%s'"
    ERROR_MANY_EXPLICIT = "More than one explicit transfer"
	ERROR_MANY_IMPLICIT = "More than one implicit request"
	ERROR_NO_ANCHOR = "No anchor for alias '%s'"
	ERROR_BAD_ANCHOR = "Invalid anchor: %s"
	ERROR_MANY_ANCHOR = "More than one anchor"
	ERROR_ANCHOR_ALIAS = "Can't define both an anchor and an alias"
	ERROR_BAD_ALIAS = "Invalid alias: %s"
	ERROR_MANY_ALIAS = "More than one alias"
	ERROR_ZERO_INDENT = "Can't use zero as an indentation width"
	ERROR_UNSUPPORTED_VERSION = "This release of YAML.rb does not support YAML version %s"
	ERROR_UNSUPPORTED_ENCODING = "Attempt to use unsupported encoding: %s"

	#
	# YAML Error classes
	#
    
	class Error < StandardError; end
	class ParseError < Error; end
    class TypeError < StandardError; end

end
PK     Y\
8O4      yaml/dbm.rbnu [        require 'yaml'
require 'dbm'
#
# YAML + DBM = YDBM
# - Same interface as DBM class
#
module YAML

class DBM < ::DBM
    VERSION = "0.1"
    def []( key )
        fetch( key )
    end
    def []=( key, val )
        store( key, val )
    end
    def fetch( keystr, ifnone = nil )
        begin
            val = super( keystr )
            return YAML::load( val ) if String === val
        rescue IndexError
        end
        if block_given?
            yield keystr
        else
            ifnone
        end
    end
    def index( keystr )
        super( keystr.to_yaml )
    end
    def values_at( *keys )
        keys.collect { |k| fetch( k ) }
    end
    def delete( key )
        v = super( key )
        if String === v
            v = YAML::load( v ) 
        end
        v
    end
    def delete_if
        del_keys = keys.dup
        del_keys.delete_if { |k| yield( k, fetch( k ) ) == false }
        del_keys.each { |k| delete( k ) } 
        self
    end
    def reject
        hsh = self.to_hash
        hsh.reject { |k,v| yield k, v }
    end
    def each_pair
        keys.each { |k| yield k, fetch( k ) }
        self
    end
    def each_value
        super { |v| yield YAML::load( v ) }
        self
    end
    def values
        super.collect { |v| YAML::load( v ) }
    end
    def has_value?( val )
        each_value { |v| return true if v == val }
        return false
    end
    def invert
        h = {}
        keys.each { |k| h[ self.fetch( k ) ] = k }
        h
    end
    def replace( hsh )
        clear
        update( hsh )
    end
    def shift
        a = super
        a[1] = YAML::load( a[1] ) if a
        a
    end
    def select( *keys )
        if block_given?
            self.keys.collect { |k| v = self[k]; [k, v] if yield k, v }.compact
        else
            values_at( *keys )
        end
    end
    def store( key, val )
        super( key, val.to_yaml )
        val
    end
    def update( hsh )
        hsh.keys.each do |k|
            self.store( k, hsh.fetch( k ) )
        end
        self
    end
    def to_a
        a = []
        keys.each { |k| a.push [ k, self.fetch( k ) ] }
        a
    end
    def to_hash
        h = {}
        keys.each { |k| h[ k ] = self.fetch( k ) }
        h
    end
    alias :each :each_pair
end

end
PK     Y\G,r  r    tempfile.rbnu [        #
# tempfile - manipulates temporary files
#
# $Id: tempfile.rb 16127 2008-04-21 09:43:44Z knu $
#

require 'delegate'
require 'tmpdir'

# A class for managing temporary files.  This library is written to be
# thread safe.
class Tempfile < DelegateClass(File)
  MAX_TRY = 10
  @@cleanlist = []

  # Creates a temporary file of mode 0600 in the temporary directory,
  # opens it with mode "w+", and returns a Tempfile object which
  # represents the created temporary file.  A Tempfile object can be
  # treated just like a normal File object.
  #
  # The basename parameter is used to determine the name of a
  # temporary file.  If an Array is given, the first element is used
  # as prefix string and the second as suffix string, respectively.
  # Otherwise it is treated as prefix string.
  #
  # If tmpdir is omitted, the temporary directory is determined by
  # Dir::tmpdir provided by 'tmpdir.rb'.
  # When $SAFE > 0 and the given tmpdir is tainted, it uses
  # /tmp. (Note that ENV values are tainted by default)
  def initialize(basename, tmpdir=Dir::tmpdir)
    if $SAFE > 0 and tmpdir.tainted?
      tmpdir = '/tmp'
    end

    lock = nil
    n = failure = 0
    
    begin
      Thread.critical = true

      begin
	tmpname = File.join(tmpdir, make_tmpname(basename, n))
	lock = tmpname + '.lock'
	n += 1
      end while @@cleanlist.include?(tmpname) or
	File.exist?(lock) or File.exist?(tmpname)

      Dir.mkdir(lock)
    rescue
      failure += 1
      retry if failure < MAX_TRY
      raise "cannot generate tempfile `%s'" % tmpname
    ensure
      Thread.critical = false
    end

    @data = [tmpname]
    @clean_proc = Tempfile.callback(@data)
    ObjectSpace.define_finalizer(self, @clean_proc)

    @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)
    @tmpname = tmpname
    @@cleanlist << @tmpname
    @data[1] = @tmpfile
    @data[2] = @@cleanlist

    super(@tmpfile)

    # Now we have all the File/IO methods defined, you must not
    # carelessly put bare puts(), etc. after this.

    Dir.rmdir(lock)
  end

  def make_tmpname(basename, n)
    case basename
    when Array
      prefix, suffix = *basename
    else
      prefix, suffix = basename, ''
    end
 
    t = Time.now.strftime("%Y%m%d")
    path = "#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}-#{n}#{suffix}"
  end
  private :make_tmpname

  # Opens or reopens the file with mode "r+".
  def open
    @tmpfile.close if @tmpfile
    @tmpfile = File.open(@tmpname, 'r+')
    @data[1] = @tmpfile
    __setobj__(@tmpfile)
  end

  def _close	# :nodoc:
    @tmpfile.close if @tmpfile
    @tmpfile = nil
    @data[1] = nil if @data
  end    
  protected :_close

  # Closes the file.  If the optional flag is true, unlinks the file
  # after closing.
  #
  # If you don't explicitly unlink the temporary file, the removal
  # will be delayed until the object is finalized.
  def close(unlink_now=false)
    if unlink_now
      close!
    else
      _close
    end
  end

  # Closes and unlinks the file.
  def close!
    _close
    @clean_proc.call
    ObjectSpace.undefine_finalizer(self)
    @data = @tmpname = nil
  end

  # Unlinks the file.  On UNIX-like systems, it is often a good idea
  # to unlink a temporary file immediately after creating and opening
  # it, because it leaves other programs zero chance to access the
  # file.
  def unlink
    # keep this order for thread safeness
    begin
      File.unlink(@tmpname) if File.exist?(@tmpname)
      @@cleanlist.delete(@tmpname)
      @data = @tmpname = nil
      ObjectSpace.undefine_finalizer(self)
    rescue Errno::EACCES
      # may not be able to unlink on Windows; just ignore
    end
  end
  alias delete unlink

  # Returns the full path name of the temporary file.
  def path
    @tmpname
  end

  # Returns the size of the temporary file.  As a side effect, the IO
  # buffer is flushed before determining the size.
  def size
    if @tmpfile
      @tmpfile.flush
      @tmpfile.stat.size
    else
      0
    end
  end
  alias length size

  class << self
    def callback(data)	# :nodoc:
      pid = $$
      lambda{
	if pid == $$ 
	  path, tmpfile, cleanlist = *data

	  print "removing ", path, "..." if $DEBUG

	  tmpfile.close if tmpfile

	  # keep this order for thread safeness
	  File.unlink(path) if File.exist?(path)
	  cleanlist.delete(path) if cleanlist

	  print "done\n" if $DEBUG
	end
      }
    end

    # If no block is given, this is a synonym for new().
    #
    # If a block is given, it will be passed tempfile as an argument,
    # and the tempfile will automatically be closed when the block
    # terminates.  In this case, open() returns nil.
    def open(*args)
      tempfile = new(*args)

      if block_given?
	begin
	  yield(tempfile)
	ensure
	  tempfile.close
	end

	nil
      else
	tempfile
      end
    end
  end
end

if __FILE__ == $0
#  $DEBUG = true
  f = Tempfile.new("foo")
  f.print("foo\n")
  f.close
  f.open
  p f.gets # => "foo\n"
  f.close!
end
PK     Y\'6  6    resolv-replace.rbnu [        require 'socket'
require 'resolv'

class << IPSocket
  alias original_resolv_getaddress getaddress
  def getaddress(host)
    begin
      return Resolv.getaddress(host).to_s
    rescue Resolv::ResolvError
      raise SocketError, "Hostname not known: #{host}"
    end
  end
end

class TCPSocket
  alias original_resolv_initialize initialize
  def initialize(host, serv, *rest)
    rest[0] = IPSocket.getaddress(rest[0]) unless rest.empty?
    original_resolv_initialize(IPSocket.getaddress(host), serv, *rest)
  end
end

class UDPSocket
  alias original_resolv_bind bind
  def bind(host, port)
    host = IPSocket.getaddress(host) if host != ""
    original_resolv_bind(host, port)
  end

  alias original_resolv_connect connect
  def connect(host, port)
    original_resolv_connect(IPSocket.getaddress(host), port)
  end

  alias original_resolv_send send
  def send(mesg, flags, *rest)
    if rest.length == 2
      host, port = rest
      begin
        addrs = Resolv.getaddresses(host)
      rescue Resolv::ResolvError
        raise SocketError, "Hostname not known: #{host}"
      end
      err = nil
      addrs[0...-1].each {|addr|
        begin
          return original_resolv_send(mesg, flags, addr, port)
        rescue SystemCallError
        end
      }
      original_resolv_send(mesg, flags, addrs[-1], port)
    else
      original_resolv_send(mesg, flags, *rest)
    end
  end
end

class SOCKSSocket
  alias original_resolv_initialize initialize
  def initialize(host, serv)
    original_resolv_initialize(IPSocket.getaddress(host), port)
  end
end if defined? SOCKSSocket
PK     Y\ܽ      date.rbnu [        #
# date.rb - date and time library
#
# Author: Tadayoshi Funaba 1998-2010
#
# Documentation: William Webber <william@williamwebber.com>
#
#--
# $Id: date.rb,v 2.37 2008-01-17 20:16:31+09 tadf Exp $
#++
#
# == Overview
#
# This file provides two classes for working with
# dates and times.
#
# The first class, Date, represents dates.
# It works with years, months, weeks, and days.
# See the Date class documentation for more details.
#
# The second, DateTime, extends Date to include hours,
# minutes, seconds, and fractions of a second.  It
# provides basic support for time zones.  See the
# DateTime class documentation for more details.
#
# === Ways of calculating the date.
#
# In common usage, the date is reckoned in years since or
# before the Common Era (CE/BCE, also known as AD/BC), then
# as a month and day-of-the-month within the current year.
# This is known as the *Civil* *Date*, and abbreviated
# as +civil+ in the Date class.
#
# Instead of year, month-of-the-year,  and day-of-the-month,
# the date can also be reckoned in terms of year and
# day-of-the-year.  This is known as the *Ordinal* *Date*,
# and is abbreviated as +ordinal+ in the Date class.  (Note
# that referring to this as the Julian date is incorrect.)
#
# The date can also be reckoned in terms of year, week-of-the-year,
# and day-of-the-week.  This is known as the *Commercial*
# *Date*, and is abbreviated as +commercial+ in the
# Date class.  The commercial week runs Monday (day-of-the-week
# 1) to Sunday (day-of-the-week 7), in contrast to the civil
# week which runs Sunday (day-of-the-week 0) to Saturday
# (day-of-the-week 6).  The first week of the commercial year
# starts on the Monday on or before January 1, and the commercial
# year itself starts on this Monday, not January 1.
#
# For scientific purposes, it is convenient to refer to a date
# simply as a day count, counting from an arbitrary initial
# day.  The date first chosen for this was January 1, 4713 BCE.
# A count of days from this date is the *Julian* *Day* *Number*
# or *Julian* *Date*, which is abbreviated as +jd+ in the
# Date class.  This is in local time, and counts from midnight
# on the initial day.  The stricter usage is in UTC, and counts
# from midday on the initial day.  This is referred to in the
# Date class as the *Astronomical* *Julian* *Day* *Number*, and
# abbreviated as +ajd+.  In the Date class, the Astronomical
# Julian Day Number includes fractional days.
#
# Another absolute day count is the *Modified* *Julian* *Day*
# *Number*, which takes November 17, 1858 as its initial day.
# This is abbreviated as +mjd+ in the Date class.  There
# is also an *Astronomical* *Modified* *Julian* *Day* *Number*,
# which is in UTC and includes fractional days.  This is
# abbreviated as +amjd+ in the Date class.  Like the Modified
# Julian Day Number (and unlike the Astronomical Julian
# Day Number), it counts from midnight.
#
# Alternative calendars such as the Chinese Lunar Calendar,
# the Islamic Calendar, or the French Revolutionary Calendar
# are not supported by the Date class; nor are calendars that
# are based on an Era different from the Common Era, such as
# the Japanese Imperial Calendar or the Republic of China
# Calendar.
#
# === Calendar Reform
#
# The standard civil year is 365 days long.  However, the
# solar year is fractionally longer than this.  To account
# for this, a *leap* *year* is occasionally inserted.  This
# is a year with 366 days, the extra day falling on February 29.
# In the early days of the civil calendar, every fourth
# year without exception was a leap year.  This way of
# reckoning leap years is the *Julian* *Calendar*.
#
# However, the solar year is marginally shorter than 365 1/4
# days, and so the *Julian* *Calendar* gradually ran slow
# over the centuries.  To correct this, every 100th year
# (but not every 400th year) was excluded as a leap year.
# This way of reckoning leap years, which we use today, is
# the *Gregorian* *Calendar*.
#
# The Gregorian Calendar was introduced at different times
# in different regions.  The day on which it was introduced
# for a particular region is the *Day* *of* *Calendar*
# *Reform* for that region.  This is abbreviated as +sg+
# (for Start of Gregorian calendar) in the Date class.
#
# Two such days are of particular
# significance.  The first is October 15, 1582, which was
# the Day of Calendar Reform for Italy and most Catholic
# countries.  The second is September 14, 1752, which was
# the Day of Calendar Reform for England and its colonies
# (including what is now the United States).  These two
# dates are available as the constants Date::ITALY and
# Date::ENGLAND, respectively.  (By comparison, Germany and
# Holland, less Catholic than Italy but less stubborn than
# England, changed over in 1698; Sweden in 1753; Russia not
# till 1918, after the Revolution; and Greece in 1923.  Many
# Orthodox churches still use the Julian Calendar.  A complete
# list of Days of Calendar Reform can be found at
# http://www.polysyllabic.com/GregConv.html.)
#
# Switching from the Julian to the Gregorian calendar
# involved skipping a number of days to make up for the
# accumulated lag, and the later the switch was (or is)
# done, the more days need to be skipped.  So in 1582 in Italy,
# 4th October was followed by 15th October, skipping 10 days; in 1752
# in England, 2nd September was followed by 14th September, skipping
# 11 days; and if I decided to switch from Julian to Gregorian
# Calendar this midnight, I would go from 27th July 2003 (Julian)
# today to 10th August 2003 (Gregorian) tomorrow, skipping
# 13 days.  The Date class is aware of this gap, and a supposed
# date that would fall in the middle of it is regarded as invalid.
#
# The Day of Calendar Reform is relevant to all date representations
# involving years.  It is not relevant to the Julian Day Numbers,
# except for converting between them and year-based representations.
#
# In the Date and DateTime classes, the Day of Calendar Reform or
# +sg+ can be specified a number of ways.  First, it can be as
# the Julian Day Number of the Day of Calendar Reform.  Second,
# it can be using the constants Date::ITALY or Date::ENGLAND; these
# are in fact the Julian Day Numbers of the Day of Calendar Reform
# of the respective regions.  Third, it can be as the constant
# Date::JULIAN, which means to always use the Julian Calendar.
# Finally, it can be as the constant Date::GREGORIAN, which means
# to always use the Gregorian Calendar.
#
# Note: in the Julian Calendar, New Years Day was March 25.  The
# Date class does not follow this convention.
#
# === Time Zones
#
# DateTime objects support a simple representation
# of time zones.  Time zones are represented as an offset
# from UTC, as a fraction of a day.  This offset is the
# how much local time is later (or earlier) than UTC.
# UTC offset 0 is centred on England (also known as GMT).
# As you travel east, the offset increases until you
# reach the dateline in the middle of the Pacific Ocean;
# as you travel west, the offset decreases.  This offset
# is abbreviated as +of+ in the Date class.
#
# This simple representation of time zones does not take
# into account the common practice of Daylight Savings
# Time or Summer Time.
#
# Most DateTime methods return the date and the
# time in local time.  The two exceptions are
# #ajd() and #amjd(), which return the date and time
# in UTC time, including fractional days.
#
# The Date class does not support time zone offsets, in that
# there is no way to create a Date object with a time zone.
# However, methods of the Date class when used by a
# DateTime instance will use the time zone offset of this
# instance.
#
# == Examples of use
#
# === Print out the date of every Sunday between two dates.
#
#     def print_sundays(d1, d2)
#         d1 +=1 while (d1.wday != 0)
#         d1.step(d2, 7) do |date|
#             puts "#{Date::MONTHNAMES[date.mon]} #{date.day}"
#         end
#     end
#
#     print_sundays(Date::civil(2003, 4, 8), Date::civil(2003, 5, 23))
#
# === Calculate how many seconds to go till midnight on New Year's Day.
#
#     def secs_to_new_year(now = DateTime::now())
#         new_year = DateTime.new(now.year + 1, 1, 1)
#         dif = new_year - now
#         hours, mins, secs, ignore_fractions = Date::day_fraction_to_time(dif)
#         return hours * 60 * 60 + mins * 60 + secs
#     end
#
#     puts secs_to_new_year()

require 'rational'
require 'date/format'

# Class representing a date.
#
# See the documentation to the file date.rb for an overview.
#
# Internally, the date is represented as an Astronomical
# Julian Day Number, +ajd+.  The Day of Calendar Reform, +sg+, is
# also stored, for conversions to other date formats.  (There
# is also an +of+ field for a time zone offset, but this
# is only for the use of the DateTime subclass.)
#
# A new Date object is created using one of the object creation
# class methods named after the corresponding date format, and the
# arguments appropriate to that date format; for instance,
# Date::civil() (aliased to Date::new()) with year, month,
# and day-of-month, or Date::ordinal() with year and day-of-year.
# All of these object creation class methods also take the
# Day of Calendar Reform as an optional argument.
#
# Date objects are immutable once created.
#
# Once a Date has been created, date values
# can be retrieved for the different date formats supported
# using instance methods.  For instance, #mon() gives the
# Civil month, #cwday() gives the Commercial day of the week,
# and #yday() gives the Ordinal day of the year.  Date values
# can be retrieved in any format, regardless of what format
# was used to create the Date instance.
#
# The Date class includes the Comparable module, allowing
# date objects to be compared and sorted, ranges of dates
# to be created, and so forth.
class Date

  include Comparable

  # Full month names, in English.  Months count from 1 to 12; a
  # month's numerical representation indexed into this array
  # gives the name of that month (hence the first element is nil).
  MONTHNAMES = [nil] + %w(January February March April May June July
			  August September October November December)

  # Full names of days of the week, in English.  Days of the week
  # count from 0 to 6 (except in the commercial week); a day's numerical
  # representation indexed into this array gives the name of that day.
  DAYNAMES = %w(Sunday Monday Tuesday Wednesday Thursday Friday Saturday)

  # Abbreviated month names, in English.
  ABBR_MONTHNAMES = [nil] + %w(Jan Feb Mar Apr May Jun
			       Jul Aug Sep Oct Nov Dec)

  # Abbreviated day names, in English.
  ABBR_DAYNAMES = %w(Sun Mon Tue Wed Thu Fri Sat)

  [MONTHNAMES, DAYNAMES, ABBR_MONTHNAMES, ABBR_DAYNAMES].each do |xs|
    xs.each{|x| x.freeze unless x.nil?}.freeze
  end

  class Infinity < Numeric # :nodoc:

    include Comparable

    def initialize(d=1) @d = d <=> 0 end

    def d() @d end

    protected :d

    def zero? () false end
    def finite? () false end
    def infinite? () d.nonzero? end
    def nan? () d.zero? end

    def abs() self.class.new end

    def -@ () self.class.new(-d) end
    def +@ () self.class.new(+d) end

    def <=> (other)
      case other
      when Infinity; return d <=> other.d
      when Numeric; return d
      else
	begin
	  l, r = other.coerce(self)
	  return l <=> r
	rescue NoMethodError
	end
      end
      nil
    end

    def coerce(other)
      case other
      when Numeric; return -d, d
      else
	super
      end
    end

  end

  # The Julian Day Number of the Day of Calendar Reform for Italy
  # and the Catholic countries.
  ITALY     = 2299161 # 1582-10-15

  # The Julian Day Number of the Day of Calendar Reform for England
  # and her Colonies.
  ENGLAND   = 2361222 # 1752-09-14

  # A constant used to indicate that a Date should always use the
  # Julian calendar.
  JULIAN    =  Infinity.new

  # A constant used to indicate that a Date should always use the
  # Gregorian calendar.
  GREGORIAN = -Infinity.new

  HALF_DAYS_IN_DAY       = Rational(1, 2) # :nodoc:
  HOURS_IN_DAY           = Rational(1, 24) # :nodoc:
  MINUTES_IN_DAY         = Rational(1, 1440) # :nodoc:
  SECONDS_IN_DAY         = Rational(1, 86400) # :nodoc:
  MILLISECONDS_IN_DAY    = Rational(1, 86400*10**3) # :nodoc:
  NANOSECONDS_IN_DAY     = Rational(1, 86400*10**9) # :nodoc:
  MILLISECONDS_IN_SECOND = Rational(1, 10**3) # :nodoc:
  NANOSECONDS_IN_SECOND  = Rational(1, 10**9) # :nodoc:

  MJD_EPOCH_IN_AJD       = Rational(4800001, 2) # 1858-11-17 # :nodoc:
  UNIX_EPOCH_IN_AJD      = Rational(4881175, 2) # 1970-01-01 # :nodoc:
  MJD_EPOCH_IN_CJD       = 2400001 # :nodoc:
  UNIX_EPOCH_IN_CJD      = 2440588 # :nodoc:
  LD_EPOCH_IN_CJD        = 2299160 # :nodoc:

  # Does a given Julian Day Number fall inside the old-style (Julian)
  # calendar?
  #
  # +jd+ is the Julian Day Number in question. +sg+ may be Date::GREGORIAN,
  # in which case the answer is false; it may be Date::JULIAN, in which case
  # the answer is true; or it may a number representing the Day of
  # Calendar Reform. Date::ENGLAND and Date::ITALY are two possible such
  # days.

  def self.julian? (jd, sg)
    case sg
    when Numeric
      jd < sg
    else
      if $VERBOSE
	warn("#{caller.shift.sub(/:in .*/, '')}: " \
"warning: do not use non-numerical object as julian day number anymore")
      end
      not sg
    end
  end

  # Does a given Julian Day Number fall inside the new-style (Gregorian)
  # calendar?
  #
  # The reverse of self.os?  See the documentation for that method for
  # more details.
  def self.gregorian? (jd, sg) !julian?(jd, sg) end

  def self.fix_style(jd, sg) # :nodoc:
    if julian?(jd, sg)
    then JULIAN
    else GREGORIAN end
  end

  private_class_method :fix_style

  # Convert an Ordinal Date to a Julian Day Number.
  #
  # +y+ and +d+ are the year and day-of-year to convert.
  # +sg+ specifies the Day of Calendar Reform.
  #
  # Returns the corresponding Julian Day Number.
  def self.ordinal_to_jd(y, d, sg=GREGORIAN)
    civil_to_jd(y, 1, d, sg)
  end

  # Convert a Julian Day Number to an Ordinal Date.
  #
  # +jd+ is the Julian Day Number to convert.
  # +sg+ specifies the Day of Calendar Reform.
  #
  # Returns the corresponding Ordinal Date as
  # [year, day_of_year]
  def self.jd_to_ordinal(jd, sg=GREGORIAN)
    y = jd_to_civil(jd, sg)[0]
    doy = jd - civil_to_jd(y - 1, 12, 31, fix_style(jd, sg))
    return y, doy
  end

  # Convert a Civil Date to a Julian Day Number.
  # +y+, +m+, and +d+ are the year, month, and day of the
  # month.  +sg+ specifies the Day of Calendar Reform.
  #
  # Returns the corresponding Julian Day Number.
  def self.civil_to_jd(y, m, d, sg=GREGORIAN)
    if m <= 2
      y -= 1
      m += 12
    end
    a = (y / 100.0).floor
    b = 2 - a + (a / 4.0).floor
    jd = (365.25 * (y + 4716)).floor +
      (30.6001 * (m + 1)).floor +
      d + b - 1524
    if julian?(jd, sg)
      jd -= b
    end
    jd
  end

  # Convert a Julian Day Number to a Civil Date.  +jd+ is
  # the Julian Day Number. +sg+ specifies the Day of
  # Calendar Reform.
  #
  # Returns the corresponding [year, month, day_of_month]
  # as a three-element array.
  def self.jd_to_civil(jd, sg=GREGORIAN)
    if julian?(jd, sg)
      a = jd
    else
      x = ((jd - 1867216.25) / 36524.25).floor
      a = jd + 1 + x - (x / 4.0).floor
    end
    b = a + 1524
    c = ((b - 122.1) / 365.25).floor
    d = (365.25 * c).floor
    e = ((b - d) / 30.6001).floor
    dom = b - d - (30.6001 * e).floor
    if e <= 13
      m = e - 1
      y = c - 4716
    else
      m = e - 13
      y = c - 4715
    end
    return y, m, dom
  end

  # Convert a Commercial Date to a Julian Day Number.
  #
  # +y+, +w+, and +d+ are the (commercial) year, week of the year,
  # and day of the week of the Commercial Date to convert.
  # +sg+ specifies the Day of Calendar Reform.
  def self.commercial_to_jd(y, w, d, ns=GREGORIAN)
    jd = civil_to_jd(y, 1, 4, ns)
    (jd - (((jd - 1) + 1) % 7)) +
      7 * (w - 1) +
      (d - 1)
  end

  # Convert a Julian Day Number to a Commercial Date
  #
  # +jd+ is the Julian Day Number to convert.
  # +sg+ specifies the Day of Calendar Reform.
  #
  # Returns the corresponding Commercial Date as
  # [commercial_year, week_of_year, day_of_week]
  def self.jd_to_commercial(jd, sg=GREGORIAN)
    ns = fix_style(jd, sg)
    a = jd_to_civil(jd - 3, ns)[0]
    y = if jd >= commercial_to_jd(a + 1, 1, 1, ns) then a + 1 else a end
    w = 1 + ((jd - commercial_to_jd(y, 1, 1, ns)) / 7).floor
    d = (jd + 1) % 7
    d = 7 if d == 0
    return y, w, d
  end

  def self.weeknum_to_jd(y, w, d, f=0, ns=GREGORIAN) # :nodoc:
    a = civil_to_jd(y, 1, 1, ns) + 6
    (a - ((a - f) + 1) % 7 - 7) + 7 * w + d
  end

  def self.jd_to_weeknum(jd, f=0, sg=GREGORIAN) # :nodoc:
    ns = fix_style(jd, sg)
    y, m, d = jd_to_civil(jd, ns)
    a = civil_to_jd(y, 1, 1, ns) + 6
    w, d = (jd - (a - ((a - f) + 1) % 7) + 7).divmod(7)
    return y, w, d
  end

  private_class_method :weeknum_to_jd, :jd_to_weeknum

  # Convert an Astronomical Julian Day Number to a (civil) Julian
  # Day Number.
  #
  # +ajd+ is the Astronomical Julian Day Number to convert.
  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).
  #
  # Returns the (civil) Julian Day Number as [day_number,
  # fraction] where +fraction+ is always 1/2.
  def self.ajd_to_jd(ajd, of=0) (ajd + of + HALF_DAYS_IN_DAY).divmod(1) end

  # Convert a (civil) Julian Day Number to an Astronomical Julian
  # Day Number.
  #
  # +jd+ is the Julian Day Number to convert, and +fr+ is a
  # fractional day.
  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).
  #
  # Returns the Astronomical Julian Day Number as a single
  # numeric value.
  def self.jd_to_ajd(jd, fr, of=0) jd + fr - of - HALF_DAYS_IN_DAY end

  # Convert a fractional day +fr+ to [hours, minutes, seconds,
  # fraction_of_a_second]
  def self.day_fraction_to_time(fr)
    ss,  fr = fr.divmod(SECONDS_IN_DAY) # 4p
    h,   ss = ss.divmod(3600)
    min, s  = ss.divmod(60)
    return h, min, s, fr
  end

  # Convert an +h+ hour, +min+ minutes, +s+ seconds period
  # to a fractional day.
  begin
    Rational(Rational(1, 2), 2) # a challenge

    def self.time_to_day_fraction(h, min, s)
      Rational(h * 3600 + min * 60 + s, 86400) # 4p
    end
  rescue
    def self.time_to_day_fraction(h, min, s)
	if Integer === h && Integer === min && Integer === s
	  Rational(h * 3600 + min * 60 + s, 86400) # 4p
	else
	  (h * 3600 + min * 60 + s).to_r/86400 # 4p
	end
    end
  end

  # Convert an Astronomical Modified Julian Day Number to an
  # Astronomical Julian Day Number.
  def self.amjd_to_ajd(amjd) amjd + MJD_EPOCH_IN_AJD end

  # Convert an Astronomical Julian Day Number to an
  # Astronomical Modified Julian Day Number.
  def self.ajd_to_amjd(ajd) ajd - MJD_EPOCH_IN_AJD end

  # Convert a Modified Julian Day Number to a Julian
  # Day Number.
  def self.mjd_to_jd(mjd) mjd + MJD_EPOCH_IN_CJD end

  # Convert a Julian Day Number to a Modified Julian Day
  # Number.
  def self.jd_to_mjd(jd) jd - MJD_EPOCH_IN_CJD end

  # Convert a count of the number of days since the adoption
  # of the Gregorian Calendar (in Italy) to a Julian Day Number.
  def self.ld_to_jd(ld) ld + LD_EPOCH_IN_CJD end

  # Convert a Julian Day Number to the number of days since
  # the adoption of the Gregorian Calendar (in Italy).
  def self.jd_to_ld(jd) jd - LD_EPOCH_IN_CJD end

  # Convert a Julian Day Number to the day of the week.
  #
  # Sunday is day-of-week 0; Saturday is day-of-week 6.
  def self.jd_to_wday(jd) (jd + 1) % 7 end

  # Is a year a leap year in the Julian calendar?
  #
  # All years divisible by 4 are leap years in the Julian calendar.
  def self.julian_leap? (y) y % 4 == 0 end

  # Is a year a leap year in the Gregorian calendar?
  #
  # All years divisible by 4 are leap years in the Gregorian calendar,
  # except for years divisible by 100 and not by 400.
  def self.gregorian_leap? (y) y % 4 == 0 && y % 100 != 0 || y % 400 == 0 end

  class << self; alias_method :leap?, :gregorian_leap? end
  class << self; alias_method :new!, :new end

  # Is +jd+ a valid Julian Day Number?
  #
  # If it is, returns it.  In fact, any value is treated as a valid
  # Julian Day Number.
  def self.valid_jd? (jd, sg=ITALY) jd end

  # Do the year +y+ and day-of-year +d+ make a valid Ordinal Date?
  # Returns the corresponding Julian Day Number if they do, or
  # nil if they don't.
  #
  # +d+ can be a negative number, in which case it counts backwards
  # from the end of the year (-1 being the last day of the year).
  # No year wraparound is performed, however, so valid values of
  # +d+ are -365 .. -1, 1 .. 365 on a non-leap-year,
  # -366 .. -1, 1 .. 366 on a leap year.
  # A date falling in the period skipped in the Day of Calendar Reform
  # adjustment is not valid.
  #
  # +sg+ specifies the Day of Calendar Reform.
  def self.valid_ordinal? (y, d, sg=ITALY)
    if d < 0
      ny, = (y + 1).divmod(1)
      jd = ordinal_to_jd(ny, d + 1, sg)
      ns = fix_style(jd, sg)
      return unless [y] == jd_to_ordinal(jd, sg)[0..0]
      return unless [ny, 1] == jd_to_ordinal(jd - d, ns)
    else
      jd = ordinal_to_jd(y, d, sg)
      return unless [y, d] == jd_to_ordinal(jd, sg)
    end
    jd
  end

  # Do year +y+, month +m+, and day-of-month +d+ make a
  # valid Civil Date?  Returns the corresponding Julian
  # Day Number if they do, nil if they don't.
  #
  # +m+ and +d+ can be negative, in which case they count
  # backwards from the end of the year and the end of the
  # month respectively.  No wraparound is performed, however,
  # and invalid values cause an ArgumentError to be raised.
  # A date falling in the period skipped in the Day of Calendar
  # Reform adjustment is not valid.
  #
  # +sg+ specifies the Day of Calendar Reform.
  def self.valid_civil? (y, m, d, sg=ITALY)
    if m < 0
      m += 13
    end
    if d < 0
      ny, nm = (y * 12 + m).divmod(12)
      nm,    = (nm + 1).divmod(1)
      jd = civil_to_jd(ny, nm, d + 1, sg)
      ns = fix_style(jd, sg)
      return unless [y, m] == jd_to_civil(jd, sg)[0..1]
      return unless [ny, nm, 1] == jd_to_civil(jd - d, ns)
    else
      jd = civil_to_jd(y, m, d, sg)
      return unless [y, m, d] == jd_to_civil(jd, sg)
    end
    jd
  end

  class << self; alias_method :valid_date?, :valid_civil? end

  # Do year +y+, week-of-year +w+, and day-of-week +d+ make a
  # valid Commercial Date?  Returns the corresponding Julian
  # Day Number if they do, nil if they don't.
  #
  # Monday is day-of-week 1; Sunday is day-of-week 7.
  #
  # +w+ and +d+ can be negative, in which case they count
  # backwards from the end of the year and the end of the
  # week respectively.  No wraparound is performed, however,
  # and invalid values cause an ArgumentError to be raised.
  # A date falling in the period skipped in the Day of Calendar
  # Reform adjustment is not valid.
  #
  # +sg+ specifies the Day of Calendar Reform.
  def self.valid_commercial? (y, w, d, sg=ITALY)
    if d < 0
      d += 8
    end
    if w < 0
      ny, nw, nd =
	jd_to_commercial(commercial_to_jd(y + 1, 1, 1) + w * 7)
      return unless ny == y
      w = nw
    end
    jd = commercial_to_jd(y, w, d)
    return unless gregorian?(jd, sg)
    return unless [y, w, d] == jd_to_commercial(jd)
    jd
  end

  def self.valid_weeknum? (y, w, d, f, sg=ITALY) # :nodoc:
    if d < 0
      d += 7
    end
    if w < 0
      ny, nw, nd, nf =
	jd_to_weeknum(weeknum_to_jd(y + 1, 1, f, f) + w * 7, f)
      return unless ny == y
      w = nw
    end
    jd = weeknum_to_jd(y, w, d, f)
    return unless gregorian?(jd, sg)
    return unless [y, w, d] == jd_to_weeknum(jd, f)
    jd
  end

  private_class_method :valid_weeknum?

  # Do hour +h+, minute +min+, and second +s+ constitute a valid time?
  #
  # If they do, returns their value as a fraction of a day.  If not,
  # returns nil.
  #
  # The 24-hour clock is used.  Negative values of +h+, +min+, and
  # +sec+ are treating as counting backwards from the end of the
  # next larger unit (e.g. a +min+ of -2 is treated as 58).  No
  # wraparound is performed.
  def self.valid_time? (h, min, s)
    h   += 24 if h   < 0
    min += 60 if min < 0
    s   += 60 if s   < 0
    return unless ((0...24) === h &&
		   (0...60) === min &&
		   (0...60) === s) ||
		  (24 == h &&
		    0 == min &&
		    0 == s)
    time_to_day_fraction(h, min, s)
  end

  # Create a new Date object from a Julian Day Number.
  #
  # +jd+ is the Julian Day Number; if not specified, it defaults to
  # 0.
  # +sg+ specifies the Day of Calendar Reform.
  def self.jd(jd=0, sg=ITALY)
    jd = valid_jd?(jd, sg)
    new!(jd_to_ajd(jd, 0, 0), 0, sg)
  end

  # Create a new Date object from an Ordinal Date, specified
  # by year +y+ and day-of-year +d+. +d+ can be negative,
  # in which it counts backwards from the end of the year.
  # No year wraparound is performed, however.  An invalid
  # value for +d+ results in an ArgumentError being raised.
  #
  # +y+ defaults to -4712, and +d+ to 1; this is Julian Day
  # Number day 0.
  #
  # +sg+ specifies the Day of Calendar Reform.
  def self.ordinal(y=-4712, d=1, sg=ITALY)
    unless jd = valid_ordinal?(y, d, sg)
      raise ArgumentError, 'invalid date'
    end
    new!(jd_to_ajd(jd, 0, 0), 0, sg)
  end

  # Create a new Date object for the Civil Date specified by
  # year +y+, month +m+, and day-of-month +d+.
  #
  # +m+ and +d+ can be negative, in which case they count
  # backwards from the end of the year and the end of the
  # month respectively.  No wraparound is performed, however,
  # and invalid values cause an ArgumentError to be raised.
  # can be negative
  #
  # +y+ defaults to -4712, +m+ to 1, and +d+ to 1; this is
  # Julian Day Number day 0.
  #
  # +sg+ specifies the Day of Calendar Reform.
  def self.civil(y=-4712, m=1, d=1, sg=ITALY)
    unless jd = valid_civil?(y, m, d, sg)
      raise ArgumentError, 'invalid date'
    end
    new!(jd_to_ajd(jd, 0, 0), 0, sg)
  end

  class << self; alias_method :new, :civil end

  # Create a new Date object for the Commercial Date specified by
  # year +y+, week-of-year +w+, and day-of-week +d+.
  #
  # Monday is day-of-week 1; Sunday is day-of-week 7.
  #
  # +w+ and +d+ can be negative, in which case they count
  # backwards from the end of the year and the end of the
  # week respectively.  No wraparound is performed, however,
  # and invalid values cause an ArgumentError to be raised.
  #
  # +y+ defaults to 1582, +w+ to 41, and +d+ to 5, the Day of
  # Calendar Reform for Italy and the Catholic countries.
  #
  # +sg+ specifies the Day of Calendar Reform.
  def self.commercial(y=1582, w=41, d=5, sg=ITALY)
    unless jd = valid_commercial?(y, w, d, sg)
      raise ArgumentError, 'invalid date'
    end
    new!(jd_to_ajd(jd, 0, 0), 0, sg)
  end

  def self.weeknum(y=1582, w=41, d=5, f=0, sg=ITALY) # :nodoc:
    unless jd = valid_weeknum?(y, w, d, f, sg)
      raise ArgumentError, 'invalid date'
    end
    new!(jd_to_ajd(jd, 0, 0), 0, sg)
  end

  private_class_method :weeknum

  def self.rewrite_frags(elem) # :nodoc:
    elem ||= {}
    if seconds = elem[:seconds]
      d,   fr = seconds.divmod(86400)
      h,   fr = fr.divmod(3600)
      min, fr = fr.divmod(60)
      s,   fr = fr.divmod(1)
      elem[:jd] = UNIX_EPOCH_IN_CJD + d
      elem[:hour] = h
      elem[:min] = min
      elem[:sec] = s
      elem[:sec_fraction] = fr
      elem.delete(:seconds)
      elem.delete(:offset)
    end
    elem
  end

  private_class_method :rewrite_frags

  def self.complete_frags(elem) # :nodoc:
    i = 0
    g = [[:time, [:hour, :min, :sec]],
	 [nil, [:jd]],
	 [:ordinal, [:year, :yday, :hour, :min, :sec]],
	 [:civil, [:year, :mon, :mday, :hour, :min, :sec]],
	 [:commercial, [:cwyear, :cweek, :cwday, :hour, :min, :sec]],
	 [:wday, [:wday, :hour, :min, :sec]],
	 [:wnum0, [:year, :wnum0, :wday, :hour, :min, :sec]],
	 [:wnum1, [:year, :wnum1, :wday, :hour, :min, :sec]],
	 [nil, [:cwyear, :cweek, :wday, :hour, :min, :sec]],
	 [nil, [:year, :wnum0, :cwday, :hour, :min, :sec]],
	 [nil, [:year, :wnum1, :cwday, :hour, :min, :sec]]].
      collect{|k, a| e = elem.values_at(*a).compact; [k, a, e]}.
      select{|k, a, e| e.size > 0}.
      sort_by{|k, a, e| [e.size, i -= 1]}.last

    d = nil

    if g && g[0] && (g[1].size - g[2].size) != 0
      d ||= Date.today

      case g[0]
      when :ordinal
	elem[:year] ||= d.year
	elem[:yday] ||= 1
      when :civil
	g[1].each do |e|
	  break if elem[e]
	  elem[e] = d.__send__(e)
	end
	elem[:mon]  ||= 1
	elem[:mday] ||= 1
      when :commercial
	g[1].each do |e|
	  break if elem[e]
	  elem[e] = d.__send__(e)
	end
	elem[:cweek] ||= 1
	elem[:cwday] ||= 1
      when :wday
	elem[:jd] ||= (d - d.wday + elem[:wday]).jd
      when :wnum0
	g[1].each do |e|
	  break if elem[e]
	  elem[e] = d.__send__(e)
	end
	elem[:wnum0] ||= 0
	elem[:wday]  ||= 0
      when :wnum1
	g[1].each do |e|
	  break if elem[e]
	  elem[e] = d.__send__(e)
	end
	elem[:wnum1] ||= 0
	elem[:wday]  ||= 0
      end
    end

    if g && g[0] == :time
      if self <= DateTime
	d ||= Date.today
	elem[:jd] ||= d.jd
      end
    end

    elem[:hour] ||= 0
    elem[:min]  ||= 0
    elem[:sec]  ||= 0
    elem[:sec] = [elem[:sec], 59].min

    elem
  end

  private_class_method :complete_frags

  def self.valid_date_frags?(elem, sg) # :nodoc:
    catch :jd do
      a = elem.values_at(:jd)
      if a.all?
	if jd = valid_jd?(*(a << sg))
	  throw :jd, jd
	end
      end

      a = elem.values_at(:year, :yday)
      if a.all?
	if jd = valid_ordinal?(*(a << sg))
	  throw :jd, jd
	end
      end

      a = elem.values_at(:year, :mon, :mday)
      if a.all?
	if jd = valid_civil?(*(a << sg))
	  throw :jd, jd
	end
      end

      a = elem.values_at(:cwyear, :cweek, :cwday)
      if a[2].nil? && elem[:wday]
	a[2] = elem[:wday].nonzero? || 7
      end
      if a.all?
	if jd = valid_commercial?(*(a << sg))
	  throw :jd, jd
	end
      end

      a = elem.values_at(:year, :wnum0, :wday)
      if a[2].nil? && elem[:cwday]
	a[2] = elem[:cwday] % 7
      end
      if a.all?
	if jd = valid_weeknum?(*(a << 0 << sg))
	  throw :jd, jd
	end
      end

      a = elem.values_at(:year, :wnum1, :wday)
      if a[2]
	a[2] = (a[2] - 1) % 7
      end
      if a[2].nil? && elem[:cwday]
	a[2] = (elem[:cwday] - 1) % 7
      end
      if a.all?
	if jd = valid_weeknum?(*(a << 1 << sg))
	  throw :jd, jd
	end
      end
    end
  end

  private_class_method :valid_date_frags?

  def self.valid_time_frags? (elem) # :nodoc:
    h, min, s = elem.values_at(:hour, :min, :sec)
    valid_time?(h, min, s)
  end

  private_class_method :valid_time_frags?

  def self.new_by_frags(elem, sg) # :nodoc:
    elem = rewrite_frags(elem)
    elem = complete_frags(elem)
    unless jd = valid_date_frags?(elem, sg)
      raise ArgumentError, 'invalid date'
    end
    new!(jd_to_ajd(jd, 0, 0), 0, sg)
  end

  private_class_method :new_by_frags

  # Create a new Date object by parsing from a String
  # according to a specified format.
  #
  # +str+ is a String holding a date representation.
  # +fmt+ is the format that the date is in.  See
  # date/format.rb for details on supported formats.
  #
  # The default +str+ is '-4712-01-01', and the default
  # +fmt+ is '%F', which means Year-Month-Day_of_Month.
  # This gives Julian Day Number day 0.
  #
  # +sg+ specifies the Day of Calendar Reform.
  #
  # An ArgumentError will be raised if +str+ cannot be
  # parsed.
  def self.strptime(str='-4712-01-01', fmt='%F', sg=ITALY)
    elem = _strptime(str, fmt)
    new_by_frags(elem, sg)
  end

  # Create a new Date object by parsing from a String,
  # without specifying the format.
  #
  # +str+ is a String holding a date representation.
  # +comp+ specifies whether to interpret 2-digit years
  # as 19XX (>= 69) or 20XX (< 69); the default is not to.
  # The method will attempt to parse a date from the String
  # using various heuristics; see #_parse in date/format.rb
  # for more details.  If parsing fails, an ArgumentError
  # will be raised.
  #
  # The default +str+ is '-4712-01-01'; this is Julian
  # Day Number day 0.
  #
  # +sg+ specifies the Day of Calendar Reform.
  def self.parse(str='-4712-01-01', comp=false, sg=ITALY)
    elem = _parse(str, comp)
    new_by_frags(elem, sg)
  end

  class << self

    def once(*ids) # :nodoc:
      for id in ids
	module_eval <<-"end;"
	  alias_method :__#{id.to_i}__, :#{id.to_s}
	  private :__#{id.to_i}__
	  def #{id.to_s}(*args, &block)
	    (@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0]
	  end
	end;
      end
    end

    private :once

  end

  # *NOTE* this is the documentation for the method new!().  If
  # you are reading this as the documentation for new(), that is
  # because rdoc doesn't fully support the aliasing of the
  # initialize() method.
  # new() is in
  # fact an alias for #civil(): read the documentation for that
  # method instead.
  #
  # Create a new Date object.
  #
  # +ajd+ is the Astronomical Julian Day Number.
  # +of+ is the offset from UTC as a fraction of a day.
  # Both default to 0.
  #
  # +sg+ specifies the Day of Calendar Reform to use for this
  # Date object.
  #
  # Using one of the factory methods such as Date::civil is
  # generally easier and safer.
  def initialize(ajd=0, of=0, sg=ITALY) @ajd, @of, @sg = ajd, of, sg end

  # Get the date as an Astronomical Julian Day Number.
  def ajd() @ajd end

  # Get the date as an Astronomical Modified Julian Day Number.
  def amjd() self.class.ajd_to_amjd(@ajd) end

  once :amjd

  # Get the date as a Julian Day Number.
  def jd() self.class.ajd_to_jd(@ajd, @of)[0] end

  # Get any fractional day part of the date.
  def day_fraction() self.class.ajd_to_jd(@ajd, @of)[1] end

  # Get the date as a Modified Julian Day Number.
  def mjd() self.class.jd_to_mjd(jd) end

  # Get the date as the number of days since the Day of Calendar
  # Reform (in Italy and the Catholic countries).
  def ld() self.class.jd_to_ld(jd) end

  once :jd, :day_fraction, :mjd, :ld

  # Get the date as a Civil Date, [year, month, day_of_month]
  def civil() self.class.jd_to_civil(jd, @sg) end # :nodoc:

  # Get the date as an Ordinal Date, [year, day_of_year]
  def ordinal() self.class.jd_to_ordinal(jd, @sg) end # :nodoc:

  # Get the date as a Commercial Date, [year, week_of_year, day_of_week]
  def commercial() self.class.jd_to_commercial(jd, @sg) end # :nodoc:

  def weeknum0() self.class.__send__(:jd_to_weeknum, jd, 0, @sg) end # :nodoc:
  def weeknum1() self.class.__send__(:jd_to_weeknum, jd, 1, @sg) end # :nodoc:

  once :civil, :ordinal, :commercial, :weeknum0, :weeknum1
  private :civil, :ordinal, :commercial, :weeknum0, :weeknum1

  # Get the year of this date.
  def year() civil[0] end

  # Get the day-of-the-year of this date.
  #
  # January 1 is day-of-the-year 1
  def yday() ordinal[1] end

  # Get the month of this date.
  #
  # January is month 1.
  def mon() civil[1] end

  # Get the day-of-the-month of this date.
  def mday() civil[2] end

  alias_method :month, :mon
  alias_method :day, :mday

  def wnum0() weeknum0[1] end # :nodoc:
  def wnum1() weeknum1[1] end # :nodoc:

  private :wnum0, :wnum1

  # Get the time of this date as [hours, minutes, seconds,
  # fraction_of_a_second]
  def time() self.class.day_fraction_to_time(day_fraction) end # :nodoc:

  once :time
  private :time

  # Get the hour of this date.
  def hour() time[0] end

  # Get the minute of this date.
  def min() time[1] end

  # Get the second of this date.
  def sec() time[2] end

  # Get the fraction-of-a-second of this date.  The unit is in days.
  # I do NOT recommend you to use this method.
  def sec_fraction() time[3] end

=begin
  alias_method :minute, :min
  alias_method :second, :sec
  alias_method :second_fraction, :sec_fraction
=end

  private :hour, :min, :sec, :sec_fraction
#	  :minute, :second, :second_fraction

  def zone() strftime('%:z') end

  private :zone

  # Get the commercial year of this date.  See *Commercial* *Date*
  # in the introduction for how this differs from the normal year.
  def cwyear() commercial[0] end

  # Get the commercial week of the year of this date.
  def cweek() commercial[1] end

  # Get the commercial day of the week of this date.  Monday is
  # commercial day-of-week 1; Sunday is commercial day-of-week 7.
  def cwday() commercial[2] end

  # Get the week day of this date.  Sunday is day-of-week 0;
  # Saturday is day-of-week 6.
  def wday() self.class.jd_to_wday(jd) end

  once :wday

=begin
  MONTHNAMES.each_with_index do |n, i|
    if n
      define_method(n.downcase + '?'){mon == i}
    end
  end

  DAYNAMES.each_with_index do |n, i|
    define_method(n.downcase + '?'){wday == i}
  end
=end

  # Is the current date old-style (Julian Calendar)?
  def julian? () self.class.julian?(jd, @sg) end

  # Is the current date new-style (Gregorian Calendar)?
  def gregorian? () self.class.gregorian?(jd, @sg) end

  once :julian?, :gregorian?

  def fix_style # :nodoc:
    if julian?
    then self.class::JULIAN
    else self.class::GREGORIAN end
  end

  private :fix_style

  # Is this a leap year?
  def leap?
    self.class.jd_to_civil(self.class.civil_to_jd(year, 3, 1, fix_style) - 1,
		     fix_style)[-1] == 29
  end

  once :leap?

  # When is the Day of Calendar Reform for this Date object?
  def start() @sg end

  # Create a copy of this Date object using a new Day of Calendar Reform.
  def new_start(sg=self.class::ITALY) self.class.new!(@ajd, @of, sg) end

  # Create a copy of this Date object that uses the Italian/Catholic
  # Day of Calendar Reform.
  def italy() new_start(self.class::ITALY) end

  # Create a copy of this Date object that uses the English/Colonial
  # Day of Calendar Reform.
  def england() new_start(self.class::ENGLAND) end

  # Create a copy of this Date object that always uses the Julian
  # Calendar.
  def julian() new_start(self.class::JULIAN) end

  # Create a copy of this Date object that always uses the Gregorian
  # Calendar.
  def gregorian() new_start(self.class::GREGORIAN) end

  def offset() @of end

  def new_offset(of=0)
    if String === of
      of = Rational(zone_to_diff(of) || 0, 86400)
    end
    self.class.new!(@ajd, of, @sg)
  end

  private :offset, :new_offset

  # Return a new Date object that is +n+ days later than the
  # current one.
  #
  # +n+ may be a negative value, in which case the new Date
  # is earlier than the current one; however, #-() might be
  # more intuitive.
  #
  # If +n+ is not a Numeric, a TypeError will be thrown.  In
  # particular, two Dates cannot be added to each other.
  def + (n)
    case n
    when Numeric; return self.class.new!(@ajd + n, @of, @sg)
    end
    raise TypeError, 'expected numeric'
  end

  # If +x+ is a Numeric value, create a new Date object that is
  # +x+ days earlier than the current one.
  #
  # If +x+ is a Date, return the number of days between the
  # two dates; or, more precisely, how many days later the current
  # date is than +x+.
  #
  # If +x+ is neither Numeric nor a Date, a TypeError is raised.
  def - (x)
    case x
    when Numeric; return self.class.new!(@ajd - x, @of, @sg)
    when Date;    return @ajd - x.ajd
    end
    raise TypeError, 'expected numeric or date'
  end

  # Compare this date with another date.
  #
  # +other+ can also be a Numeric value, in which case it is
  # interpreted as an Astronomical Julian Day Number.
  #
  # Comparison is by Astronomical Julian Day Number, including
  # fractional days.  This means that both the time and the
  # timezone offset are taken into account when comparing
  # two DateTime instances.  When comparing a DateTime instance
  # with a Date instance, the time of the latter will be
  # considered as falling on midnight UTC.
  def <=> (other)
    case other
    when Numeric; return @ajd <=> other
    when Date;    return @ajd <=> other.ajd
    end
    nil
  end

  # The relationship operator for Date.
  #
  # Compares dates by Julian Day Number.  When comparing
  # two DateTime instances, or a DateTime with a Date,
  # the instances will be regarded as equivalent if they
  # fall on the same date in local time.
  def === (other)
    case other
    when Numeric; return jd == other
    when Date;    return jd == other.jd
    end
    false
  end

  def next_day(n=1) self + n end
# def prev_day(n=1) self - n end

  private :next_day

  # Return a new Date one day after this one.
  def next() next_day end

  alias_method :succ, :next

  # Return a new Date object that is +n+ months later than
  # the current one.
  #
  # If the day-of-the-month of the current Date is greater
  # than the last day of the target month, the day-of-the-month
  # of the returned Date will be the last day of the target month.
  def >> (n)
    y, m = (year * 12 + (mon - 1) + n).divmod(12)
    m,   = (m + 1)                    .divmod(1)
    d = mday
    until jd2 = self.class.valid_civil?(y, m, d, fix_style)
      d -= 1
      raise ArgumentError, 'invalid date' unless d > 0
    end
    self + (jd2 - jd)
  end

  # Return a new Date object that is +n+ months earlier than
  # the current one.
  #
  # If the day-of-the-month of the current Date is greater
  # than the last day of the target month, the day-of-the-month
  # of the returned Date will be the last day of the target month.
  def << (n) self >> -n end

=begin
  def next_month(n=1) self >> n end
  def prev_month(n=1) self << n end

  def next_year(n=1) self >> n * 12 end
  def prev_year(n=1) self << n * 12 end
=end

#  require 'enumerator'

  # Step the current date forward +step+ days at a
  # time (or backward, if +step+ is negative) until
  # we reach +limit+ (inclusive), yielding the resultant
  # date at each step.
  def step(limit, step=1) # :yield: date
=begin
    if step.zero?
      raise ArgumentError, "step can't be 0"
    end
=end
=begin
    unless block_given?
      return to_enum(:step, limit, step)
    end
=end
    da = self
    op = %w(- <= >=)[step <=> 0]
    while da.__send__(op, limit)
      yield da
      da += step
    end
    self
  end

  # Step forward one day at a time until we reach +max+
  # (inclusive), yielding each date as we go.
  def upto(max, &block) # :yield: date
    step(max, +1, &block)
  end

  # Step backward one day at a time until we reach +min+
  # (inclusive), yielding each date as we go.
  def downto(min, &block) # :yield: date
    step(min, -1, &block)
  end

  # Is this Date equal to +other+?
  #
  # +other+ must both be a Date object, and represent the same date.
  def eql? (other) Date === other && self == other end

  # Calculate a hash value for this date.
  def hash() @ajd.hash end

  # Return internal object state as a programmer-readable string.
  def inspect() format('#<%s: %s,%s,%s>', self.class, @ajd, @of, @sg) end

  # Return the date as a human-readable string.
  #
  # The format used is YYYY-MM-DD.
  def to_s() format('%.4d-%02d-%02d', year, mon, mday) end # 4p

  # Dump to Marshal format.
  def _dump(limit) Marshal.dump([@ajd, @of, @sg], -1) end

# def self._load(str) new!(*Marshal.load(str)) end

  # Load from Marshal format.
  def self._load(str)
    a = Marshal.load(str)
    if a.size == 2
      ajd,     sg = a
           of = 0
      ajd -= 1.to_r/2
    else
      ajd, of, sg = a
    end
    new!(ajd, of, sg)
  end

end

# Class representing a date and time.
#
# See the documentation to the file date.rb for an overview.
#
# DateTime objects are immutable once created.
#
# == Other methods.
#
# The following methods are defined in Date, but declared private
# there.  They are made public in DateTime.  They are documented
# here.
#
# === hour()
#
# Get the hour-of-the-day of the time.  This is given
# using the 24-hour clock, counting from midnight.  The first
# hour after midnight is hour 0; the last hour of the day is
# hour 23.
#
# === min()
#
# Get the minute-of-the-hour of the time.
#
# === sec()
#
# Get the second-of-the-minute of the time.
#
# === sec_fraction()
#
# Get the fraction of a second of the time.  This is returned as
# a +Rational+.  The unit is in days.
# I do NOT recommend you to use this method.
#
# === zone()
#
# Get the time zone as a String.  This is representation of the
# time offset such as "+1000", not the true time-zone name.
#
# === offset()
#
# Get the time zone offset as a fraction of a day.  This is returned
# as a +Rational+.
#
# === new_offset(of=0)
#
# Create a new DateTime object, identical to the current one, except
# with a new time zone offset of +of+.  +of+ is the new offset from
# UTC as a fraction of a day.
#
class DateTime < Date

  # Create a new DateTime object corresponding to the specified
  # Julian Day Number +jd+ and hour +h+, minute +min+, second +s+.
  #
  # The 24-hour clock is used.  Negative values of +h+, +min+, and
  # +sec+ are treating as counting backwards from the end of the
  # next larger unit (e.g. a +min+ of -2 is treated as 58).  No
  # wraparound is performed.  If an invalid time portion is specified,
  # an ArgumentError is raised.
  #
  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).
  # +sg+ specifies the Day of Calendar Reform.
  #
  # All day/time values default to 0.
  def self.jd(jd=0, h=0, min=0, s=0, of=0, sg=ITALY)
    unless (jd = valid_jd?(jd, sg)) &&
	   (fr = valid_time?(h, min, s))
      raise ArgumentError, 'invalid date'
    end
    if String === of
      of = Rational(zone_to_diff(of) || 0, 86400)
    end
    new!(jd_to_ajd(jd, fr, of), of, sg)
  end

  # Create a new DateTime object corresponding to the specified
  # Ordinal Date and hour +h+, minute +min+, second +s+.
  #
  # The 24-hour clock is used.  Negative values of +h+, +min+, and
  # +sec+ are treating as counting backwards from the end of the
  # next larger unit (e.g. a +min+ of -2 is treated as 58).  No
  # wraparound is performed.  If an invalid time portion is specified,
  # an ArgumentError is raised.
  #
  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).
  # +sg+ specifies the Day of Calendar Reform.
  #
  # +y+ defaults to -4712, and +d+ to 1; this is Julian Day Number
  # day 0.  The time values default to 0.
  def self.ordinal(y=-4712, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
    unless (jd = valid_ordinal?(y, d, sg)) &&
	   (fr = valid_time?(h, min, s))
      raise ArgumentError, 'invalid date'
    end
    if String === of
      of = Rational(zone_to_diff(of) || 0, 86400)
    end
    new!(jd_to_ajd(jd, fr, of), of, sg)
  end

  # Create a new DateTime object corresponding to the specified
  # Civil Date and hour +h+, minute +min+, second +s+.
  #
  # The 24-hour clock is used.  Negative values of +h+, +min+, and
  # +sec+ are treating as counting backwards from the end of the
  # next larger unit (e.g. a +min+ of -2 is treated as 58).  No
  # wraparound is performed.  If an invalid time portion is specified,
  # an ArgumentError is raised.
  #
  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).
  # +sg+ specifies the Day of Calendar Reform.
  #
  # +y+ defaults to -4712, +m+ to 1, and +d+ to 1; this is Julian Day
  # Number day 0.  The time values default to 0.
  def self.civil(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
    unless (jd = valid_civil?(y, m, d, sg)) &&
	   (fr = valid_time?(h, min, s))
      raise ArgumentError, 'invalid date'
    end
    if String === of
      of = Rational(zone_to_diff(of) || 0, 86400)
    end
    new!(jd_to_ajd(jd, fr, of), of, sg)
  end

  class << self; alias_method :new, :civil end

  # Create a new DateTime object corresponding to the specified
  # Commercial Date and hour +h+, minute +min+, second +s+.
  #
  # The 24-hour clock is used.  Negative values of +h+, +min+, and
  # +sec+ are treating as counting backwards from the end of the
  # next larger unit (e.g. a +min+ of -2 is treated as 58).  No
  # wraparound is performed.  If an invalid time portion is specified,
  # an ArgumentError is raised.
  #
  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).
  # +sg+ specifies the Day of Calendar Reform.
  #
  # +y+ defaults to 1582, +w+ to 41, and +d+ to 5; this is the Day of
  # Calendar Reform for Italy and the Catholic countries.
  # The time values default to 0.
  def self.commercial(y=1582, w=41, d=5, h=0, min=0, s=0, of=0, sg=ITALY)
    unless (jd = valid_commercial?(y, w, d, sg)) &&
	   (fr = valid_time?(h, min, s))
      raise ArgumentError, 'invalid date'
    end
    if String === of
      of = Rational(zone_to_diff(of) || 0, 86400)
    end
    new!(jd_to_ajd(jd, fr, of), of, sg)
  end

  def self.weeknum(y=1582, w=41, d=5, f=0, h=0, min=0, s=0, of=0, sg=ITALY) # :nodoc:
    unless (jd = valid_weeknum?(y, w, d, f, sg)) &&
	   (fr = valid_time?(h, min, s))
      raise ArgumentError, 'invalid date'
    end
    if String === of
      of = Rational(zone_to_diff(of) || 0, 86400)
    end
    new!(jd_to_ajd(jd, fr, of), of, sg)
  end

  private_class_method :weeknum

  def self.new_by_frags(elem, sg) # :nodoc:
    elem = rewrite_frags(elem)
    elem = complete_frags(elem)
    unless (jd = valid_date_frags?(elem, sg)) &&
	   (fr = valid_time_frags?(elem))
      raise ArgumentError, 'invalid date'
    end
    fr += (elem[:sec_fraction] || 0) / 86400
    of = Rational(elem[:offset] || 0, 86400)
    new!(jd_to_ajd(jd, fr, of), of, sg)
  end

  private_class_method :new_by_frags

  # Create a new DateTime object by parsing from a String
  # according to a specified format.
  #
  # +str+ is a String holding a date-time representation.
  # +fmt+ is the format that the date-time is in.  See
  # date/format.rb for details on supported formats.
  #
  # The default +str+ is '-4712-01-01T00:00:00+00:00', and the default
  # +fmt+ is '%FT%T%z'.  This gives midnight on Julian Day Number day 0.
  #
  # +sg+ specifies the Day of Calendar Reform.
  #
  # An ArgumentError will be raised if +str+ cannot be
  # parsed.
  def self.strptime(str='-4712-01-01T00:00:00+00:00', fmt='%FT%T%z', sg=ITALY)
    elem = _strptime(str, fmt)
    new_by_frags(elem, sg)
  end

  # Create a new DateTime object by parsing from a String,
  # without specifying the format.
  #
  # +str+ is a String holding a date-time representation.
  # +comp+ specifies whether to interpret 2-digit years
  # as 19XX (>= 69) or 20XX (< 69); the default is not to.
  # The method will attempt to parse a date-time from the String
  # using various heuristics; see #_parse in date/format.rb
  # for more details.  If parsing fails, an ArgumentError
  # will be raised.
  #
  # The default +str+ is '-4712-01-01T00:00:00+00:00'; this is Julian
  # Day Number day 0.
  #
  # +sg+ specifies the Day of Calendar Reform.
  def self.parse(str='-4712-01-01T00:00:00+00:00', comp=false, sg=ITALY)
    elem = _parse(str, comp)
    new_by_frags(elem, sg)
  end

  public :hour, :min, :sec, :sec_fraction, :zone, :offset, :new_offset
#	 :minute, :second, :second_fraction

  def to_s # 4p
    format('%.4d-%02d-%02dT%02d:%02d:%02d%s',
	   year, mon, mday, hour, min, sec, zone)
  end

end

class Time

#  def to_time() getlocal end

  def to_date
    jd = Date.civil_to_jd(year, mon, mday, Date::ITALY)
    Date.new!(Date.jd_to_ajd(jd, 0, 0), 0, Date::ITALY)
  end

  def to_datetime
    jd = DateTime.civil_to_jd(year, mon, mday, DateTime::ITALY)
    fr = DateTime.time_to_day_fraction(hour, min, [sec, 59].min) +
      Rational(usec, 86400_000_000)
    of = Rational(utc_offset, 86400)
    DateTime.new!(DateTime.jd_to_ajd(jd, fr, of), of, DateTime::ITALY)
  end

  private :to_date, :to_datetime

end

class Date

=begin
  def to_time() Time.local(year, mon, mday) end
  def to_date() self end
  def to_datetime() DateTime.new!(self.class.jd_to_ajd(jd, 0, 0), @of, @sg) end
=end

  # Create a new Date object representing today.
  #
  # +sg+ specifies the Day of Calendar Reform.
  def self.today(sg=ITALY)
    t = Time.now
    jd = civil_to_jd(t.year, t.mon, t.mday, sg)
    new!(jd_to_ajd(jd, 0, 0), 0, sg)
  end

  # Create a new DateTime object representing the current time.
  #
  # +sg+ specifies the Day of Calendar Reform.
  def self.now(sg=ITALY)
    t = Time.now
    jd = civil_to_jd(t.year, t.mon, t.mday, sg)
    fr = time_to_day_fraction(t.hour, t.min, [t.sec, 59].min) +
      Rational(t.usec, 86400_000_000)
    of = Rational(t.utc_offset, 86400)
    new!(jd_to_ajd(jd, fr, of), of, sg)
  end

  private_class_method :now

end

class DateTime < Date

=begin
  def to_time
    d = new_offset(0)
    d.instance_eval do
      Time.utc(year, mon, mday, hour, min, sec,
	       (sec_fraction * 86400000000).to_i)
    end.
	getlocal
  end

  def to_date() Date.new!(self.class.jd_to_ajd(jd, 0, 0), 0, @sg) end
  def to_datetime() self end
=end

  private_class_method :today
  public_class_method  :now

end

class Date

  class << self

    def deprecated_class_method_alias(old, new) # :nodoc:
      module_eval <<-"end;"
	class << self
	  def #{old}(*args, &block)
	    if $VERBOSE
	      warn("\#{caller.shift.sub(/:in .*/, '')}: " \
		   "warning: \#{self}::#{old} is deprecated; " \
		   "use \#{self}::#{new}")
	    end
	    #{new}(*args, &block)
	  end
	end
      end;
    end

    private :deprecated_class_method_alias

    def deprecated_alias(old, new) # :nodoc:
      module_eval <<-"end;"
	def #{old}(*args, &block)
	  if $VERBOSE
	    warn("\#{caller.shift.sub(/:in .*/, '')}: " \
		 "warning: \#{self.class}\##{old} is deprecated; " \
		 "use \#{self.class}\##{new}")
	  end
	  #{new}(*args, &block)
	end
      end;
    end

    private :deprecated_alias

  end

  [ %w(os?	julian?),
    %w(ns?	gregorian?),
    %w(exist1?	valid_jd?),
    %w(exist2?	valid_ordinal?),
    %w(exist3?	valid_date?),
    %w(exist?	valid_date?),
    %w(existw?	valid_commercial?),
    %w(new0	new!),
    %w(new1	jd),
    %w(new2	ordinal),
    %w(new3	new),
    %w(neww	commercial)
  ].each do |old, new|
    deprecated_class_method_alias(old, new)
  end

  [ %w(os?	julian?),
    %w(ns?	gregorian?),
    %w(sg	start),
    %w(newsg	new_start),
    %w(of	offset),
    %w(newof	new_offset)
  ].each do |old, new|
    deprecated_alias(old, new)
  end

  private :of, :newof

end

class DateTime < Date

  public :of, :newof

end
PK     Y\+0    
  timeout.rbnu [        #--
# = timeout.rb
#
# execution timeout
#
# = Copyright
#
# Copyright:: (C) 2000  Network Applied Communication Laboratory, Inc.
# Copyright:: (C) 2000  Information-technology Promotion Agency, Japan
#
#++
#
# = Description
#
# A way of performing a potentially long-running operation in a thread, and
# terminating it's execution if it hasn't finished within fixed amount of
# time.
#
# Previous versions of timeout didn't use a module for namespace. This version
# provides both Timeout.timeout, and a backwards-compatible #timeout.
#
# = Synopsis
#
#   require 'timeout'
#   status = Timeout::timeout(5) {
#     # Something that should be interrupted if it takes too much time...
#   }
#

module Timeout

  ##
  # Raised by Timeout#timeout when the block times out.

  class Error < Interrupt
  end
  class ExitException < ::Exception # :nodoc:
  end

  THIS_FILE = /\A#{Regexp.quote(__FILE__)}:/o
  CALLER_OFFSET = ((c = caller[0]) && THIS_FILE =~ c) ? 1 : 0

  ##
  # Executes the method's block. If the block execution terminates before +sec+
  # seconds has passed, it returns true. If not, it terminates the execution
  # and raises +exception+ (which defaults to Timeout::Error).
  #
  # Note that this is both a method of module Timeout, so you can 'include
  # Timeout' into your classes so they have a #timeout method, as well as a
  # module method, so you can call it directly as Timeout.timeout().

  def timeout(sec, klass = nil)
    return yield if sec == nil or sec.zero?
    raise ThreadError, "timeout within critical session" if Thread.critical
    exception = klass || Class.new(ExitException)
    begin
      x = Thread.current
      y = Thread.start {
        begin
          sleep sec
        rescue => e
          x.raise e
        else
          x.raise exception, "execution expired" if x.alive?
        end
      }
      yield sec
      #    return true
    rescue exception => e
      rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/o
      (bt = e.backtrace).reject! {|m| rej =~ m}
      level = -caller(CALLER_OFFSET).size
      while THIS_FILE =~ bt[level]
        bt.delete_at(level)
        level += 1
      end
      raise if klass            # if exception class is specified, it
                                # would be expected outside.
      raise Error, e.message, e.backtrace
    ensure
      if y and y.alive?
        y.kill
        y.join # make sure y is dead.
      end
    end
  end

  module_function :timeout

end

##
# Identical to:
#
#   Timeout::timeout(n, e, &block).
#
# Defined for backwards compatibility with earlier versions of timeout.rb, see
# Timeout#timeout.

def timeout(n, e = nil, &block) # :nodoc:
  Timeout::timeout(n, e, &block)
end

##
# Another name for Timeout::Error, defined for backwards compatibility with
# earlier versions of timeout.rb.

TimeoutError = Timeout::Error # :nodoc:

if __FILE__ == $0
  p timeout(5) {
    45
  }
  p timeout(5, TimeoutError) {
    45
  }
  p timeout(nil) {
    54
  }
  p timeout(0) {
    54
  }
  p timeout(5) {
    loop {
      p 10
      sleep 1
    }
  }
end

PK     Y\g~^Z  Z    runit/testresult.rbnu [        # Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit/testresult'

module RUNIT
  class TestResult < Test::Unit::TestResult
    attr_reader(:errors, :failures)
    def succeed?
      return passed?
    end
    def failure_size
      return failure_count
    end
    def run_asserts
      return assertion_count
    end
    def error_size
      return error_count
    end
    def run_tests
      return run_count
    end
    def add_failure(failure)
      def failure.at
        return location
      end
      def failure.err
        return message
      end
      super(failure)
    end
    def add_error(error)
      def error.at
        return location
      end
      def error.err
        return exception
      end
      super(error)
    end
  end
end
PK     Y\?W      runit/cui/testrunner.rbnu [        # Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit/ui/console/testrunner'
require 'runit/testresult'

module RUNIT
  module CUI
    class TestRunner < Test::Unit::UI::Console::TestRunner
      @@quiet_mode = false
      
      def self.run(suite)
        self.new().run(suite)
      end
      
      def initialize
        super nil
      end
      
      def run(suite, quiet_mode=@@quiet_mode)
        @suite = suite
        def @suite.suite
          self
        end
        @output_level = (quiet_mode ? Test::Unit::UI::PROGRESS_ONLY : Test::Unit::UI::VERBOSE)
        start
      end
      
      def create_mediator(suite)
        mediator = Test::Unit::UI::TestRunnerMediator.new(suite)
        class << mediator
          attr_writer :result_delegate
          def create_result
            return @result_delegate.create_result
          end
        end
        mediator.result_delegate = self
        return mediator
      end
      
      def create_result
        return RUNIT::TestResult.new
      end
      
      def self.quiet_mode=(boolean)
        @@quiet_mode = boolean
      end
    end
  end
end
PK     Y\>@/  /    runit/assert.rbnu [        # Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit/assertions'
require 'runit/error'

module RUNIT
  module Assert
    include Test::Unit::Assertions

    def setup_assert
    end

    def assert_no_exception(*args, &block)
      assert_nothing_raised(*args, &block)
    end

    # To deal with the fact that RubyUnit does not check that the
    # regular expression is, indeed, a regular expression, if it is
    # not, we do our own assertion using the same semantics as
    # RubyUnit
    def assert_match(actual_string, expected_re, message="")
      _wrap_assertion {
        full_message = build_message(message, "Expected <?> to match <?>", actual_string, expected_re)
        assert_block(full_message) {
          expected_re =~ actual_string
        }
        Regexp.last_match
      }
    end

    def assert_not_nil(actual, message="")
      assert(!actual.nil?, message)
    end

    def assert_not_match(actual_string, expected_re, message="")
      assert_no_match(expected_re, actual_string, message)
    end

    def assert_matches(*args)
      assert_match(*args)
    end

    def assert_fail(message="")
      flunk(message)
    end

    def assert_equal_float(expected, actual, delta, message="")
      assert_in_delta(expected, actual, delta, message)
    end

    def assert_send(object, method, *args)
      super([object, method, *args])
    end

    def assert_exception(exception, message="", &block)
      assert_raises(exception, message, &block)
    end

    def assert_respond_to(method, object, message="")
      if (called_internally?)
        super
      else
        super(object, method, message)
      end
    end

    def called_internally?
      /assertions\.rb/.match(caller[1])
    end
  end
end
PK     Y\Ϋa        runit/topublic.rbnu [        # Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

module RUNIT
  module ToPublic
  end
end
PK     Y\0       runit/testcase.rbnu [        # Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'runit/testresult'
require 'runit/testsuite'
require 'runit/assert'
require 'runit/error'
require 'test/unit/testcase'

module RUNIT
  class TestCase < Test::Unit::TestCase  
    include RUNIT::Assert
    
    def self.suite
      method_names = instance_methods(true)
      tests = method_names.delete_if { |method_name| method_name !~ /^test/ }
      suite = TestSuite.new(name)
      tests.each {
        |test|
        catch(:invalid_test) {
          suite << new(test, name)
        }
      }
      return suite
    end
    
    def initialize(test_name, suite_name=self.class.name)
      super(test_name)
    end
    
    def assert_equals(*args)
      assert_equal(*args)
    end
    
    def name
      super.sub(/^(.*?)\((.*)\)$/, '\2#\1')
    end
    
    def run(result, &progress_block)
      progress_block = proc {} unless (block_given?)
      super(result, &progress_block)
    end
  end
end
PK     Y\2'L      runit/testsuite.rbnu [        # Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit/testsuite'

module RUNIT
  class TestSuite < Test::Unit::TestSuite
    def add_test(*args)
      add(*args)
    end
    
    def add(*args)
      self.<<(*args)
    end
    
    def count_test_cases
      return size
    end
    
    def run(result, &progress_block)
      progress_block = proc {} unless (block_given?)
      super(result, &progress_block)
    end
  end
end
PK      Z\}3$        runit/error.rbnu [        # Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit/assertionfailederror.rb'

module RUNIT
  AssertionFailedError = Test::Unit::AssertionFailedError
end
PK      Z\H~qd  d    open3.rbnu [        #
# = open3.rb: Popen, but with stderr, too
#
# Author:: Yukihiro Matsumoto
# Documentation:: Konrad Meyer
#
# Open3 gives you access to stdin, stdout, and stderr when running other
# programs.
#

#
# Open3 grants you access to stdin, stdout, and stderr when running another
# program. Example:
#
#   require "open3"
#   include Open3
#   
#   stdin, stdout, stderr = popen3('nroff -man')
#
# Open3.popen3 can also take a block which will receive stdin, stdout and
# stderr as parameters.  This ensures stdin, stdout and stderr are closed
# once the block exits. Example:
#
#   require "open3"
#
#   Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }
#

module Open3
  # 
  # Open stdin, stdout, and stderr streams and start external executable.
  # Non-block form:
  #   
  #   require 'open3'
  #
  #   stdin, stdout, stderr = Open3.popen3(cmd)
  #
  # Block form:
  #
  #   require 'open3'
  #
  #   Open3.popen3(cmd) { |stdin, stdout, stderr| ... }
  #
  # The parameter +cmd+ is passed directly to Kernel#exec.
  #
  # _popen3_ is like _system_ in that you can pass extra parameters, and the
  # strings won't be mangled by shell expansion.
  #
  #   stdin, stdout, stderr = Open3.popen3('identify', '/weird path/with spaces/and "strange" characters.jpg')
  #   result = stdout.read
  #
  def popen3(*cmd)
    pw = IO::pipe   # pipe[0] for read, pipe[1] for write
    pr = IO::pipe
    pe = IO::pipe

    pid = fork{
      # child
      fork{
	# grandchild
	pw[1].close
	STDIN.reopen(pw[0])
	pw[0].close

	pr[0].close
	STDOUT.reopen(pr[1])
	pr[1].close

	pe[0].close
	STDERR.reopen(pe[1])
	pe[1].close

	exec(*cmd)
      }
      exit!(0)
    }

    pw[0].close
    pr[1].close
    pe[1].close
    Process.waitpid(pid)
    pi = [pw[1], pr[0], pe[0]]
    pw[1].sync = true
    if defined? yield
      begin
	return yield(*pi)
      ensure
	pi.each{|p| p.close unless p.closed?}
      end
    end
    pi
  end
  module_function :popen3
end

if $0 == __FILE__
  a = Open3.popen3("nroff -man")
  Thread.start do
    while line = gets
      a[0].print line
    end
    a[0].close
  end
  while line = a[1].gets
    print ":", line
  end
end
PK      Z\}        date2.rbnu [        # date2 was overridden by date.
# To be precise, date was overridden by date2,
# and date2 was renamed to date.

require 'date'
PK      Z\=RnpR  pR    debug.rbnu [        # Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
# Copyright (C) 2000  Information-technology Promotion Agency, Japan
# Copyright (C) 2000-2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>

if $SAFE > 0
  STDERR.print "-r debug.rb is not available in safe mode\n"
  exit 1
end

require 'tracer'
require 'pp'

class Tracer
  def Tracer.trace_func(*vars)
    Single.trace_func(*vars)
  end
end

SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__

class DEBUGGER__
class Mutex
  def initialize
    @locker = nil
    @waiting = []
    @locked = false;
  end

  def locked?
    @locked
  end

  def lock
    return if Thread.critical
    return if @locker == Thread.current
    while (Thread.critical = true; @locked)
      @waiting.push Thread.current
      Thread.stop
    end
    @locked = true
    @locker = Thread.current
    Thread.critical = false
    self
  end

  def unlock
    return if Thread.critical
    return unless @locked
    unless @locker == Thread.current
      raise RuntimeError, "unlocked by other"
    end
    Thread.critical = true
    t = @waiting.shift
    @locked = false
    @locker = nil
    Thread.critical = false
    t.run if t
    self
  end
end
MUTEX = Mutex.new

class Context
  DEBUG_LAST_CMD = []

  begin
    require 'readline'
    def readline(prompt, hist)
      Readline::readline(prompt, hist)
    end
  rescue LoadError
    def readline(prompt, hist)
      STDOUT.print prompt
      STDOUT.flush
      line = STDIN.gets
      exit unless line
      line.chomp!
      line
    end
    USE_READLINE = false
  end

  def initialize
    if Thread.current == Thread.main
      @stop_next = 1
    else
      @stop_next = 0
    end
    @last_file = nil
    @file = nil
    @line = nil
    @no_step = nil
    @frames = []
    @finish_pos = 0
    @trace = false
    @catch = "StandardError"
    @suspend_next = false
  end

  def stop_next(n=1)
    @stop_next = n
  end

  def set_suspend
    @suspend_next = true
  end

  def clear_suspend
    @suspend_next = false
  end

  def suspend_all
    DEBUGGER__.suspend
  end

  def resume_all
    DEBUGGER__.resume
  end

  def check_suspend
    return if Thread.critical
    while (Thread.critical = true; @suspend_next)
      DEBUGGER__.waiting.push Thread.current
      @suspend_next = false
      Thread.stop
    end
    Thread.critical = false
  end

  def trace?
    @trace
  end

  def set_trace(arg)
    @trace = arg
  end

  def stdout
    DEBUGGER__.stdout
  end

  def break_points
    DEBUGGER__.break_points
  end

  def display
    DEBUGGER__.display
  end

  def context(th)
    DEBUGGER__.context(th)
  end

  def set_trace_all(arg)
    DEBUGGER__.set_trace(arg)
  end

  def set_last_thread(th)
    DEBUGGER__.set_last_thread(th)
  end

  def debug_eval(str, binding)
    begin
      val = eval(str, binding)
    rescue StandardError, ScriptError => e
      at = eval("caller(1)", binding)
      stdout.printf "%s:%s\n", at.shift, e.to_s.sub(/\(eval\):1:(in `.*?':)?/, '')
      for i in at
	stdout.printf "\tfrom %s\n", i
      end
      throw :debug_error
    end
  end

  def debug_silent_eval(str, binding)
    begin
      eval(str, binding)
    rescue StandardError, ScriptError
      nil
    end
  end

  def var_list(ary, binding)
    ary.sort!
    for v in ary
      stdout.printf "  %s => %s\n", v, eval(v, binding).inspect
    end
  end

  def debug_variable_info(input, binding)
    case input
    when /^\s*g(?:lobal)?\s*$/
      var_list(global_variables, binding)

    when /^\s*l(?:ocal)?\s*$/
      var_list(eval("local_variables", binding), binding)

    when /^\s*i(?:nstance)?\s+/
      obj = debug_eval($', binding)
      var_list(obj.instance_variables, obj.instance_eval{binding()})

    when /^\s*c(?:onst(?:ant)?)?\s+/
      obj = debug_eval($', binding)
      unless obj.kind_of? Module
	stdout.print "Should be Class/Module: ", $', "\n"
      else
	var_list(obj.constants, obj.module_eval{binding()})
      end
    end
  end

  def debug_method_info(input, binding)
    case input
    when /^i(:?nstance)?\s+/
      obj = debug_eval($', binding)

      len = 0
      for v in obj.methods.sort
	len += v.size + 1
	if len > 70
	  len = v.size + 1
	  stdout.print "\n"
	end
	stdout.print v, " "
      end
      stdout.print "\n"

    else
      obj = debug_eval(input, binding)
      unless obj.kind_of? Module
	stdout.print "Should be Class/Module: ", input, "\n"
      else
	len = 0
	for v in obj.instance_methods(false).sort
	  len += v.size + 1
	  if len > 70
	    len = v.size + 1
	    stdout.print "\n"
	  end
	  stdout.print v, " "
	end
	stdout.print "\n"
      end
    end
  end

  def thnum
    num = DEBUGGER__.instance_eval{@thread_list[Thread.current]}
    unless num
      DEBUGGER__.make_thread_list
      num = DEBUGGER__.instance_eval{@thread_list[Thread.current]}
    end
    num
  end

  def debug_command(file, line, id, binding)
    MUTEX.lock
    unless defined?($debugger_restart) and $debugger_restart
      callcc{|c| $debugger_restart = c} 
    end
    set_last_thread(Thread.current)
    frame_pos = 0
    binding_file = file
    binding_line = line
    previous_line = nil
    if ENV['EMACS']
      stdout.printf "\032\032%s:%d:\n", binding_file, binding_line
    else
      stdout.printf "%s:%d:%s", binding_file, binding_line,
	line_at(binding_file, binding_line)
    end
    @frames[0] = [binding, file, line, id]
    display_expressions(binding)
    prompt = true
    while prompt and input = readline("(rdb:%d) "%thnum(), true)
      catch(:debug_error) do
	if input == ""
          next unless DEBUG_LAST_CMD[0]
	  input = DEBUG_LAST_CMD[0]
	  stdout.print input, "\n"
	else
	  DEBUG_LAST_CMD[0] = input
	end

	case input
	when /^\s*tr(?:ace)?(?:\s+(on|off))?(?:\s+(all))?$/
          if defined?( $2 )
            if $1 == 'on'
              set_trace_all true
            else
              set_trace_all false
            end
          elsif defined?( $1 )
            if $1 == 'on'
              set_trace true
            else
              set_trace false
            end
          end
          if trace?
            stdout.print "Trace on.\n"
          else
            stdout.print "Trace off.\n"
          end

	when /^\s*b(?:reak)?\s+(?:(.+):)?([^.:]+)$/
	  pos = $2
          if $1
            klass = debug_silent_eval($1, binding)
            file = $1
          end
	  if pos =~ /^\d+$/
	    pname = pos
	    pos = pos.to_i
	  else
	    pname = pos = pos.intern.id2name
	  end
	  break_points.push [true, 0, klass || file, pos]
	  stdout.printf "Set breakpoint %d at %s:%s\n", break_points.size, klass || file, pname

	when /^\s*b(?:reak)?\s+(.+)[#.]([^.:]+)$/
	  pos = $2.intern.id2name
	  klass = debug_eval($1, binding)
	  break_points.push [true, 0, klass, pos]
	  stdout.printf "Set breakpoint %d at %s.%s\n", break_points.size, klass, pos

	when /^\s*wat(?:ch)?\s+(.+)$/
	  exp = $1
	  break_points.push [true, 1, exp]
	  stdout.printf "Set watchpoint %d:%s\n", break_points.size, exp

	when /^\s*b(?:reak)?$/
	  if break_points.find{|b| b[1] == 0}
	    n = 1
	    stdout.print "Breakpoints:\n"
	    for b in break_points
	      if b[0] and b[1] == 0
		stdout.printf "  %d %s:%s\n", n, b[2], b[3] 
	      end
	      n += 1
	    end
	  end
	  if break_points.find{|b| b[1] == 1}
	    n = 1
	    stdout.print "\n"
	    stdout.print "Watchpoints:\n"
	    for b in break_points
	      if b[0] and b[1] == 1
		stdout.printf "  %d %s\n", n, b[2]
	      end
	      n += 1
	    end
	  end
	  if break_points.size == 0
	    stdout.print "No breakpoints\n"
	  else
	    stdout.print "\n"
	  end

	when /^\s*del(?:ete)?(?:\s+(\d+))?$/
	  pos = $1
	  unless pos
	    input = readline("Clear all breakpoints? (y/n) ", false)
	    if input == "y"
	      for b in break_points
		b[0] = false
	      end
	    end
	  else
	    pos = pos.to_i
	    if break_points[pos-1]
	      break_points[pos-1][0] = false
	    else
	      stdout.printf "Breakpoint %d is not defined\n", pos
	    end
	  end

	when /^\s*disp(?:lay)?\s+(.+)$/
	  exp = $1
	  display.push [true, exp]
	  stdout.printf "%d: ", display.size
	  display_expression(exp, binding)

	when /^\s*disp(?:lay)?$/
	  display_expressions(binding)

	when /^\s*undisp(?:lay)?(?:\s+(\d+))?$/
	  pos = $1
	  unless pos
	    input = readline("Clear all expressions? (y/n) ", false)
	    if input == "y"
	      for d in display
		d[0] = false
	      end
	    end
	  else
	    pos = pos.to_i
	    if display[pos-1]
	      display[pos-1][0] = false
	    else
	      stdout.printf "Display expression %d is not defined\n", pos
	    end
	  end

	when /^\s*c(?:ont)?$/
	  prompt = false

	when /^\s*s(?:tep)?(?:\s+(\d+))?$/
	  if $1
	    lev = $1.to_i
	  else
	    lev = 1
	  end
	  @stop_next = lev
	  prompt = false

	when /^\s*n(?:ext)?(?:\s+(\d+))?$/
	  if $1
	    lev = $1.to_i
	  else
	    lev = 1
	  end
	  @stop_next = lev
	  @no_step = @frames.size - frame_pos
	  prompt = false

	when /^\s*w(?:here)?$/, /^\s*f(?:rame)?$/
	  display_frames(frame_pos)

	when /^\s*l(?:ist)?(?:\s+(.+))?$/
	  if not $1
	    b = previous_line ? previous_line + 10 : binding_line - 5
	    e = b + 9
	  elsif $1 == '-'
	    b = previous_line ? previous_line - 10 : binding_line - 5
	    e = b + 9
	  else
	    b, e = $1.split(/[-,]/)
	    if e
	      b = b.to_i
	      e = e.to_i
	    else
	      b = b.to_i - 5
	      e = b + 9
	    end
	  end
	  previous_line = b
	  display_list(b, e, binding_file, binding_line)

	when /^\s*up(?:\s+(\d+))?$/
	  previous_line = nil
	  if $1
	    lev = $1.to_i
	  else
	    lev = 1
	  end
	  frame_pos += lev
	  if frame_pos >= @frames.size
	    frame_pos = @frames.size - 1
	    stdout.print "At toplevel\n"
	  end
	  binding, binding_file, binding_line = @frames[frame_pos]
	  stdout.print format_frame(frame_pos)

	when /^\s*down(?:\s+(\d+))?$/
	  previous_line = nil
	  if $1
	    lev = $1.to_i
	  else
	    lev = 1
	  end
	  frame_pos -= lev
	  if frame_pos < 0
	    frame_pos = 0
	    stdout.print "At stack bottom\n"
	  end
	  binding, binding_file, binding_line = @frames[frame_pos]
	  stdout.print format_frame(frame_pos)

	when /^\s*fin(?:ish)?$/
	  if frame_pos == @frames.size
	    stdout.print "\"finish\" not meaningful in the outermost frame.\n"
	  else
	    @finish_pos = @frames.size - frame_pos
	    frame_pos = 0
	    prompt = false
	  end

	when /^\s*cat(?:ch)?(?:\s+(.+))?$/
	  if $1
	    excn = $1
	    if excn == 'off'
	      @catch = nil
	      stdout.print "Clear catchpoint.\n"
	    else
	      @catch = excn
	      stdout.printf "Set catchpoint %s.\n", @catch
	    end
	  else
	    if @catch
	      stdout.printf "Catchpoint %s.\n", @catch
	    else
	      stdout.print "No catchpoint.\n"
	    end
	  end

	when /^\s*q(?:uit)?$/
	  input = readline("Really quit? (y/n) ", false)
	  if input == "y"
	    exit!	# exit -> exit!: No graceful way to stop threads...
	  end

	when /^\s*v(?:ar)?\s+/
	  debug_variable_info($', binding)

	when /^\s*m(?:ethod)?\s+/
	  debug_method_info($', binding)

	when /^\s*th(?:read)?\s+/
	  if DEBUGGER__.debug_thread_info($', binding) == :cont
	    prompt = false
	  end

	when /^\s*pp\s+/
	  PP.pp(debug_eval($', binding), stdout)

	when /^\s*p\s+/
	  stdout.printf "%s\n", debug_eval($', binding).inspect

	when /^\s*r(?:estart)?$/
          $debugger_restart.call

	when /^\s*h(?:elp)?$/
	  debug_print_help()

	else
	  v = debug_eval(input, binding)
	  stdout.printf "%s\n", v.inspect
	end
      end
    end
    MUTEX.unlock
    resume_all
  end

  def debug_print_help
    stdout.print <<EOHELP
Debugger help v.-0.002b
Commands
  b[reak] [file:|class:]<line|method>
  b[reak] [class.]<line|method>
                             set breakpoint to some position
  wat[ch] <expression>       set watchpoint to some expression
  cat[ch] (<exception>|off)  set catchpoint to an exception
  b[reak]                    list breakpoints
  cat[ch]                    show catchpoint
  del[ete][ nnn]             delete some or all breakpoints
  disp[lay] <expression>     add expression into display expression list
  undisp[lay][ nnn]          delete one particular or all display expressions
  c[ont]                     run until program ends or hit breakpoint
  s[tep][ nnn]               step (into methods) one line or till line nnn
  n[ext][ nnn]               go over one line or till line nnn
  w[here]                    display frames
  f[rame]                    alias for where
  l[ist][ (-|nn-mm)]         list program, - lists backwards
                             nn-mm lists given lines
  up[ nn]                    move to higher frame
  down[ nn]                  move to lower frame
  fin[ish]                   return to outer frame
  tr[ace] (on|off)           set trace mode of current thread
  tr[ace] (on|off) all       set trace mode of all threads
  q[uit]                     exit from debugger
  v[ar] g[lobal]             show global variables
  v[ar] l[ocal]              show local variables
  v[ar] i[nstance] <object>  show instance variables of object
  v[ar] c[onst] <object>     show constants of object
  m[ethod] i[nstance] <obj>  show methods of object
  m[ethod] <class|module>    show instance methods of class or module
  th[read] l[ist]            list all threads
  th[read] c[ur[rent]]       show current thread
  th[read] [sw[itch]] <nnn>  switch thread context to nnn
  th[read] stop <nnn>        stop thread nnn
  th[read] resume <nnn>      resume thread nnn
  p expression               evaluate expression and print its value
  h[elp]                     print this help
  <everything else>          evaluate
EOHELP
  end

  def display_expressions(binding)
    n = 1
    for d in display
      if d[0]
	stdout.printf "%d: ", n
	display_expression(d[1], binding)
      end
      n += 1
    end
  end

  def display_expression(exp, binding)
    stdout.printf "%s = %s\n", exp, debug_silent_eval(exp, binding).to_s
  end

  def frame_set_pos(file, line)
    if @frames[0]
      @frames[0][1] = file
      @frames[0][2] = line
    end
  end

  def display_frames(pos)
    0.upto(@frames.size - 1) do |n|
      if n == pos
	stdout.print "--> "
      else
	stdout.print "    "
      end
      stdout.print format_frame(n)
    end
  end

  def format_frame(pos)
    bind, file, line, id = @frames[pos]
    sprintf "#%d %s:%s%s\n", pos + 1, file, line,
      (id ? ":in `#{id.id2name}'" : "")
  end

  def display_list(b, e, file, line)
    stdout.printf "[%d, %d] in %s\n", b, e, file
    if lines = SCRIPT_LINES__[file] and lines != true
      n = 0
      b.upto(e) do |n|
	if n > 0 && lines[n-1]
	  if n == line
	    stdout.printf "=> %d  %s\n", n, lines[n-1].chomp
	  else
	    stdout.printf "   %d  %s\n", n, lines[n-1].chomp
	  end
	end
      end
    else
      stdout.printf "No sourcefile available for %s\n", file
    end
  end

  def line_at(file, line)
    lines = SCRIPT_LINES__[file]
    if lines
      return "\n" if lines == true
      line = lines[line-1]
      return "\n" unless line
      return line
    end
    return "\n"
  end

  def debug_funcname(id)
    if id.nil?
      "toplevel"
    else
      id.id2name
    end
  end

  def check_break_points(file, klass, pos, binding, id)
    return false if break_points.empty?
    n = 1
    for b in break_points
      if b[0]		# valid
	if b[1] == 0	# breakpoint
	  if (b[2] == file and b[3] == pos) or
	      (klass and b[2] == klass and b[3] == pos)
	    stdout.printf "Breakpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos
	    return true
	  end
	elsif b[1] == 1	# watchpoint
	  if debug_silent_eval(b[2], binding)
	    stdout.printf "Watchpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos
	    return true
	  end
	end
      end
      n += 1
    end
    return false
  end

  def excn_handle(file, line, id, binding)
    if $!.class <= SystemExit
      set_trace_func nil
      exit
    end

    if @catch and ($!.class.ancestors.find { |e| e.to_s == @catch })
      stdout.printf "%s:%d: `%s' (%s)\n", file, line, $!, $!.class
      fs = @frames.size
      tb = caller(0)[-fs..-1]
      if tb
	for i in tb
	  stdout.printf "\tfrom %s\n", i
	end
      end
      suspend_all
      debug_command(file, line, id, binding)
    end
  end

  def trace_func(event, file, line, id, binding, klass)
    Tracer.trace_func(event, file, line, id, binding, klass) if trace?
    context(Thread.current).check_suspend
    @file = file
    @line = line
    case event
    when 'line'
      frame_set_pos(file, line)
      if !@no_step or @frames.size == @no_step
	@stop_next -= 1
	@stop_next = -1 if @stop_next < 0
      elsif @frames.size < @no_step
	@stop_next = 0		# break here before leaving...
      else
	# nothing to do. skipped.
      end
      if @stop_next == 0 or check_break_points(file, nil, line, binding, id)
	@no_step = nil
	suspend_all
	debug_command(file, line, id, binding)
      end

    when 'call'
      @frames.unshift [binding, file, line, id]
      if check_break_points(file, klass, id.id2name, binding, id)
	suspend_all
	debug_command(file, line, id, binding)
      end

    when 'c-call'
      frame_set_pos(file, line)

    when 'class'
      @frames.unshift [binding, file, line, id]

    when 'return', 'end'
      if @frames.size == @finish_pos
	@stop_next = 1
	@finish_pos = 0
      end
      @frames.shift

    when 'end'
      @frames.shift

    when 'raise' 
      excn_handle(file, line, id, binding)

    end
    @last_file = file
  end
end

trap("INT") { DEBUGGER__.interrupt }
@last_thread = Thread::main
@max_thread = 1
@thread_list = {Thread::main => 1}
@break_points = []
@display = []
@waiting = []
@stdout = STDOUT

class << DEBUGGER__
  def stdout
    @stdout
  end

  def stdout=(s)
    @stdout = s
  end

  def display
    @display
  end

  def break_points
    @break_points
  end

  def waiting
    @waiting
  end

  def set_trace( arg )
    saved_crit = Thread.critical
    Thread.critical = true
    make_thread_list
    for th, in @thread_list
      context(th).set_trace arg
    end
    Thread.critical = saved_crit
    arg
  end

  def set_last_thread(th)
    @last_thread = th
  end

  def suspend
    saved_crit = Thread.critical
    Thread.critical = true
    make_thread_list
    for th, in @thread_list
      next if th == Thread.current
      context(th).set_suspend
    end
    Thread.critical = saved_crit
    # Schedule other threads to suspend as soon as possible.
    Thread.pass unless Thread.critical
  end

  def resume
    saved_crit = Thread.critical
    Thread.critical = true
    make_thread_list
    for th, in @thread_list
      next if th == Thread.current
      context(th).clear_suspend
    end
    waiting.each do |th|
      th.run
    end
    waiting.clear
    Thread.critical = saved_crit
    # Schedule other threads to restart as soon as possible.
    Thread.pass
  end

  def context(thread=Thread.current)
    c = thread[:__debugger_data__]
    unless c
      thread[:__debugger_data__] = c = Context.new
    end
    c
  end

  def interrupt
    context(@last_thread).stop_next
  end

  def get_thread(num)
    th = @thread_list.index(num)
    unless th
      @stdout.print "No thread ##{num}\n"
      throw :debug_error
    end
    th
  end

  def thread_list(num)
    th = get_thread(num)
    if th == Thread.current
      @stdout.print "+"
    else
      @stdout.print " "
    end
    @stdout.printf "%d ", num
    @stdout.print th.inspect, "\t"
    file = context(th).instance_eval{@file}
    if file
      @stdout.print file,":",context(th).instance_eval{@line}
    end
    @stdout.print "\n"
  end

  def thread_list_all
    for th in @thread_list.values.sort
      thread_list(th)
    end
  end

  def make_thread_list
    hash = {}
    for th in Thread::list
      if @thread_list.key? th
	hash[th] = @thread_list[th]
      else
	@max_thread += 1
	hash[th] = @max_thread
      end
    end
    @thread_list = hash
  end

  def debug_thread_info(input, binding)
    case input
    when /^l(?:ist)?/
      make_thread_list
      thread_list_all

    when /^c(?:ur(?:rent)?)?$/
      make_thread_list
      thread_list(@thread_list[Thread.current])

    when /^(?:sw(?:itch)?\s+)?(\d+)/
      make_thread_list
      th = get_thread($1.to_i)
      if th == Thread.current
	@stdout.print "It's the current thread.\n"
      else
	thread_list(@thread_list[th])
	context(th).stop_next
	th.run
	return :cont
      end

    when /^stop\s+(\d+)/
      make_thread_list
      th = get_thread($1.to_i)
      if th == Thread.current
	@stdout.print "It's the current thread.\n"
      elsif th.stop?
	@stdout.print "Already stopped.\n"
      else
	thread_list(@thread_list[th])
	context(th).suspend 
      end

    when /^resume\s+(\d+)/
      make_thread_list
      th = get_thread($1.to_i)
      if th == Thread.current
	@stdout.print "It's the current thread.\n"
      elsif !th.stop?
	@stdout.print "Already running."
      else
	thread_list(@thread_list[th])
	th.run
      end
    end
  end
end

stdout.printf "Debug.rb\n"
stdout.printf "Emacs support available.\n\n"
set_trace_func proc { |event, file, line, id, binding, klass, *rest|
  DEBUGGER__.context.trace_func event, file, line, id, binding, klass
}
end
PK      Z\?rK[  [    profiler.rbnu [        module Profiler__
  # internal values
  @@start = @@stack = @@map = nil
  PROFILE_PROC = proc{|event, file, line, id, binding, klass|
    case event
    when "call", "c-call"
      now = Process.times[0]
      @@stack.push [now, 0.0]
    when "return", "c-return"
      now = Process.times[0]
      key = [klass, id]
      if tick = @@stack.pop
        data = (@@map[key] ||= [0, 0.0, 0.0, key])
        data[0] += 1
        cost = now - tick[0]
        data[1] += cost
        data[2] += cost - tick[1]
        @@stack[-1][1] += cost if @@stack[-1]
      end
    end
  }
module_function
  def start_profile
    @@start = Process.times[0]
    @@stack = []
    @@map = {}
    set_trace_func PROFILE_PROC
  end
  def stop_profile
    set_trace_func nil
  end
  def print_profile(f)
    stop_profile
    total = Process.times[0] - @@start
    if total == 0 then total = 0.01 end
    data = @@map.values
    data.sort!{|a,b| b[2] <=> a[2]}
    sum = 0
    f.printf "  %%   cumulative   self              self     total\n"
    f.printf " time   seconds   seconds    calls  ms/call  ms/call  name\n"
    for d in data
      sum += d[2]
      f.printf "%6.2f %8.2f  %8.2f %8d ", d[2]/total*100, sum, d[2], d[0]
      f.printf "%8.2f %8.2f  %s\n", d[2]*1000/d[0], d[1]*1000/d[0], get_name(*d[3])
    end
    f.printf "%6.2f %8.2f  %8.2f %8d ", 0.0, total, 0.0, 1     # ???
    f.printf "%8.2f %8.2f  %s\n", 0.0, total*1000, "#toplevel" # ???
  end
  def get_name(klass, id)
    name = klass.to_s || ""
    if klass.kind_of? Class
      name += "#"
    else
      name += "."
    end
    name + id.id2name
  end
  private :get_name
end
PK      Z\      tsort.rbnu [        #!/usr/bin/env ruby
#--
# tsort.rb - provides a module for topological sorting and strongly connected components.
#++
#

#
# TSort implements topological sorting using Tarjan's algorithm for
# strongly connected components.
#
# TSort is designed to be able to be used with any object which can be
# interpreted as a directed graph.
#
# TSort requires two methods to interpret an object as a graph,
# tsort_each_node and tsort_each_child.
#
# * tsort_each_node is used to iterate for all nodes over a graph.
# * tsort_each_child is used to iterate for child nodes of a given node.
#
# The equality of nodes are defined by eql? and hash since
# TSort uses Hash internally.
#
# == A Simple Example
#
# The following example demonstrates how to mix the TSort module into an
# existing class (in this case, Hash). Here, we're treating each key in
# the hash as a node in the graph, and so we simply alias the required
# #tsort_each_node method to Hash's #each_key method. For each key in the
# hash, the associated value is an array of the node's child nodes. This
# choice in turn leads to our implementation of the required #tsort_each_child
# method, which fetches the array of child nodes and then iterates over that
# array using the user-supplied block.
#
#   require 'tsort'
#   
#   class Hash
#     include TSort
#     alias tsort_each_node each_key
#     def tsort_each_child(node, &block)
#       fetch(node).each(&block)
#     end
#   end
#   
#   {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
#   #=> [3, 2, 1, 4]
#   
#   {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
#   #=> [[4], [2, 3], [1]]
#
# == A More Realistic Example
#
# A very simple `make' like tool can be implemented as follows:
#
#   require 'tsort'
#   
#   class Make
#     def initialize
#       @dep = {}
#       @dep.default = []
#     end
#     
#     def rule(outputs, inputs=[], &block)
#       triple = [outputs, inputs, block]
#       outputs.each {|f| @dep[f] = [triple]}
#       @dep[triple] = inputs
#     end
#     
#     def build(target)
#       each_strongly_connected_component_from(target) {|ns|
#         if ns.length != 1
#           fs = ns.delete_if {|n| Array === n}
#           raise TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
#         end
#         n = ns.first
#         if Array === n
#           outputs, inputs, block = n
#           inputs_time = inputs.map {|f| File.mtime f}.max
#           begin
#             outputs_time = outputs.map {|f| File.mtime f}.min
#           rescue Errno::ENOENT
#             outputs_time = nil
#           end
#           if outputs_time == nil ||
#              inputs_time != nil && outputs_time <= inputs_time
#             sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
#             block.call
#           end
#         end
#       }
#     end
#     
#     def tsort_each_child(node, &block)
#       @dep[node].each(&block)
#     end
#     include TSort
#   end
#   
#   def command(arg)
#     print arg, "\n"
#     system arg
#   end
#   
#   m = Make.new
#   m.rule(%w[t1]) { command 'date > t1' }
#   m.rule(%w[t2]) { command 'date > t2' }
#   m.rule(%w[t3]) { command 'date > t3' }
#   m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
#   m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
#   m.build('t5')
#
# == Bugs
#
# * 'tsort.rb' is wrong name because this library uses
#   Tarjan's algorithm for strongly connected components.
#   Although 'strongly_connected_components.rb' is correct but too long.
#
# == References
#
# R. E. Tarjan, "Depth First Search and Linear Graph Algorithms",
# <em>SIAM Journal on Computing</em>, Vol. 1, No. 2, pp. 146-160, June 1972.
#

module TSort
  class Cyclic < StandardError
  end

  #
  # Returns a topologically sorted array of nodes.
  # The array is sorted from children to parents, i.e.
  # the first element has no child and the last node has no parent.
  #
  # If there is a cycle, TSort::Cyclic is raised.
  #
  def tsort
    result = []
    tsort_each {|element| result << element}
    result
  end

  #
  # The iterator version of the #tsort method.
  # <tt><em>obj</em>.tsort_each</tt> is similar to <tt><em>obj</em>.tsort.each</tt>, but
  # modification of _obj_ during the iteration may lead to unexpected results.
  #
  # #tsort_each returns +nil+.
  # If there is a cycle, TSort::Cyclic is raised.
  #
  def tsort_each # :yields: node
    each_strongly_connected_component {|component|
      if component.size == 1
        yield component.first
      else
        raise Cyclic.new("topological sort failed: #{component.inspect}")
      end
    }
  end

  #
  # Returns strongly connected components as an array of arrays of nodes.
  # The array is sorted from children to parents.
  # Each elements of the array represents a strongly connected component.
  #
  def strongly_connected_components
    result = []
    each_strongly_connected_component {|component| result << component}
    result
  end

  #
  # The iterator version of the #strongly_connected_components method.
  # <tt><em>obj</em>.each_strongly_connected_component</tt> is similar to
  # <tt><em>obj</em>.strongly_connected_components.each</tt>, but
  # modification of _obj_ during the iteration may lead to unexpected results.
  #
  #
  # #each_strongly_connected_component returns +nil+.
  #
  def each_strongly_connected_component # :yields: nodes
    id_map = {}
    stack = []
    tsort_each_node {|node|
      unless id_map.include? node
        each_strongly_connected_component_from(node, id_map, stack) {|c|
          yield c
        }
      end
    }
    nil
  end

  #
  # Iterates over strongly connected component in the subgraph reachable from 
  # _node_.
  #
  # Return value is unspecified.
  #
  # #each_strongly_connected_component_from doesn't call #tsort_each_node.
  #
  def each_strongly_connected_component_from(node, id_map={}, stack=[]) # :yields: nodes
    minimum_id = node_id = id_map[node] = id_map.size
    stack_length = stack.length
    stack << node

    tsort_each_child(node) {|child|
      if id_map.include? child
        child_id = id_map[child]
        minimum_id = child_id if child_id && child_id < minimum_id
      else
        sub_minimum_id =
          each_strongly_connected_component_from(child, id_map, stack) {|c|
            yield c
          }
        minimum_id = sub_minimum_id if sub_minimum_id < minimum_id
      end
    }

    if node_id == minimum_id
      component = stack.slice!(stack_length .. -1)
      component.each {|n| id_map[n] = nil}
      yield component
    end

    minimum_id
  end

  #
  # Should be implemented by a extended class.
  #
  # #tsort_each_node is used to iterate for all nodes over a graph.
  #
  def tsort_each_node # :yields: node
    raise NotImplementedError.new
  end

  #
  # Should be implemented by a extended class.
  #
  # #tsort_each_child is used to iterate for child nodes of _node_.
  #
  def tsort_each_child(node) # :yields: child
    raise NotImplementedError.new
  end
end

if __FILE__ == $0
  require 'test/unit'

  class TSortHash < Hash # :nodoc:
    include TSort
    alias tsort_each_node each_key
    def tsort_each_child(node, &block)
      fetch(node).each(&block)
    end
  end

  class TSortArray < Array # :nodoc:
    include TSort
    alias tsort_each_node each_index
    def tsort_each_child(node, &block)
      fetch(node).each(&block)
    end
  end

  class TSortTest < Test::Unit::TestCase # :nodoc:
    def test_dag
      h = TSortHash[{1=>[2, 3], 2=>[3], 3=>[]}]
      assert_equal([3, 2, 1], h.tsort)
      assert_equal([[3], [2], [1]], h.strongly_connected_components)
    end

    def test_cycle
      h = TSortHash[{1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}]
      assert_equal([[4], [2, 3], [1]],
        h.strongly_connected_components.map {|nodes| nodes.sort})
      assert_raise(TSort::Cyclic) { h.tsort }
    end

    def test_array
      a = TSortArray[[1], [0], [0], [2]]
      assert_equal([[0, 1], [2], [3]],
        a.strongly_connected_components.map {|nodes| nodes.sort})

      a = TSortArray[[], [0]]
      assert_equal([[0], [1]],
        a.strongly_connected_components.map {|nodes| nodes.sort})
    end
  end

end

PK      Z\ &	y  y  	  expect.rbnu [        $expect_verbose = false

class IO
  def expect(pat,timeout=9999999)
    buf = ''
    case pat
    when String
      e_pat = Regexp.new(Regexp.quote(pat))
    when Regexp
      e_pat = pat
    end
    while true
      if !IO.select([self],nil,nil,timeout) or eof? then
        result = nil
        break
      end
      c = getc.chr
      buf << c
      if $expect_verbose
        STDOUT.print c
        STDOUT.flush
      end
      if mat=e_pat.match(buf) then
        result = [buf,*mat.to_a[1..-1]]
        break
      end
    end
    if block_given? then
      yield result
    else
      return result
    end
    nil
  end
end

PK      Z\UWI  WI    prettyprint.rbnu [        # $Id$

# This class implements a pretty printing algorithm. It finds line breaks and
# nice indentations for grouped structure.
# 
# By default, the class assumes that primitive elements are strings and each
# byte in the strings have single column in width. But it can be used for
# other situations by giving suitable arguments for some methods:
# * newline object and space generation block for PrettyPrint.new
# * optional width argument for PrettyPrint#text
# * PrettyPrint#breakable
#
# There are several candidate uses:
# * text formatting using proportional fonts
# * multibyte characters which has columns different to number of bytes
# * non-string formatting
#
# == Bugs
# * Box based formatting?
# * Other (better) model/algorithm?
# 
# == References
# Christian Lindig, Strictly Pretty, March 2000,
# http://www.st.cs.uni-sb.de/~lindig/papers/#pretty
# 
# Philip Wadler, A prettier printer, March 1998,
# http://homepages.inf.ed.ac.uk/wadler/topics/language-design.html#prettier
# 
# == Author
# Tanaka Akira <akr@m17n.org>
# 
class PrettyPrint

  # This is a convenience method which is same as follows:
  # 
  #   begin
  #     q = PrettyPrint.new(output, maxwidth, newline, &genspace)
  #     ...
  #     q.flush
  #     output
  #   end
  # 
  def PrettyPrint.format(output='', maxwidth=79, newline="\n", genspace=lambda {|n| ' ' * n})
    q = PrettyPrint.new(output, maxwidth, newline, &genspace)
    yield q
    q.flush
    output
  end

  # This is similar to PrettyPrint::format but the result has no breaks.
  #
  # +maxwidth+, +newline+ and +genspace+ are ignored.
  #
  # The invocation of +breakable+ in the block doesn't break a line and is
  # treated as just an invocation of +text+.
  #
  def PrettyPrint.singleline_format(output='', maxwidth=nil, newline=nil, genspace=nil)
    q = SingleLine.new(output)
    yield q
    output
  end

  # Creates a buffer for pretty printing.
  #
  # +output+ is an output target. If it is not specified, '' is assumed. It
  # should have a << method which accepts the first argument +obj+ of
  # PrettyPrint#text, the first argument +sep+ of PrettyPrint#breakable, the
  # first argument +newline+ of PrettyPrint.new, and the result of a given
  # block for PrettyPrint.new.
  #
  # +maxwidth+ specifies maximum line length. If it is not specified, 79 is
  # assumed. However actual outputs may overflow +maxwidth+ if long
  # non-breakable texts are provided.
  #
  # +newline+ is used for line breaks. "\n" is used if it is not specified.
  #
  # The block is used to generate spaces. {|width| ' ' * width} is used if it
  # is not given.
  #
  def initialize(output='', maxwidth=79, newline="\n", &genspace)
    @output = output
    @maxwidth = maxwidth
    @newline = newline
    @genspace = genspace || lambda {|n| ' ' * n}

    @output_width = 0
    @buffer_width = 0
    @buffer = []

    root_group = Group.new(0)
    @group_stack = [root_group]
    @group_queue = GroupQueue.new(root_group)
    @indent = 0
  end
  attr_reader :output, :maxwidth, :newline, :genspace
  attr_reader :indent, :group_queue

  def current_group
    @group_stack.last
  end

  # first? is a predicate to test the call is a first call to first? with
  # current group.
  #
  # It is useful to format comma separated values as:
  #
  #   q.group(1, '[', ']') {
  #     xxx.each {|yyy|
  #       unless q.first?
  #         q.text ','
  #         q.breakable
  #       end
  #       ... pretty printing yyy ...
  #     }
  #   }
  #
  # first? is obsoleted in 1.8.2.
  #
  def first?
    warn "PrettyPrint#first? is obsoleted at 1.8.2."
    current_group.first?
  end

  def break_outmost_groups
    while @maxwidth < @output_width + @buffer_width
      return unless group = @group_queue.deq
      until group.breakables.empty?
        data = @buffer.shift
        @output_width = data.output(@output, @output_width)
        @buffer_width -= data.width
      end
      while !@buffer.empty? && Text === @buffer.first
        text = @buffer.shift
        @output_width = text.output(@output, @output_width)
        @buffer_width -= text.width
      end
    end
  end

  # This adds +obj+ as a text of +width+ columns in width.
  #
  # If +width+ is not specified, obj.length is used.
  #
  def text(obj, width=obj.length)
    if @buffer.empty?
      @output << obj
      @output_width += width
    else
      text = @buffer.last
      unless Text === text
        text = Text.new
        @buffer << text
      end
      text.add(obj, width)
      @buffer_width += width
      break_outmost_groups
    end
  end

  def fill_breakable(sep=' ', width=sep.length)
    group { breakable sep, width }
  end

  # This tells "you can break a line here if necessary", and a +width+\-column
  # text +sep+ is inserted if a line is not broken at the point.
  #
  # If +sep+ is not specified, " " is used.
  #
  # If +width+ is not specified, +sep.length+ is used. You will have to
  # specify this when +sep+ is a multibyte character, for example.
  #
  def breakable(sep=' ', width=sep.length)
    group = @group_stack.last
    if group.break?
      flush
      @output << @newline
      @output << @genspace.call(@indent)
      @output_width = @indent
      @buffer_width = 0
    else
      @buffer << Breakable.new(sep, width, self)
      @buffer_width += width
      break_outmost_groups
    end
  end

  # Groups line break hints added in the block. The line break hints are all
  # to be used or not.
  #
  # If +indent+ is specified, the method call is regarded as nested by
  # nest(indent) { ... }.
  #
  # If +open_obj+ is specified, <tt>text open_obj, open_width</tt> is called
  # before grouping. If +close_obj+ is specified, <tt>text close_obj,
  # close_width</tt> is called after grouping.
  #
  def group(indent=0, open_obj='', close_obj='', open_width=open_obj.length, close_width=close_obj.length)
    text open_obj, open_width
    group_sub {
      nest(indent) {
        yield
      }
    }
    text close_obj, close_width
  end

  def group_sub
    group = Group.new(@group_stack.last.depth + 1)
    @group_stack.push group
    @group_queue.enq group
    begin
      yield
    ensure
      @group_stack.pop
      if group.breakables.empty?
        @group_queue.delete group
      end
    end
  end

  # Increases left margin after newline with +indent+ for line breaks added in
  # the block.
  #
  def nest(indent)
    @indent += indent
    begin
      yield
    ensure
      @indent -= indent
    end
  end

  # outputs buffered data.
  #
  def flush
    @buffer.each {|data|
      @output_width = data.output(@output, @output_width)
    }
    @buffer.clear
    @buffer_width = 0
  end

  class Text
    def initialize
      @objs = []
      @width = 0
    end
    attr_reader :width

    def output(out, output_width)
      @objs.each {|obj| out << obj}
      output_width + @width
    end

    def add(obj, width)
      @objs << obj
      @width += width
    end
  end

  class Breakable
    def initialize(sep, width, q)
      @obj = sep
      @width = width
      @pp = q
      @indent = q.indent
      @group = q.current_group
      @group.breakables.push self
    end
    attr_reader :obj, :width, :indent

    def output(out, output_width)
      @group.breakables.shift
      if @group.break?
        out << @pp.newline
        out << @pp.genspace.call(@indent)
        @indent
      else
        @pp.group_queue.delete @group if @group.breakables.empty?
        out << @obj
        output_width + @width
      end
    end
  end

  class Group
    def initialize(depth)
      @depth = depth
      @breakables = []
      @break = false
    end
    attr_reader :depth, :breakables

    def break
      @break = true
    end

    def break?
      @break
    end

    def first?
      if defined? @first
        false
      else
        @first = false
        true
      end
    end
  end

  class GroupQueue
    def initialize(*groups)
      @queue = []
      groups.each {|g| enq g}
    end

    def enq(group)
      depth = group.depth
      @queue << [] until depth < @queue.length
      @queue[depth] << group
    end

    def deq
      @queue.each {|gs|
        (gs.length-1).downto(0) {|i|
          unless gs[i].breakables.empty?
            group = gs.slice!(i, 1).first
            group.break
            return group
          end
        }
        gs.each {|group| group.break}
        gs.clear
      }
      return nil
    end

    def delete(group)
      @queue[group.depth].delete(group)
    end
  end

  class SingleLine
    def initialize(output, maxwidth=nil, newline=nil)
      @output = output
      @first = [true]
    end

    def text(obj, width=nil)
      @output << obj
    end

    def breakable(sep=' ', width=nil)
      @output << sep
    end

    def nest(indent)
      yield
    end

    def group(indent=nil, open_obj='', close_obj='', open_width=nil, close_width=nil)
      @first.push true
      @output << open_obj
      yield
      @output << close_obj
      @first.pop
    end

    def flush
    end

    def first?
      result = @first[-1]
      @first[-1] = false
      result
    end
  end
end

if __FILE__ == $0
  require 'test/unit'

  class WadlerExample < Test::Unit::TestCase # :nodoc:
    def setup
      @tree = Tree.new("aaaa", Tree.new("bbbbb", Tree.new("ccc"),
                                                 Tree.new("dd")),
                               Tree.new("eee"),
                               Tree.new("ffff", Tree.new("gg"),
                                                Tree.new("hhh"),
                                                Tree.new("ii")))
    end

    def hello(width)
      PrettyPrint.format('', width) {|hello|
        hello.group {
          hello.group {
            hello.group {
              hello.group {
                hello.text 'hello'
                hello.breakable; hello.text 'a'
              }
              hello.breakable; hello.text 'b'
            }
            hello.breakable; hello.text 'c'
          }
          hello.breakable; hello.text 'd'
        }
      }
    end

    def test_hello_00_06
      expected = <<'End'.chomp
hello
a
b
c
d
End
      assert_equal(expected, hello(0))
      assert_equal(expected, hello(6))
    end

    def test_hello_07_08
      expected = <<'End'.chomp
hello a
b
c
d
End
      assert_equal(expected, hello(7))
      assert_equal(expected, hello(8))
    end

    def test_hello_09_10
      expected = <<'End'.chomp
hello a b
c
d
End
      out = hello(9); assert_equal(expected, out)
      out = hello(10); assert_equal(expected, out)
    end

    def test_hello_11_12
      expected = <<'End'.chomp
hello a b c
d
End
      assert_equal(expected, hello(11))
      assert_equal(expected, hello(12))
    end

    def test_hello_13
      expected = <<'End'.chomp
hello a b c d
End
      assert_equal(expected, hello(13))
    end

    def tree(width)
      PrettyPrint.format('', width) {|q| @tree.show(q)}
    end

    def test_tree_00_19
      expected = <<'End'.chomp
aaaa[bbbbb[ccc,
           dd],
     eee,
     ffff[gg,
          hhh,
          ii]]
End
      assert_equal(expected, tree(0))
      assert_equal(expected, tree(19))
    end

    def test_tree_20_22
      expected = <<'End'.chomp
aaaa[bbbbb[ccc, dd],
     eee,
     ffff[gg,
          hhh,
          ii]]
End
      assert_equal(expected, tree(20))
      assert_equal(expected, tree(22))
    end

    def test_tree_23_43
      expected = <<'End'.chomp
aaaa[bbbbb[ccc, dd],
     eee,
     ffff[gg, hhh, ii]]
End
      assert_equal(expected, tree(23))
      assert_equal(expected, tree(43))
    end

    def test_tree_44
      assert_equal(<<'End'.chomp, tree(44))
aaaa[bbbbb[ccc, dd], eee, ffff[gg, hhh, ii]]
End
    end

    def tree_alt(width)
      PrettyPrint.format('', width) {|q| @tree.altshow(q)}
    end

    def test_tree_alt_00_18
      expected = <<'End'.chomp
aaaa[
  bbbbb[
    ccc,
    dd
  ],
  eee,
  ffff[
    gg,
    hhh,
    ii
  ]
]
End
      assert_equal(expected, tree_alt(0))
      assert_equal(expected, tree_alt(18))
    end

    def test_tree_alt_19_20
      expected = <<'End'.chomp
aaaa[
  bbbbb[ ccc, dd ],
  eee,
  ffff[
    gg,
    hhh,
    ii
  ]
]
End
      assert_equal(expected, tree_alt(19))
      assert_equal(expected, tree_alt(20))
    end

    def test_tree_alt_20_49
      expected = <<'End'.chomp
aaaa[
  bbbbb[ ccc, dd ],
  eee,
  ffff[ gg, hhh, ii ]
]
End
      assert_equal(expected, tree_alt(21))
      assert_equal(expected, tree_alt(49))
    end

    def test_tree_alt_50
      expected = <<'End'.chomp
aaaa[ bbbbb[ ccc, dd ], eee, ffff[ gg, hhh, ii ] ]
End
      assert_equal(expected, tree_alt(50))
    end

    class Tree # :nodoc:
      def initialize(string, *children)
        @string = string
        @children = children
      end

      def show(q)
        q.group {
          q.text @string
          q.nest(@string.length) {
            unless @children.empty?
              q.text '['
              q.nest(1) {
                first = true
                @children.each {|t|
                  if first
                    first = false
                  else
                    q.text ','
                    q.breakable
                  end
                  t.show(q)
                }
              }
              q.text ']'
            end
          }
        }
      end

      def altshow(q)
        q.group {
          q.text @string
          unless @children.empty?
            q.text '['
            q.nest(2) {
              q.breakable
              first = true
              @children.each {|t|
                if first
                  first = false
                else
                  q.text ','
                  q.breakable
                end
                t.altshow(q)
              }
            }
            q.breakable
            q.text ']'
          end
        }
      end

    end
  end

  class StrictPrettyExample < Test::Unit::TestCase # :nodoc:
    def prog(width)
      PrettyPrint.format('', width) {|q|
        q.group {
          q.group {q.nest(2) {
                       q.text "if"; q.breakable;
                       q.group {
                         q.nest(2) {
                           q.group {q.text "a"; q.breakable; q.text "=="}
                           q.breakable; q.text "b"}}}}
          q.breakable
          q.group {q.nest(2) {
                       q.text "then"; q.breakable;
                       q.group {
                         q.nest(2) {
                           q.group {q.text "a"; q.breakable; q.text "<<"}
                           q.breakable; q.text "2"}}}}
          q.breakable
          q.group {q.nest(2) {
                       q.text "else"; q.breakable;
                       q.group {
                         q.nest(2) {
                           q.group {q.text "a"; q.breakable; q.text "+"}
                           q.breakable; q.text "b"}}}}}
      }
    end

    def test_00_04
      expected = <<'End'.chomp
if
  a
    ==
    b
then
  a
    <<
    2
else
  a
    +
    b
End
      assert_equal(expected, prog(0))
      assert_equal(expected, prog(4))
    end

    def test_05
      expected = <<'End'.chomp
if
  a
    ==
    b
then
  a
    <<
    2
else
  a +
    b
End
      assert_equal(expected, prog(5))
    end

    def test_06
      expected = <<'End'.chomp
if
  a ==
    b
then
  a <<
    2
else
  a +
    b
End
      assert_equal(expected, prog(6))
    end

    def test_07
      expected = <<'End'.chomp
if
  a ==
    b
then
  a <<
    2
else
  a + b
End
      assert_equal(expected, prog(7))
    end

    def test_08
      expected = <<'End'.chomp
if
  a == b
then
  a << 2
else
  a + b
End
      assert_equal(expected, prog(8))
    end

    def test_09
      expected = <<'End'.chomp
if a == b
then
  a << 2
else
  a + b
End
      assert_equal(expected, prog(9))
    end

    def test_10
      expected = <<'End'.chomp
if a == b
then
  a << 2
else a + b
End
      assert_equal(expected, prog(10))
    end

    def test_11_31
      expected = <<'End'.chomp
if a == b
then a << 2
else a + b
End
      assert_equal(expected, prog(11))
      assert_equal(expected, prog(15))
      assert_equal(expected, prog(31))
    end

    def test_32
      expected = <<'End'.chomp
if a == b then a << 2 else a + b
End
      assert_equal(expected, prog(32))
    end

  end

  class TailGroup < Test::Unit::TestCase # :nodoc:
    def test_1
      out = PrettyPrint.format('', 10) {|q|
        q.group {
          q.group {
            q.text "abc"
            q.breakable
            q.text "def"
          }
          q.group {
            q.text "ghi"
            q.breakable
            q.text "jkl"
          }
        }
      }
      assert_equal("abc defghi\njkl", out)
    end
  end

  class NonString < Test::Unit::TestCase # :nodoc:
    def format(width)
      PrettyPrint.format([], width, 'newline', lambda {|n| "#{n} spaces"}) {|q|
        q.text(3, 3)
        q.breakable(1, 1)
        q.text(3, 3)
      }
    end

    def test_6
      assert_equal([3, "newline", "0 spaces", 3], format(6))
    end

    def test_7
      assert_equal([3, 1, 3], format(7))
    end

  end

  class Fill < Test::Unit::TestCase # :nodoc:
    def format(width)
      PrettyPrint.format('', width) {|q|
        q.group {
          q.text 'abc'
          q.fill_breakable
          q.text 'def'
          q.fill_breakable
          q.text 'ghi'
          q.fill_breakable
          q.text 'jkl'
          q.fill_breakable
          q.text 'mno'
          q.fill_breakable
          q.text 'pqr'
          q.fill_breakable
          q.text 'stu'
        }
      }
    end

    def test_00_06
      expected = <<'End'.chomp
abc
def
ghi
jkl
mno
pqr
stu
End
      assert_equal(expected, format(0))
      assert_equal(expected, format(6))
    end

    def test_07_10
      expected = <<'End'.chomp
abc def
ghi jkl
mno pqr
stu
End
      assert_equal(expected, format(7))
      assert_equal(expected, format(10))
    end

    def test_11_14
      expected = <<'End'.chomp
abc def ghi
jkl mno pqr
stu
End
      assert_equal(expected, format(11))
      assert_equal(expected, format(14))
    end

    def test_15_18
      expected = <<'End'.chomp
abc def ghi jkl
mno pqr stu
End
      assert_equal(expected, format(15))
      assert_equal(expected, format(18))
    end

    def test_19_22
      expected = <<'End'.chomp
abc def ghi jkl mno
pqr stu
End
      assert_equal(expected, format(19))
      assert_equal(expected, format(22))
    end

    def test_23_26
      expected = <<'End'.chomp
abc def ghi jkl mno pqr
stu
End
      assert_equal(expected, format(23))
      assert_equal(expected, format(26))
    end

    def test_27
      expected = <<'End'.chomp
abc def ghi jkl mno pqr stu
End
      assert_equal(expected, format(27))
    end

  end
end
PK      Z\-!~a  a    csv.rbnu [        # CSV -- module for generating/parsing CSV data.
# Copyright (C) 2000-2004  NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>.
  
# $Id: csv.rb 11708 2007-02-12 23:01:19Z shyouhei $
  
# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.
  
  
class CSV
  class IllegalFormatError < RuntimeError; end

  # deprecated
  class Cell < String
    def initialize(data = "", is_null = false)
      super(is_null ? "" : data)
    end

    def data
      to_s
    end
  end

  # deprecated
  class Row < Array
  end

  # Open a CSV formatted file for reading or writing.
  #
  # For reading.
  #
  # EXAMPLE 1
  #   CSV.open('csvfile.csv', 'r') do |row|
  #     p row
  #   end
  #
  # EXAMPLE 2
  #   reader = CSV.open('csvfile.csv', 'r')
  #   row1 = reader.shift
  #   row2 = reader.shift
  #   if row2.empty?
  #     p 'row2 not find.'
  #   end
  #   reader.close
  #
  # ARGS
  #   filename: filename to parse.
  #   col_sep: Column separator.  ?, by default.  If you want to separate
  #     fields with semicolon, give ?; here.
  #   row_sep: Row separator.  nil by default.  nil means "\r\n or \n".  If you
  #     want to separate records with \r, give ?\r here.
  #
  # RETURNS
  #   reader instance.  To get parse result, see CSV::Reader#each.
  #
  #
  # For writing.
  #
  # EXAMPLE 1
  #   CSV.open('csvfile.csv', 'w') do |writer|
  #     writer << ['r1c1', 'r1c2']
  #     writer << ['r2c1', 'r2c2']
  #     writer << [nil, nil]
  #   end
  #
  # EXAMPLE 2
  #   writer = CSV.open('csvfile.csv', 'w')
  #   writer << ['r1c1', 'r1c2'] << ['r2c1', 'r2c2'] << [nil, nil]
  #   writer.close
  #
  # ARGS
  #   filename: filename to generate.
  #   col_sep: Column separator.  ?, by default.  If you want to separate
  #     fields with semicolon, give ?; here.
  #   row_sep: Row separator.  nil by default.  nil means "\r\n or \n".  If you
  #     want to separate records with \r, give ?\r here.
  #
  # RETURNS
  #   writer instance.  See CSV::Writer#<< and CSV::Writer#add_row to know how
  #   to generate CSV string.
  #
  def CSV.open(path, mode, fs = nil, rs = nil, &block)
    if mode == 'r' or mode == 'rb'
      open_reader(path, mode, fs, rs, &block)
    elsif mode == 'w' or mode == 'wb'
      open_writer(path, mode, fs, rs, &block)
    else
      raise ArgumentError.new("'mode' must be 'r', 'rb', 'w', or 'wb'")
    end
  end

  def CSV.foreach(path, rs = nil, &block)
    open_reader(path, 'r', ',', rs, &block)
  end

  def CSV.read(path, length = nil, offset = nil)
    CSV.parse(IO.read(path, length, offset))
  end
  
  def CSV.readlines(path, rs = nil)
    reader = open_reader(path, 'r', ',', rs)
    begin
      reader.collect { |row| row }
    ensure
      reader.close
    end
  end

  def CSV.generate(path, fs = nil, rs = nil, &block)
    open_writer(path, 'w', fs, rs, &block)
  end

  # Parse lines from given string or stream.  Return rows as an Array of Arrays.
  def CSV.parse(str_or_readable, fs = nil, rs = nil, &block)
    if File.exist?(str_or_readable)
      STDERR.puts("CSV.parse(filename) is deprecated." +
        "  Use CSV.open(filename, 'r') instead.")
      return open_reader(str_or_readable, 'r', fs, rs, &block)
    end
    if block
      CSV::Reader.parse(str_or_readable, fs, rs) do |row|
        yield(row)
      end
      nil
    else
      CSV::Reader.create(str_or_readable, fs, rs).collect { |row| row }
    end
  end

  # Parse a line from given string.  Bear in mind it parses ONE LINE.  Rest of
  # the string is ignored for example "a,b\r\nc,d" => ['a', 'b'] and the
  # second line 'c,d' is ignored.
  #
  # If you don't know whether a target string to parse is exactly 1 line or
  # not, use CSV.parse_row instead of this method.
  def CSV.parse_line(src, fs = nil, rs = nil)
    fs ||= ','
    if fs.is_a?(Fixnum)
      fs = fs.chr
    end
    if !rs.nil? and rs.is_a?(Fixnum)
      rs = rs.chr
    end
    idx = 0
    res_type = :DT_COLSEP
    row = []
    begin
      while res_type == :DT_COLSEP
        res_type, idx, cell = parse_body(src, idx, fs, rs)
        row << cell
      end
    rescue IllegalFormatError
      return []
    end
    row
  end

  # Create a line from cells.  each cell is stringified by to_s.
  def CSV.generate_line(row, fs = nil, rs = nil)
    if row.size == 0
      return ''
    end
    fs ||= ','
    if fs.is_a?(Fixnum)
      fs = fs.chr
    end
    if !rs.nil? and rs.is_a?(Fixnum)
      rs = rs.chr
    end
    res_type = :DT_COLSEP
    result_str = ''
    idx = 0
    while true
      generate_body(row[idx], result_str, fs, rs)
      idx += 1
      if (idx == row.size)
        break
      end
      generate_separator(:DT_COLSEP, result_str, fs, rs)
    end
    result_str
  end
  
  # Parse a line from string.  Consider using CSV.parse_line instead.
  # To parse lines in CSV string, see EXAMPLE below.
  #
  # EXAMPLE
  #   src = "a,b\r\nc,d\r\ne,f"
  #   idx = 0
  #   begin
  #     parsed = []
  #     parsed_cells, idx = CSV.parse_row(src, idx, parsed)
  #     puts "Parsed #{ parsed_cells } cells."
  #     p parsed
  #   end while parsed_cells > 0
  #
  # ARGS
  #   src: a CSV data to be parsed.  Must respond '[](idx)'.
  #     src[](idx) must return a char. (Not a string such as 'a', but 97).
  #     src[](idx_out_of_bounds) must return nil.  A String satisfies this
  #     requirement.
  #   idx: index of parsing location of 'src'.  0 origin.
  #   out_dev: buffer for parsed cells.  Must respond '<<(aString)'.
  #   col_sep: Column separator.  ?, by default.  If you want to separate
  #     fields with semicolon, give ?; here.
  #   row_sep: Row separator.  nil by default.  nil means "\r\n or \n".  If you
  #     want to separate records with \r, give ?\r here.
  #
  # RETURNS
  #   parsed_cells: num of parsed cells.
  #   idx: index of next parsing location of 'src'.
  #
  def CSV.parse_row(src, idx, out_dev, fs = nil, rs = nil)
    fs ||= ','
    if fs.is_a?(Fixnum)
      fs = fs.chr
    end
    if !rs.nil? and rs.is_a?(Fixnum)
      rs = rs.chr
    end
    idx_backup = idx
    parsed_cells = 0
    res_type = :DT_COLSEP
    begin
      while res_type != :DT_ROWSEP
        res_type, idx, cell = parse_body(src, idx, fs, rs)
        if res_type == :DT_EOS
          if idx == idx_backup #((parsed_cells == 0) and cell.nil?)
            return 0, 0
          end
          res_type = :DT_ROWSEP
        end
        parsed_cells += 1
        out_dev << cell
      end
    rescue IllegalFormatError
      return 0, 0
    end
    return parsed_cells, idx
  end
  
  # Convert a line from cells data to string.  Consider using CSV.generate_line
  # instead.  To generate multi-row CSV string, see EXAMPLE below.
  #
  # EXAMPLE
  #   row1 = ['a', 'b']
  #   row2 = ['c', 'd']
  #   row3 = ['e', 'f']
  #   src = [row1, row2, row3]
  #   buf = ''
  #   src.each do |row|
  #     parsed_cells = CSV.generate_row(row, 2, buf)
  #     puts "Created #{ parsed_cells } cells."
  #   end
  #   p buf
  #
  # ARGS
  #   src: an Array of String to be converted to CSV string.  Must respond to
  #     'size' and '[](idx)'.  src[idx] must return String.
  #   cells: num of cells in a line.
  #   out_dev: buffer for generated CSV string.  Must respond to '<<(string)'.
  #   col_sep: Column separator.  ?, by default.  If you want to separate
  #     fields with semicolon, give ?; here.
  #   row_sep: Row separator.  nil by default.  nil means "\r\n or \n".  If you
  #     want to separate records with \r, give ?\r here.
  #
  # RETURNS
  #   parsed_cells: num of converted cells.
  #
  def CSV.generate_row(src, cells, out_dev, fs = nil, rs = nil)
    fs ||= ','
    if fs.is_a?(Fixnum)
      fs = fs.chr
    end
    if !rs.nil? and rs.is_a?(Fixnum)
      rs = rs.chr
    end
    src_size = src.size
    if (src_size == 0)
      if cells == 0
        generate_separator(:DT_ROWSEP, out_dev, fs, rs)
      end
      return 0
    end
    res_type = :DT_COLSEP
    parsed_cells = 0
    generate_body(src[parsed_cells], out_dev, fs, rs)
    parsed_cells += 1
    while ((parsed_cells < cells) and (parsed_cells != src_size))
      generate_separator(:DT_COLSEP, out_dev, fs, rs)
      generate_body(src[parsed_cells], out_dev, fs, rs)
      parsed_cells += 1
    end
    if (parsed_cells == cells)
      generate_separator(:DT_ROWSEP, out_dev, fs, rs)
    else
      generate_separator(:DT_COLSEP, out_dev, fs, rs)
    end
    parsed_cells
  end
  
  # Private class methods.
  class << self
  private

    def open_reader(path, mode, fs, rs, &block)
      file = File.open(path, mode)
      if block
        begin
          CSV::Reader.parse(file, fs, rs) do |row|
            yield(row)
          end
        ensure
          file.close
        end
        nil
      else
        reader = CSV::Reader.create(file, fs, rs)
        reader.close_on_terminate
        reader
      end
    end

    def open_writer(path, mode, fs, rs, &block)
      file = File.open(path, mode)
      if block
        begin
          CSV::Writer.generate(file, fs, rs) do |writer|
            yield(writer)
          end
        ensure
          file.close
        end
        nil
      else
        writer = CSV::Writer.create(file, fs, rs) 
        writer.close_on_terminate
        writer
      end
    end

    def parse_body(src, idx, fs, rs)
      fs_str = fs
      fs_size = fs_str.size
      rs_str = rs || "\n"
      rs_size = rs_str.size
      fs_idx = rs_idx = 0
      cell = Cell.new
      state = :ST_START
      quoted = cr = false
      c = nil
      last_idx = idx
      while c = src[idx]
        unless quoted
          fschar = (c == fs_str[fs_idx])
          rschar = (c == rs_str[rs_idx])
          # simple 1 char backtrack
          if !fschar and c == fs_str[0]
            fs_idx = 0
            fschar = true
            if state == :ST_START
              state = :ST_DATA
            elsif state == :ST_QUOTE
              raise IllegalFormatError
            end
          end
          if !rschar and c == rs_str[0]
            rs_idx = 0
            rschar = true
            if state == :ST_START
              state = :ST_DATA
            elsif state == :ST_QUOTE
              raise IllegalFormatError
            end
          end
        end
        if c == ?"
          fs_idx = rs_idx = 0
          if cr
            raise IllegalFormatError
          end
          cell << src[last_idx, (idx - last_idx)]
          last_idx = idx
          if state == :ST_DATA
            if quoted
              last_idx += 1
              quoted = false
              state = :ST_QUOTE
            else
              raise IllegalFormatError
            end
          elsif state == :ST_QUOTE
            cell << c.chr
            last_idx += 1
            quoted = true
            state = :ST_DATA
          else  # :ST_START
            quoted = true
            last_idx += 1
            state = :ST_DATA
          end
        elsif fschar or rschar
          if fschar
            fs_idx += 1
          end
          if rschar
            rs_idx += 1
          end
          sep = nil
          if fs_idx == fs_size
            if state == :ST_START and rs_idx > 0 and fs_idx < rs_idx
              state = :ST_DATA
            end
            cell << src[last_idx, (idx - last_idx - (fs_size - 1))]
            last_idx = idx
            fs_idx = rs_idx = 0
            if cr
              raise IllegalFormatError
            end
            sep = :DT_COLSEP
          elsif rs_idx == rs_size
            if state == :ST_START and fs_idx > 0 and rs_idx < fs_idx
              state = :ST_DATA
            end
            if !(rs.nil? and cr)
              cell << src[last_idx, (idx - last_idx - (rs_size - 1))]
              last_idx = idx
            end
            fs_idx = rs_idx = 0
            sep = :DT_ROWSEP
          end
          if sep
            if state == :ST_DATA
              return sep, idx + 1, cell;
            elsif state == :ST_QUOTE
              return sep, idx + 1, cell;
            else  # :ST_START
              return sep, idx + 1, nil
            end
          end
        elsif rs.nil? and c == ?\r
          # special \r treatment for backward compatibility
          fs_idx = rs_idx = 0
          if cr
            raise IllegalFormatError
          end
          cell << src[last_idx, (idx - last_idx)]
          last_idx = idx
          if quoted
            state = :ST_DATA
          else
            cr = true
          end
        else
          fs_idx = rs_idx = 0
          if state == :ST_DATA or state == :ST_START
            if cr
              raise IllegalFormatError
            end
            state = :ST_DATA
          else  # :ST_QUOTE
            raise IllegalFormatError
          end
        end
        idx += 1
      end
      if state == :ST_START
        if fs_idx > 0 or rs_idx > 0
          state = :ST_DATA
        else
          return :DT_EOS, idx, nil
        end
      elsif quoted
        raise IllegalFormatError
      elsif cr
        raise IllegalFormatError
      end
      cell << src[last_idx, (idx - last_idx)]
      last_idx = idx
      return :DT_EOS, idx, cell
    end
  
    def generate_body(cell, out_dev, fs, rs)
      if cell.nil?
        # empty
      else
        cell = cell.to_s
        row_data = cell.dup
        if (row_data.gsub!('"', '""') or
            row_data.index(fs) or
            (rs and row_data.index(rs)) or
            (/[\r\n]/ =~ row_data) or
            (cell.empty?))
          out_dev << '"' << row_data << '"'
        else
          out_dev << row_data
        end
      end
    end
    
    def generate_separator(type, out_dev, fs, rs)
      case type
      when :DT_COLSEP
        out_dev << fs
      when :DT_ROWSEP
        out_dev << (rs || "\n")
      end
    end
  end


  # CSV formatted string/stream reader.
  #
  # EXAMPLE
  #   read CSV lines untill the first column is 'stop'.
  #
  #   CSV::Reader.parse(File.open('bigdata', 'rb')) do |row|
  #     p row
  #     break if !row[0].is_null && row[0].data == 'stop'
  #   end
  #
  class Reader
    include Enumerable

    # Parse CSV data and get lines.  Given block is called for each parsed row.
    # Block value is always nil.  Rows are not cached for performance reason.
    def Reader.parse(str_or_readable, fs = ',', rs = nil, &block)
      reader = Reader.create(str_or_readable, fs, rs)
      if block
        reader.each do |row|
          yield(row)
        end
        reader.close
        nil
      else
        reader
      end
    end

    # Returns reader instance.
    def Reader.create(str_or_readable, fs = ',', rs = nil)
      case str_or_readable
      when IO
        IOReader.new(str_or_readable, fs, rs)
      when String
        StringReader.new(str_or_readable, fs, rs)
      else
        IOReader.new(str_or_readable, fs, rs)
      end
    end

    def each
      while true
        row = []
        parsed_cells = get_row(row)
        if parsed_cells == 0
          break
        end
        yield(row)
      end
      nil
    end

    def shift
      row = []
      parsed_cells = get_row(row)
      row
    end

    def close
      terminate
    end

  private

    def initialize(dev)
      raise RuntimeError.new('Do not instanciate this class directly.')
    end

    def get_row(row)
      raise NotImplementedError.new('Method get_row must be defined in a derived class.')
    end

    def terminate
      # Define if needed.
    end
  end
  

  class StringReader < Reader
    def initialize(string, fs = ',', rs = nil)
      @fs = fs
      @rs = rs
      @dev = string
      @idx = 0
      if @dev[0, 3] == "\xef\xbb\xbf"
        @idx += 3
      end
    end

  private

    def get_row(row)
      parsed_cells, next_idx = CSV.parse_row(@dev, @idx, row, @fs, @rs)
      if parsed_cells == 0 and next_idx == 0 and @idx != @dev.size
        raise IllegalFormatError.new
      end
      @idx = next_idx
      parsed_cells
    end
  end


  class IOReader < Reader
    def initialize(io, fs = ',', rs = nil)
      @io = io
      @fs = fs
      @rs = rs
      @dev = CSV::IOBuf.new(@io)
      @idx = 0
      if @dev[0] == 0xef and @dev[1] == 0xbb and @dev[2] == 0xbf
        @idx += 3
      end
      @close_on_terminate = false
    end

    # Tell this reader to close the IO when terminated (Triggered by invoking
    # CSV::IOReader#close).
    def close_on_terminate
      @close_on_terminate = true
    end

  private

    def get_row(row)
      parsed_cells, next_idx = CSV.parse_row(@dev, @idx, row, @fs, @rs)
      if parsed_cells == 0 and next_idx == 0 and !@dev.is_eos?
        raise IllegalFormatError.new
      end
      dropped = @dev.drop(next_idx)
      @idx = next_idx - dropped
      parsed_cells
    end

    def terminate
      if @close_on_terminate
        @io.close
      end

      if @dev
        @dev.close
      end
    end
  end


  # CSV formatted string/stream writer.
  #
  # EXAMPLE
  #   Write rows to 'csvout' file.
  #
  #   outfile = File.open('csvout', 'wb')
  #   CSV::Writer.generate(outfile) do |csv|
  #     csv << ['c1', nil, '', '"', "\r\n", 'c2']
  #     ...
  #   end
  #
  #   outfile.close
  #
  class Writer
    # Given block is called with the writer instance.  str_or_writable must
    # handle '<<(string)'.
    def Writer.generate(str_or_writable, fs = ',', rs = nil, &block)
      writer = Writer.create(str_or_writable, fs, rs)
      if block
        yield(writer)
        writer.close
        nil
      else
        writer
      end
    end

    # str_or_writable must handle '<<(string)'.
    def Writer.create(str_or_writable, fs = ',', rs = nil)
      BasicWriter.new(str_or_writable, fs, rs)
    end

    # dump CSV stream to the device.  argument must be an Array of String.
    def <<(row)
      CSV.generate_row(row, row.size, @dev, @fs, @rs)
      self
    end
    alias add_row <<

    def close
      terminate
    end

  private

    def initialize(dev)
      raise RuntimeError.new('Do not instanciate this class directly.')
    end

    def terminate
      # Define if needed.
    end
  end


  class BasicWriter < Writer
    def initialize(str_or_writable, fs = ',', rs = nil)
      @fs = fs
      @rs = rs
      @dev = str_or_writable
      @close_on_terminate = false
    end

    # Tell this writer to close the IO when terminated (Triggered by invoking
    # CSV::BasicWriter#close).
    def close_on_terminate
      @close_on_terminate = true
    end

  private

    def terminate
      if @close_on_terminate
        @dev.close
      end
    end
  end

private

  # Buffered stream.
  #
  # EXAMPLE 1 -- an IO.
  #   class MyBuf < StreamBuf
  #     # Do initialize myself before a super class.  Super class might call my
  #     # method 'read'. (Could be awful for C++ user. :-)
  #     def initialize(s)
  #       @s = s
  #       super()
  #     end
  #
  #     # define my own 'read' method.
  #     # CAUTION: Returning nil means EnfOfStream.
  #     def read(size)
  #       @s.read(size)
  #     end
  #
  #     # release buffers. in Ruby which has GC, you do not have to call this...
  #     def terminate
  #       @s = nil
  #       super()
  #     end
  #   end
  #
  #   buf = MyBuf.new(STDIN)
  #   my_str = ''
  #   p buf[0, 0]               # => '' (null string)
  #   p buf[0]                  # => 97 (char code of 'a')
  #   p buf[0, 1]               # => 'a'
  #   my_str = buf[0, 5]
  #   p my_str                  # => 'abcde' (5 chars)
  #   p buf[0, 6]               # => "abcde\n" (6 chars)
  #   p buf[0, 7]               # => "abcde\n" (6 chars)
  #   p buf.drop(3)             # => 3 (dropped chars)
  #   p buf.get(0, 2)           # => 'de' (2 chars)
  #   p buf.is_eos?             # => false (is not EOS here)
  #   p buf.drop(5)             # => 3 (dropped chars)
  #   p buf.is_eos?             # => true (is EOS here)
  #   p buf[0]                  # => nil (is EOS here)
  #
  # EXAMPLE 2 -- String.
  #   This is a conceptual example.  No pros with this.
  #
  #   class StrBuf < StreamBuf
  #     def initialize(s)
  #       @str = s
  #       @idx = 0
  #       super()
  #     end
  #
  #     def read(size)
  #       str = @str[@idx, size]
  #       @idx += str.size
  #       str
  #     end
  #   end
  #
  class StreamBuf
    # get a char or a partial string from the stream.
    # idx: index of a string to specify a start point of a string to get.
    # unlike String instance, idx < 0 returns nil.
    # n: size of a string to get.
    # returns char at idx if n == nil.
    # returns a partial string, from idx to (idx + n) if n != nil.  at EOF,
    # the string size could not equal to arg n.
    def [](idx, n = nil) 
      if idx < 0
        return nil
      end
      if (idx_is_eos?(idx))
        if n and (@offset + idx == buf_size(@cur_buf))
          # Like a String, 'abc'[4, 1] returns nil and
          # 'abc'[3, 1] returns '' not nil.
          return ''
        else
          return nil
        end
      end
      my_buf = @cur_buf
      my_offset = @offset
      next_idx = idx
      while (my_offset + next_idx >= buf_size(my_buf))
        if (my_buf == @buf_tail_idx)
          unless add_buf
            break
          end
        end
        next_idx = my_offset + next_idx - buf_size(my_buf)
        my_buf += 1
        my_offset = 0
      end
      loc = my_offset + next_idx
      if !n
        return @buf_list[my_buf][loc]           # Fixnum of char code.
      elsif (loc + n - 1 < buf_size(my_buf))
        return @buf_list[my_buf][loc, n]        # String.
      else # should do loop insted of (tail) recursive call...
        res = @buf_list[my_buf][loc, BufSize]
        size_added = buf_size(my_buf) - loc
        if size_added > 0
          idx += size_added
          n -= size_added
          ret = self[idx, n]
          if ret
            res << ret
          end
        end
        return res
      end
    end
    alias get []
  
    # drop a string from the stream.
    # returns dropped size.  at EOF, dropped size might not equals to arg n.
    # Once you drop the head of the stream, access to the dropped part via []
    # or get returns nil.
    def drop(n)
      if is_eos?
        return 0
      end
      size_dropped = 0
      while (n > 0)
        if !@is_eos or (@cur_buf != @buf_tail_idx)
          if (@offset + n < buf_size(@cur_buf))
            size_dropped += n
            @offset += n
            n = 0
          else
            size = buf_size(@cur_buf) - @offset
            size_dropped += size
            n -= size
            @offset = 0
            unless rel_buf
              unless add_buf
                break
              end
              @cur_buf = @buf_tail_idx
            end
          end
        end
      end
      size_dropped
    end
  
    def is_eos?
      return idx_is_eos?(0)
    end
  
    # WARN: Do not instantiate this class directly.  Define your own class
    # which derives this class and define 'read' instance method.
    def initialize
      @buf_list = []
      @cur_buf = @buf_tail_idx = -1
      @offset = 0
      @is_eos = false
      add_buf
      @cur_buf = @buf_tail_idx
    end
  
  protected

    def terminate
      while (rel_buf); end
    end
  
    # protected method 'read' must be defined in derived classes.
    # CAUTION: Returning a string which size is not equal to 'size' means
    # EnfOfStream.  When it is not at EOS, you must block the callee, try to
    # read and return the sized string.
    def read(size) # raise EOFError
      raise NotImplementedError.new('Method read must be defined in a derived class.')
    end
  
  private
  
    def buf_size(idx)
      @buf_list[idx].size
    end

    def add_buf
      if @is_eos
        return false
      end
      begin
        str_read = read(BufSize)
      rescue EOFError
        str_read = nil
      rescue
        terminate
        raise
      end
      if str_read.nil?
        @is_eos = true
        @buf_list.push('')
        @buf_tail_idx += 1
        false
      else
        @buf_list.push(str_read)
        @buf_tail_idx += 1
        true
      end
    end
  
    def rel_buf
      if (@cur_buf < 0)
        return false
      end
      @buf_list[@cur_buf] = nil
      if (@cur_buf == @buf_tail_idx)
        @cur_buf = -1
        return false
      else
        @cur_buf += 1
        return true
      end
    end
  
    def idx_is_eos?(idx)
      (@is_eos and ((@cur_buf < 0) or (@cur_buf == @buf_tail_idx)))
    end
  
    BufSize = 1024 * 8
  end

  # Buffered IO.
  #
  # EXAMPLE
  #   # File 'bigdata' could be a giga-byte size one!
  #   buf = CSV::IOBuf.new(File.open('bigdata', 'rb'))
  #   CSV::Reader.new(buf).each do |row|
  #     p row
  #     break if row[0].data == 'admin'
  #   end
  #
  class IOBuf < StreamBuf
    def initialize(s)
      @s = s
      super()
    end
  
    def close
      terminate
    end

  private

    def read(size)
      @s.read(size)
    end
 
    def terminate
      super()
    end
  end
end
PK      Z\y|8X  X    find.rbnu [        #
# find.rb: the Find module for processing all files under a given directory.
#

#
# The +Find+ module supports the top-down traversal of a set of file paths.
#
# For example, to total the size of all files under your home directory,
# ignoring anything in a "dot" directory (e.g. $HOME/.ssh):
#
#   require 'find'
#
#   total_size = 0
#
#   Find.find(ENV["HOME"]) do |path|
#     if FileTest.directory?(path)
#       if File.basename(path)[0] == ?.
#         Find.prune       # Don't look any further into this directory.
#       else
#         next
#       end
#     else
#       total_size += FileTest.size(path)
#     end
#   end
#
module Find

  #
  # Calls the associated block with the name of every file and directory listed
  # as arguments, then recursively on their subdirectories, and so on.
  #
  # See the +Find+ module documentation for an example.
  #
  def find(*paths) # :yield: path
    paths.collect!{|d| d.dup}
    while file = paths.shift
      catch(:prune) do
	yield file.dup.taint
        next unless File.exist? file
	begin
	  if File.lstat(file).directory? then
	    d = Dir.open(file)
	    begin
	      for f in d
		next if f == "." or f == ".."
		if File::ALT_SEPARATOR and file =~ /^(?:[\/\\]|[A-Za-z]:[\/\\]?)$/ then
		  f = file + f
		elsif file == "/" then
		  f = "/" + f
		else
		  f = File.join(file, f)
		end
		paths.unshift f.untaint
	      end
	    ensure
	      d.close
	    end
	  end
        rescue Errno::ENOENT, Errno::EACCES
	end
      end
    end
  end

  #
  # Skips the current file or directory, restarting the loop with the next
  # entry. If the current file is a directory, that directory will not be
  # recursively entered. Meaningful only within the block associated with
  # Find::find.
  #
  # See the +Find+ module documentation for an example.
  #
  def prune
    throw :prune
  end

  module_function :find, :prune
end
PK      Z\_&ݧ      forwardable.rbnu [        # = forwardable - Support for the Delegation Pattern
#
#    $Release Version: 1.1$
#    $Revision: 16857 $
#    $Date: 2008-06-06 17:05:24 +0900 (Fri, 06 Jun 2008) $
#    by Keiju ISHITSUKA(keiju@ishitsuka.com)
#
#    Documentation by James Edward Gray II and Gavin Sinclair
#
# == Introduction
#
# This library allows you delegate method calls to an object, on a method by
# method basis.  You can use Forwardable to setup this delegation at the class
# level, or SingleForwardable to handle it at the object level.
#
# == Notes
#
# Be advised, RDoc will not detect delegated methods.
#
# <b>forwardable.rb provides single-method delegation via the
# def_delegator() and def_delegators() methods.  For full-class
# delegation via DelegateClass(), see delegate.rb.</b>
#
# == Examples
#
# === Forwardable
#
# Forwardable makes building a new class based on existing work, with a proper
# interface, almost trivial.  We want to rely on what has come before obviously,
# but with delegation we can take just the methods we need and even rename them
# as appropriate.  In many cases this is preferable to inheritance, which gives
# us the entire old interface, even if much of it isn't needed.
#
#   class Queue
#     extend Forwardable
#     
#     def initialize
#       @q = [ ]    # prepare delegate object
#     end
#     
#     # setup preferred interface, enq() and deq()...
#     def_delegator :@q, :push, :enq
#     def_delegator :@q, :shift, :deq
#     
#     # support some general Array methods that fit Queues well
#     def_delegators :@q, :clear, :first, :push, :shift, :size
#   end
# 
#   q = Queue.new
#   q.enq 1, 2, 3, 4, 5
#   q.push 6
# 
#   q.shift    # => 1
#   while q.size > 0
#     puts q.deq
#   end
# 
#   q.enq "Ruby", "Perl", "Python"
#   puts q.first
#   q.clear
#   puts q.first
#
# <i>Prints:</i>
#
#   2
#   3
#   4
#   5
#   6
#   Ruby
#   nil
#
# === SingleForwardable
#
#    printer = String.new
#    printer.extend SingleForwardable        # prepare object for delegation
#    printer.def_delegator "STDOUT", "puts"  # add delegation for STDOUT.puts()
#    printer.puts "Howdy!"
#
# <i>Prints:</i>
#
#    Howdy!

#
# The Forwardable module provides delegation of specified
# methods to a designated object, using the methods #def_delegator
# and #def_delegators.
#
# For example, say you have a class RecordCollection which
# contains an array <tt>@records</tt>.  You could provide the lookup method
# #record_number(), which simply calls #[] on the <tt>@records</tt>
# array, like this:
#
#   class RecordCollection
#     extend Forwardable
#     def_delegator :@records, :[], :record_number
#   end
#
# Further, if you wish to provide the methods #size, #<<, and #map,
# all of which delegate to @records, this is how you can do it:
#
#   class RecordCollection
#     # extend Forwardable, but we did that above
#     def_delegators :@records, :size, :<<, :map
#   end
#
# Also see the example at forwardable.rb.
#
module Forwardable

  @debug = nil
  class<<self
    # force Forwardable to show up in stack backtraces of delegated methods
    attr_accessor :debug
  end

  #
  # Shortcut for defining multiple delegator methods, but with no
  # provision for using a different name.  The following two code
  # samples have the same effect:
  #
  #   def_delegators :@records, :size, :<<, :map
  #
  #   def_delegator :@records, :size
  #   def_delegator :@records, :<<
  #   def_delegator :@records, :map
  #
  # See the examples at Forwardable and forwardable.rb.
  #
  def def_instance_delegators(accessor, *methods)
    for method in methods
      def_instance_delegator(accessor, method)
    end
  end

  #
  # Defines a method _method_ which delegates to _obj_ (i.e. it calls
  # the method of the same name in _obj_).  If _new_name_ is
  # provided, it is used as the name for the delegate method.
  #
  # See the examples at Forwardable and forwardable.rb.
  #
  def def_instance_delegator(accessor, method, ali = method)
    accessor = accessor.id2name if accessor.kind_of?(Integer)
    method = method.id2name if method.kind_of?(Integer)
    ali = ali.id2name if ali.kind_of?(Integer)

    module_eval(<<-EOS, "(__FORWARDABLE__)", 1)
      def #{ali}(*args, &block)
	begin
	  #{accessor}.__send__(:#{method}, *args, &block)
	rescue Exception
	  $@.delete_if{|s| /^\\(__FORWARDABLE__\\):/ =~ s} unless Forwardable::debug
	  Kernel::raise
	end
      end
    EOS
  end

  alias def_delegators def_instance_delegators
  alias def_delegator def_instance_delegator
end

#
# The SingleForwardable module provides delegation of specified
# methods to a designated object, using the methods #def_delegator
# and #def_delegators.  This module is similar to Forwardable, but it works on
# objects themselves, instead of their defining classes.
#
# Also see the example at forwardable.rb.
#
module SingleForwardable
  #
  # Shortcut for defining multiple delegator methods, but with no
  # provision for using a different name.  The following two code
  # samples have the same effect:
  #
  #   single_forwardable.def_delegators :@records, :size, :<<, :map
  #
  #   single_forwardable.def_delegator :@records, :size
  #   single_forwardable.def_delegator :@records, :<<
  #   single_forwardable.def_delegator :@records, :map
  #
  # See the example at forwardable.rb.
  #
  def def_singleton_delegators(accessor, *methods)
    for method in methods
      def_singleton_delegator(accessor, method)
    end
  end

  #
  # Defines a method _method_ which delegates to _obj_ (i.e. it calls
  # the method of the same name in _obj_).  If _new_name_ is
  # provided, it is used as the name for the delegate method.
  #
  # See the example at forwardable.rb.
  #
  def def_singleton_delegator(accessor, method, ali = method)
    accessor = accessor.id2name if accessor.kind_of?(Integer)
    method = method.id2name if method.kind_of?(Integer)
    ali = ali.id2name if ali.kind_of?(Integer)

    instance_eval(<<-EOS, "(__FORWARDABLE__)", 1)
       def #{ali}(*args, &block)
	 begin
	   #{accessor}.__send__(:#{method}, *args,&block)
	 rescue Exception
	   $@.delete_if{|s| /^\\(__FORWARDABLE__\\):/ =~ s} unless Forwardable::debug
	   Kernel::raise
	 end
       end
    EOS
  end

  alias def_delegators def_singleton_delegators
  alias def_delegator def_singleton_delegator
end
PK     Z\H&      xsd/codegen.rbnu [        # XSD4R - Generating code library
# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/codegen/gensupport'
require 'xsd/codegen/moduledef'
require 'xsd/codegen/classdef'
require 'xsd/codegen/methoddef'
PK     Z\@{ژ      xsd/namedelements.rbnu [        # XSD4R - WSDL named element collection.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


module XSD


class NamedElements
  include Enumerable

  def initialize
    @elements = []
    @cache = {}
  end

  def dup
    o = NamedElements.new
    o.elements = @elements.dup
    o
  end

  def freeze
    super
    @elements.freeze
    self
  end

  def empty?
    size == 0
  end

  def size
    @elements.size
  end

  def [](idx)
    if idx.is_a?(Numeric)
      @elements[idx]
    else
      @cache[idx] ||= @elements.find { |item| item.name == idx }
    end
  end

  def find_name(name)
    @elements.find { |item| item.name.name == name }
  end

  def keys
    collect { |element| element.name }
  end

  def each
    @elements.each do |element|
      yield(element)
    end
  end

  def <<(rhs)
    @elements << rhs
    self
  end
  
  def delete(rhs)
    @elements.delete(rhs)
  end

  def +(rhs)
    o = NamedElements.new
    o.elements = @elements + rhs.elements
    o
  end

  def concat(rhs)
    @elements.concat(rhs.elements)
    self
  end

  Empty = NamedElements.new.freeze

protected

  def elements=(rhs)
    @elements = rhs
  end

  def elements
    @elements
  end
end

end
PK     Z\LY      xsd/datatypes1999.rbnu [        # XSD4R - XML Schema Datatype 1999 support
# Copyright (C) 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/datatypes'


module XSD
  Namespace.replace('http://www.w3.org/1999/XMLSchema')
  InstanceNamespace.replace('http://www.w3.org/1999/XMLSchema-instance')
  AnyTypeLiteral.replace('ur-type')
  AnySimpleTypeLiteral.replace('ur-type')
  NilLiteral.replace('null')
  NilValue.replace('1')
  DateTimeLiteral.replace('timeInstant')
end
PK     Z\'t`  `    xsd/datatypes.rbnu [        # XSD4R - XML Schema Datatype implementation.
# Copyright (C) 2000, 2001, 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/qname'
require 'xsd/charset'
require 'uri'


###
## XMLSchamaDatatypes general definitions.
#
module XSD


Namespace = 'http://www.w3.org/2001/XMLSchema'
InstanceNamespace = 'http://www.w3.org/2001/XMLSchema-instance'

AttrType = 'type'
NilValue = 'true'

AnyTypeLiteral = 'anyType'
AnySimpleTypeLiteral = 'anySimpleType'
NilLiteral = 'nil'
StringLiteral = 'string'
BooleanLiteral = 'boolean'
DecimalLiteral = 'decimal'
FloatLiteral = 'float'
DoubleLiteral = 'double'
DurationLiteral = 'duration'
DateTimeLiteral = 'dateTime'
TimeLiteral = 'time'
DateLiteral = 'date'
GYearMonthLiteral = 'gYearMonth'
GYearLiteral = 'gYear'
GMonthDayLiteral = 'gMonthDay'
GDayLiteral = 'gDay'
GMonthLiteral = 'gMonth'
HexBinaryLiteral = 'hexBinary'
Base64BinaryLiteral = 'base64Binary'
AnyURILiteral = 'anyURI'
QNameLiteral = 'QName'

NormalizedStringLiteral = 'normalizedString'
#3.3.2 token
#3.3.3 language
#3.3.4 NMTOKEN
#3.3.5 NMTOKENS
#3.3.6 Name
#3.3.7 NCName
#3.3.8 ID
#3.3.9 IDREF
#3.3.10 IDREFS
#3.3.11 ENTITY
#3.3.12 ENTITIES
IntegerLiteral = 'integer'
NonPositiveIntegerLiteral = 'nonPositiveInteger'
NegativeIntegerLiteral = 'negativeInteger'
LongLiteral = 'long'
IntLiteral = 'int'
ShortLiteral = 'short'
ByteLiteral = 'byte'
NonNegativeIntegerLiteral = 'nonNegativeInteger'
UnsignedLongLiteral = 'unsignedLong'
UnsignedIntLiteral = 'unsignedInt'
UnsignedShortLiteral = 'unsignedShort'
UnsignedByteLiteral = 'unsignedByte'
PositiveIntegerLiteral = 'positiveInteger'

AttrTypeName = QName.new(InstanceNamespace, AttrType)
AttrNilName = QName.new(InstanceNamespace, NilLiteral)

AnyTypeName = QName.new(Namespace, AnyTypeLiteral)
AnySimpleTypeName = QName.new(Namespace, AnySimpleTypeLiteral)

class Error < StandardError; end
class ValueSpaceError < Error; end


###
## The base class of all datatypes with Namespace.
#
class NSDBase
  @@types = []

  attr_accessor :type

  def self.inherited(klass)
    @@types << klass
  end

  def self.types
    @@types
  end

  def initialize
  end

  def init(type)
    @type = type
  end
end


###
## The base class of XSD datatypes.
#
class XSDAnySimpleType < NSDBase
  include XSD
  Type = QName.new(Namespace, AnySimpleTypeLiteral)

  # @data represents canonical space (ex. Integer: 123).
  attr_reader :data
  # @is_nil represents this data is nil or not.
  attr_accessor :is_nil

  def initialize(value = nil)
    init(Type, value)
  end

  # true or raise
  def check_lexical_format(value)
    screen_data(value)
    true
  end

  # set accepts a string which follows lexical space (ex. String: "+123"), or
  # an object which follows canonical space (ex. Integer: 123).
  def set(value)
    if value.nil?
      @is_nil = true
      @data = nil
      _set(nil)
    else
      @is_nil = false
      _set(screen_data(value))
    end
  end

  # to_s creates a string which follows lexical space (ex. String: "123").
  def to_s()
    if @is_nil
      ""
    else
      _to_s
    end
  end

private

  def init(type, value)
    super(type)
    set(value)
  end

  # raises ValueSpaceError if check failed
  def screen_data(value)
    value
  end

  def _set(value)
    @data = value
  end

  def _to_s
    @data.to_s
  end
end

class XSDNil < XSDAnySimpleType
  Type = QName.new(Namespace, NilLiteral)
  Value = 'true'

  def initialize(value = nil)
    init(Type, value)
  end
end


###
## Primitive datatypes.
#
class XSDString < XSDAnySimpleType
  Type = QName.new(Namespace, StringLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data(value)
    unless XSD::Charset.is_ces(value, XSD::Charset.encoding)
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
    end
    value
  end
end

class XSDBoolean < XSDAnySimpleType
  Type = QName.new(Namespace, BooleanLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data(value)
    if value.is_a?(String)
      str = value.strip
      if str == 'true' || str == '1'
	true
      elsif str == 'false' || str == '0'
	false
      else
	raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
      end
    else
      value ? true : false
    end
  end
end

class XSDDecimal < XSDAnySimpleType
  Type = QName.new(Namespace, DecimalLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

  def nonzero?
    (@number != '0')
  end

private

  def screen_data(d)
    if d.is_a?(String)
      # Integer("00012") => 10 in Ruby.
      d.sub!(/^([+\-]?)0*(?=\d)/, "\\1")
    end
    screen_data_str(d)
  end

  def screen_data_str(str)
    /^([+\-]?)(\d*)(?:\.(\d*)?)?$/ =~ str.to_s.strip
    unless Regexp.last_match
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
    end
    sign = $1 || '+'
    int_part = $2
    frac_part = $3
    int_part = '0' if int_part.empty?
    frac_part = frac_part ? frac_part.sub(/0+$/, '') : ''
    point = - frac_part.size
    number = int_part + frac_part
    # normalize
    if sign == '+'
      sign = ''
    elsif sign == '-'
      if number == '0'
	sign = ''
      end
    end
    [sign, point, number]
  end

  def _set(data)
    if data.nil?
      @sign = @point = @number = @data = nil
      return
    end
    @sign, @point, @number = data
    @data = _to_s
    @data.freeze
  end

  # 0.0 -> 0; right?
  def _to_s
    str = @number.dup
    if @point.nonzero?
      str[@number.size + @point, 0] = '.'
    end
    @sign + str
  end
end

module FloatConstants
  NaN = 0.0/0.0
  POSITIVE_INF = +1.0/0.0
  NEGATIVE_INF = -1.0/0.0
  POSITIVE_ZERO = +1.0/POSITIVE_INF
  NEGATIVE_ZERO = -1.0/POSITIVE_INF
  MIN_POSITIVE_SINGLE = 2.0 ** -149
end

class XSDFloat < XSDAnySimpleType
  include FloatConstants
  Type = QName.new(Namespace, FloatLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data(value)
    # "NaN".to_f => 0 in some environment.  libc?
    if value.is_a?(Float)
      return narrow32bit(value)
    end
    str = value.to_s.strip
    if str == 'NaN'
      NaN
    elsif str == 'INF'
      POSITIVE_INF
    elsif str == '-INF'
      NEGATIVE_INF
    else
      if /^[+\-\.\deE]+$/ !~ str
	raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
      end
      # Float("-1.4E") might fail on some system.
      str << '0' if /e$/i =~ str
      begin
  	return narrow32bit(Float(str))
      rescue ArgumentError
  	raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
      end
    end
  end

  def _to_s
    if @data.nan?
      'NaN'
    elsif @data.infinite? == 1
      'INF'
    elsif @data.infinite? == -1
      '-INF'
    else
      sign = XSDFloat.positive?(@data) ? '+' : '-'
      sign + sprintf("%.10g", @data.abs).sub(/[eE]([+-])?0+/) { 'e' + $1 }
    end
  end

  # Convert to single-precision 32-bit floating point value.
  def narrow32bit(f)
    if f.nan? || f.infinite?
      f
    elsif f.abs < MIN_POSITIVE_SINGLE
      XSDFloat.positive?(f) ? POSITIVE_ZERO : NEGATIVE_ZERO
    else
      f
    end
  end

  def self.positive?(value)
    (1 / value) > 0.0
  end
end

# Ruby's Float is double-precision 64-bit floating point value.
class XSDDouble < XSDAnySimpleType
  include FloatConstants
  Type = QName.new(Namespace, DoubleLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data(value)
    # "NaN".to_f => 0 in some environment.  libc?
    if value.is_a?(Float)
      return value
    end
    str = value.to_s.strip
    if str == 'NaN'
      NaN
    elsif str == 'INF'
      POSITIVE_INF
    elsif str == '-INF'
      NEGATIVE_INF
    else
      begin
	return Float(str)
      rescue ArgumentError
	# '1.4e' cannot be parsed on some architecture.
	if /e\z/i =~ str
	  begin
	    return Float(str + '0')
	  rescue ArgumentError
	    raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
	  end
	else
	  raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
	end
      end
    end
  end

  def _to_s
    if @data.nan?
      'NaN'
    elsif @data.infinite? == 1
      'INF'
    elsif @data.infinite? == -1
      '-INF'
    else
      sign = (1 / @data > 0.0) ? '+' : '-'
      sign + sprintf("%.16g", @data.abs).sub(/[eE]([+-])?0+/) { 'e' + $1 }
    end
  end
end

class XSDDuration < XSDAnySimpleType
  Type = QName.new(Namespace, DurationLiteral)

  attr_accessor :sign
  attr_accessor :year
  attr_accessor :month
  attr_accessor :day
  attr_accessor :hour
  attr_accessor :min
  attr_accessor :sec

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data(value)
    /^([+\-]?)P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/ =~ value.to_s.strip
    unless Regexp.last_match
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
    end
    if ($5 and ((!$2 and !$3 and !$4) or (!$6 and !$7 and !$8)))
      # Should we allow 'PT5S' here?
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
    end
    sign = $1
    year = $2.to_i
    month = $3.to_i
    day = $4.to_i
    hour = $6.to_i
    min = $7.to_i
    sec = $8 ? XSDDecimal.new($8) : 0
    [sign, year, month, day, hour, min, sec]
  end

  def _set(data)
    if data.nil?
      @sign = @year = @month = @day = @hour = @min = @sec = @data = nil
      return
    end
    @sign, @year, @month, @day, @hour, @min, @sec = data
    @data = _to_s
    @data.freeze
  end

  def _to_s
    str = ''
    str << @sign if @sign
    str << 'P'
    l = ''
    l << "#{ @year }Y" if @year.nonzero?
    l << "#{ @month }M" if @month.nonzero?
    l << "#{ @day }D" if @day.nonzero?
    r = ''
    r << "#{ @hour }H" if @hour.nonzero?
    r << "#{ @min }M" if @min.nonzero?
    r << "#{ @sec }S" if @sec.nonzero?
    str << l
    if l.empty?
      str << "0D"
    end
    unless r.empty?
      str << "T" << r
    end
    str
  end
end


require 'rational'
require 'date'

module XSDDateTimeImpl
  SecInDay = 86400	# 24 * 60 * 60

  def to_obj(klass)
    if klass == Time
      to_time
    elsif klass == Date
      to_date
    elsif klass == DateTime
      to_datetime
    else
      nil
    end
  end

  def to_time
    begin
      if @data.offset * SecInDay == Time.now.utc_offset
        d = @data
	usec = (d.sec_fraction * SecInDay * 1000000).round
        Time.local(d.year, d.month, d.mday, d.hour, d.min, d.sec, usec)
      else
        d = @data.newof
	usec = (d.sec_fraction * SecInDay * 1000000).round
        Time.gm(d.year, d.month, d.mday, d.hour, d.min, d.sec, usec)
      end
    rescue ArgumentError
      nil
    end
  end

  def to_date
    Date.new0(@data.class.jd_to_ajd(@data.jd, 0, 0), 0, @data.start)
  end

  def to_datetime
    data
  end

  def tz2of(str)
    /^(?:Z|(?:([+\-])(\d\d):(\d\d))?)$/ =~ str
    sign = $1
    hour = $2.to_i
    min = $3.to_i

    of = case sign
      when '+'
	of = +(hour.to_r * 60 + min) / 1440	# 24 * 60
      when '-'
	of = -(hour.to_r * 60 + min) / 1440	# 24 * 60
      else
	0
      end
    of
  end

  def of2tz(offset)
    diffmin = offset * 24 * 60
    if diffmin.zero?
      'Z'
    else
      ((diffmin < 0) ? '-' : '+') << format('%02d:%02d',
    	(diffmin.abs / 60.0).to_i, (diffmin.abs % 60.0).to_i)
    end
  end

  def screen_data(t)
    # convert t to a DateTime as an internal representation.
    if t.respond_to?(:to_datetime)      # 1.9 or later
      t.to_datetime
    elsif t.is_a?(DateTime)
      t
    elsif t.is_a?(Date)
      t = screen_data_str(t)
      t <<= 12 if t.year < 0
      t
    elsif t.is_a?(Time)
      jd = DateTime.civil_to_jd(t.year, t.mon, t.mday, DateTime::ITALY)
      fr = DateTime.time_to_day_fraction(t.hour, t.min, [t.sec, 59].min) +
        t.usec.to_r / 1000000 / SecInDay
      of = t.utc_offset.to_r / SecInDay
      DateTime.new0(DateTime.jd_to_ajd(jd, fr, of), of, DateTime::ITALY)
    else
      screen_data_str(t)
    end
  end

  def add_tz(s)
    s + of2tz(@data.offset)
  end
end

class XSDDateTime < XSDAnySimpleType
  include XSDDateTimeImpl
  Type = QName.new(Namespace, DateTimeLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data_str(t)
    /^([+\-]?\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip
    unless Regexp.last_match
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
    end
    if $1 == '0000'
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
    end
    year = $1.to_i
    if year < 0
      year += 1
    end
    mon = $2.to_i
    mday = $3.to_i
    hour = $4.to_i
    min = $5.to_i
    sec = $6.to_i
    secfrac = $7
    zonestr = $8
    data = DateTime.civil(year, mon, mday, hour, min, sec, tz2of(zonestr))
    if secfrac
      diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay
      data += diffday
      # FYI: new0 and jd_to_rjd are not necessary to use if you don't have
      # exceptional reason.
    end
    [data, secfrac]
  end

  def _set(data)
    if data.nil?
      @data = @secfrac = nil
      return
    end
    @data, @secfrac = data
  end

  def _to_s
    year = (@data.year > 0) ? @data.year : @data.year - 1
    s = format('%.4d-%02d-%02dT%02d:%02d:%02d',
      year, @data.mon, @data.mday, @data.hour, @data.min, @data.sec)
    if @data.sec_fraction.nonzero?
      if @secfrac
  	s << ".#{ @secfrac }"
      else
	s << sprintf("%.16f",
          (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '')
      end
    end
    add_tz(s)
  end
end

class XSDTime < XSDAnySimpleType
  include XSDDateTimeImpl
  Type = QName.new(Namespace, TimeLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data_str(t)
    /^(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip
    unless Regexp.last_match
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
    end
    hour = $1.to_i
    min = $2.to_i
    sec = $3.to_i
    secfrac = $4
    zonestr = $5
    data = DateTime.civil(1, 1, 1, hour, min, sec, tz2of(zonestr))
    if secfrac
      diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay
      data += diffday
    end
    [data, secfrac]
  end

  def _set(data)
    if data.nil?
      @data = @secfrac = nil
      return
    end
    @data, @secfrac = data
  end

  def _to_s
    s = format('%02d:%02d:%02d', @data.hour, @data.min, @data.sec)
    if @data.sec_fraction.nonzero?
      if @secfrac
  	s << ".#{ @secfrac }"
      else
	s << sprintf("%.16f",
          (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '')
      end
    end
    add_tz(s)
  end
end

class XSDDate < XSDAnySimpleType
  include XSDDateTimeImpl
  Type = QName.new(Namespace, DateLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data_str(t)
    /^([+\-]?\d{4,})-(\d\d)-(\d\d)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip
    unless Regexp.last_match
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
    end
    year = $1.to_i
    if year < 0
      year += 1
    end
    mon = $2.to_i
    mday = $3.to_i
    zonestr = $4
    DateTime.civil(year, mon, mday, 0, 0, 0, tz2of(zonestr))
  end

  def _to_s
    year = (@data.year > 0) ? @data.year : @data.year - 1
    s = format('%.4d-%02d-%02d', year, @data.mon, @data.mday)
    add_tz(s)
  end
end

class XSDGYearMonth < XSDAnySimpleType
  include XSDDateTimeImpl
  Type = QName.new(Namespace, GYearMonthLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data_str(t)
    /^([+\-]?\d{4,})-(\d\d)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip
    unless Regexp.last_match
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
    end
    year = $1.to_i
    if year < 0
      year += 1
    end
    mon = $2.to_i
    zonestr = $3
    DateTime.civil(year, mon, 1, 0, 0, 0, tz2of(zonestr))
  end

  def _to_s
    year = (@data.year > 0) ? @data.year : @data.year - 1
    s = format('%.4d-%02d', year, @data.mon)
    add_tz(s)
  end
end

class XSDGYear < XSDAnySimpleType
  include XSDDateTimeImpl
  Type = QName.new(Namespace, GYearLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data_str(t)
    /^([+\-]?\d{4,})(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip
    unless Regexp.last_match
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
    end
    year = $1.to_i
    if year < 0
      year += 1
    end
    zonestr = $2
    DateTime.civil(year, 1, 1, 0, 0, 0, tz2of(zonestr))
  end

  def _to_s
    year = (@data.year > 0) ? @data.year : @data.year - 1
    s = format('%.4d', year)
    add_tz(s)
  end
end

class XSDGMonthDay < XSDAnySimpleType
  include XSDDateTimeImpl
  Type = QName.new(Namespace, GMonthDayLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data_str(t)
    /^(\d\d)-(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip
    unless Regexp.last_match
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
    end
    mon = $1.to_i
    mday = $2.to_i
    zonestr = $3
    DateTime.civil(1, mon, mday, 0, 0, 0, tz2of(zonestr))
  end

  def _to_s
    s = format('%02d-%02d', @data.mon, @data.mday)
    add_tz(s)
  end
end

class XSDGDay < XSDAnySimpleType
  include XSDDateTimeImpl
  Type = QName.new(Namespace, GDayLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data_str(t)
    /^(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip
    unless Regexp.last_match
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
    end
    mday = $1.to_i
    zonestr = $2
    DateTime.civil(1, 1, mday, 0, 0, 0, tz2of(zonestr))
  end

  def _to_s
    s = format('%02d', @data.mday)
    add_tz(s)
  end
end

class XSDGMonth < XSDAnySimpleType
  include XSDDateTimeImpl
  Type = QName.new(Namespace, GMonthLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data_str(t)
    /^(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip
    unless Regexp.last_match
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
    end
    mon = $1.to_i
    zonestr = $2
    DateTime.civil(1, mon, 1, 0, 0, 0, tz2of(zonestr))
  end

  def _to_s
    s = format('%02d', @data.mon)
    add_tz(s)
  end
end

class XSDHexBinary < XSDAnySimpleType
  Type = QName.new(Namespace, HexBinaryLiteral)

  # String in Ruby could be a binary.
  def initialize(value = nil)
    init(Type, value)
  end

  def set_encoded(value)
    if /^[0-9a-fA-F]*$/ !~ value
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
    end
    @data = String.new(value).strip
    @is_nil = false
  end

  def string
    [@data].pack("H*")
  end

private

  def screen_data(value)
    value.unpack("H*")[0].tr('a-f', 'A-F')
  end
end

class XSDBase64Binary < XSDAnySimpleType
  Type = QName.new(Namespace, Base64BinaryLiteral)

  # String in Ruby could be a binary.
  def initialize(value = nil)
    init(Type, value)
  end

  def set_encoded(value)
    if /^[A-Za-z0-9+\/=]*$/ !~ value
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
    end
    @data = String.new(value).strip
    @is_nil = false
  end

  def string
    @data.unpack("m")[0]
  end

private

  def screen_data(value)
    [value].pack("m").strip
  end
end

class XSDAnyURI < XSDAnySimpleType
  Type = QName.new(Namespace, AnyURILiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data(value)
    begin
      URI.parse(value.to_s.strip)
    rescue URI::InvalidURIError
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
    end
  end
end

class XSDQName < XSDAnySimpleType
  Type = QName.new(Namespace, QNameLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data(value)
    /^(?:([^:]+):)?([^:]+)$/ =~ value.to_s.strip
    unless Regexp.last_match
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
    end
    prefix = $1
    localpart = $2
    [prefix, localpart]
  end

  def _set(data)
    if data.nil?
      @prefix = @localpart = @data = nil
      return
    end
    @prefix, @localpart = data
    @data = _to_s
    @data.freeze
  end

  def _to_s
    if @prefix
      "#{ @prefix }:#{ @localpart }"
    else
      "#{ @localpart }"
    end
  end
end


###
## Derived types
#
class XSDNormalizedString < XSDString
  Type = QName.new(Namespace, NormalizedStringLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data(value)
    if /[\t\r\n]/ =~ value
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
    end
    super
  end
end

class XSDInteger < XSDDecimal
  Type = QName.new(Namespace, IntegerLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def screen_data_str(str)
    begin
      data = Integer(str)
    rescue ArgumentError
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
    end
    unless validate(data)
      raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
    end
    data
  end

  def _set(value)
    @data = value
  end

  def _to_s()
    @data.to_s
  end

  def validate(v)
    max = maxinclusive
    min = mininclusive
    (max.nil? or v <= max) and (min.nil? or v >= min)
  end

  def maxinclusive
    nil
  end

  def mininclusive
    nil
  end

  PositiveMinInclusive = 1
  def positive(v)
    PositiveMinInclusive <= v
  end
end

class XSDNonPositiveInteger < XSDInteger
  Type = QName.new(Namespace, NonPositiveIntegerLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def maxinclusive
    0
  end

  def mininclusive
    nil
  end
end

class XSDNegativeInteger < XSDNonPositiveInteger
  Type = QName.new(Namespace, NegativeIntegerLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def maxinclusive
    -1
  end

  def mininclusive
    nil
  end
end

class XSDLong < XSDInteger
  Type = QName.new(Namespace, LongLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def maxinclusive
    +9223372036854775807
  end

  def mininclusive
    -9223372036854775808
  end
end

class XSDInt < XSDLong
  Type = QName.new(Namespace, IntLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def maxinclusive
    +2147483647
  end

  def mininclusive
    -2147483648
  end
end

class XSDShort < XSDInt
  Type = QName.new(Namespace, ShortLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def maxinclusive
    +32767
  end

  def mininclusive
    -32768
  end
end

class XSDByte < XSDShort
  Type = QName.new(Namespace, ByteLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def maxinclusive
    +127
  end

  def mininclusive
    -128
  end
end

class XSDNonNegativeInteger < XSDInteger
  Type = QName.new(Namespace, NonNegativeIntegerLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def maxinclusive
    nil
  end

  def mininclusive
    0
  end
end

class XSDUnsignedLong < XSDNonNegativeInteger
  Type = QName.new(Namespace, UnsignedLongLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def maxinclusive
    +18446744073709551615
  end

  def mininclusive
    0
  end
end

class XSDUnsignedInt < XSDUnsignedLong
  Type = QName.new(Namespace, UnsignedIntLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def maxinclusive
    +4294967295
  end

  def mininclusive
    0
  end
end

class XSDUnsignedShort < XSDUnsignedInt
  Type = QName.new(Namespace, UnsignedShortLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def maxinclusive
    +65535
  end

  def mininclusive
    0
  end
end

class XSDUnsignedByte < XSDUnsignedShort
  Type = QName.new(Namespace, UnsignedByteLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def maxinclusive
    +255
  end

  def mininclusive
    0
  end
end

class XSDPositiveInteger < XSDNonNegativeInteger
  Type = QName.new(Namespace, PositiveIntegerLiteral)

  def initialize(value = nil)
    init(Type, value)
  end

private

  def maxinclusive
    nil
  end

  def mininclusive
    1
  end
end


end
PK     Z\h      xsd/qname.rbnu [        # XSD4R - XML QName definition.
# Copyright (C) 2002, 2003, 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


module XSD


class QName
  attr_accessor :namespace
  attr_accessor :name
  attr_accessor :source

  def initialize(namespace = nil, name = nil)
    @namespace = namespace
    @name = name
    @source = nil
  end

  def dup_name(name)
    XSD::QName.new(@namespace, name)
  end

  def dump
    ns = @namespace.nil? ? 'nil' : @namespace.dump
    name = @name.nil? ? 'nil' : @name.dump
    "XSD::QName.new(#{ns}, #{name})"
  end

  def match(rhs)
    if rhs.namespace and (rhs.namespace != @namespace)
      return false
    end
    if rhs.name and (rhs.name != @name)
      return false
    end
    true
  end

  def ==(rhs)
    !rhs.nil? and @namespace == rhs.namespace and @name == rhs.name
  end

  def ===(rhs)
    (self == rhs)
  end

  def eql?(rhs)
    (self == rhs)
  end

  def hash
    @namespace.hash ^ @name.hash
  end
  
  def to_s
    "{#{ namespace }}#{ name }"
  end

  def inspect
    sprintf("#<%s:0x%x %s>", self.class.name, __id__,
      "{#{ namespace }}#{ name }")
  end

  NormalizedNameRegexp = /^\{([^}]*)\}(.*)$/
  def parse(str)
    NormalizedNameRegexp =~ str
    self.new($1, $2)
  end

  EMPTY = QName.new.freeze
end


end
PK     Z\OG      xsd/charset.rbnu [        # XSD4R - Charset handling library.
# Copyright (C) 2001, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


module XSD


module Charset
  @internal_encoding = $KCODE

  class XSDError < StandardError; end
  class CharsetError < XSDError; end
  class UnknownCharsetError < CharsetError; end
  class CharsetConversionError < CharsetError; end

public

  ###
  ## Maps
  #
  EncodingConvertMap = {}
  def Charset.init
    EncodingConvertMap[['UTF8', 'X_ISO8859_1']] =
      Proc.new { |str| str.unpack('U*').pack('C*') }
    EncodingConvertMap[['X_ISO8859_1', 'UTF8']] =
      Proc.new { |str| str.unpack('C*').pack('U*') }
    begin
      require 'xsd/iconvcharset'
      @internal_encoding = 'UTF8'
      sjtag = (/(mswin|bccwin|mingw|cygwin|emx)/ =~ RUBY_PLATFORM) ? 'cp932' :
        'shift_jis'
      EncodingConvertMap[['UTF8', 'EUC' ]] =
        Proc.new { |str| IconvCharset.safe_iconv("euc-jp", "utf-8", str) }
      EncodingConvertMap[['EUC' , 'UTF8']] =
        Proc.new { |str| IconvCharset.safe_iconv("utf-8", "euc-jp", str) }
      EncodingConvertMap[['EUC' , 'SJIS']] =
        Proc.new { |str| IconvCharset.safe_iconv(sjtag, "euc-jp", str) }
      EncodingConvertMap[['UTF8', 'SJIS']] =
        Proc.new { |str| IconvCharset.safe_iconv(sjtag, "utf-8", str) }
      EncodingConvertMap[['SJIS', 'UTF8']] =
        Proc.new { |str| IconvCharset.safe_iconv("utf-8", sjtag, str) }
      EncodingConvertMap[['SJIS', 'EUC' ]] =
        Proc.new { |str| IconvCharset.safe_iconv("euc-jp", sjtag, str) }
    rescue LoadError
      begin
       	require 'nkf'
	EncodingConvertMap[['EUC' , 'SJIS']] =
          Proc.new { |str| NKF.nkf('-sXm0', str) }
	EncodingConvertMap[['SJIS', 'EUC' ]] =
          Proc.new { |str| NKF.nkf('-eXm0', str) }
      rescue LoadError
      end
  
      begin
	require 'uconv'
	@internal_encoding = 'UTF8'
	EncodingConvertMap[['UTF8', 'EUC' ]] = Uconv.method(:u8toeuc)
	EncodingConvertMap[['UTF8', 'SJIS']] = Uconv.method(:u8tosjis)
	EncodingConvertMap[['EUC' , 'UTF8']] = Uconv.method(:euctou8)
	EncodingConvertMap[['SJIS', 'UTF8']] = Uconv.method(:sjistou8)
      rescue LoadError
      end
    end
  end
  self.init

  CharsetMap = {
    'NONE' => 'us-ascii',
    'EUC' => 'euc-jp',
    'SJIS' => 'shift_jis',
    'UTF8' => 'utf-8',
    'X_ISO_8859_1' => 'iso-8859-1',
    'X_UNKNOWN' => nil,
  }


  ###
  ## handlers
  #
  def Charset.encoding
    @internal_encoding
  end

  def Charset.encoding=(encoding)
    warn("xsd charset is set to #{encoding}") if $DEBUG
    @internal_encoding = encoding
  end

  def Charset.xml_encoding_label
    charset_label(@internal_encoding)
  end

  def Charset.encoding_to_xml(str, charset)
    encoding_conv(str, @internal_encoding, charset_str(charset))
  end

  def Charset.encoding_from_xml(str, charset)
    encoding_conv(str, charset_str(charset), @internal_encoding)
  end

  def Charset.encoding_conv(str, enc_from, enc_to)
    if enc_from == enc_to or enc_from == 'NONE' or enc_to == 'NONE'
      str
    elsif converter = EncodingConvertMap[[enc_from, enc_to]]
      converter.call(str)
    else
      raise CharsetConversionError.new(
	"Converter not found: #{enc_from} -> #{enc_to}")
    end
  end

  def Charset.charset_label(encoding)
    CharsetMap[encoding.upcase]
  end

  def Charset.charset_str(label)
    if CharsetMap.respond_to?(:key)
      CharsetMap.key(label.downcase) || 'X_UNKNOWN'
    else
      CharsetMap.index(label.downcase) || 'X_UNKNOWN'
    end
  end

  # us_ascii = '[\x00-\x7F]'
  us_ascii = '[\x9\xa\xd\x20-\x7F]'	# XML 1.0 restricted.
  USASCIIRegexp = Regexp.new("\\A#{us_ascii}*\\z", nil, "NONE")

  twobytes_euc = '(?:[\x8E\xA1-\xFE][\xA1-\xFE])'
  threebytes_euc = '(?:\x8F[\xA1-\xFE][\xA1-\xFE])'
  character_euc = "(?:#{us_ascii}|#{twobytes_euc}|#{threebytes_euc})"
  EUCRegexp = Regexp.new("\\A#{character_euc}*\\z", nil, "NONE")

  # onebyte_sjis = '[\x00-\x7F\xA1-\xDF]'
  onebyte_sjis = '[\x9\xa\xd\x20-\x7F\xA1-\xDF]'	# XML 1.0 restricted.
  twobytes_sjis = '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'
  character_sjis = "(?:#{onebyte_sjis}|#{twobytes_sjis})"
  SJISRegexp = Regexp.new("\\A#{character_sjis}*\\z", nil, "NONE")

  # 0xxxxxxx
  # 110yyyyy 10xxxxxx
  twobytes_utf8 = '(?:[\xC0-\xDF][\x80-\xBF])'
  # 1110zzzz 10yyyyyy 10xxxxxx
  threebytes_utf8 = '(?:[\xE0-\xEF][\x80-\xBF][\x80-\xBF])'
  # 11110uuu 10uuuzzz 10yyyyyy 10xxxxxx
  fourbytes_utf8 = '(?:[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF])'
  character_utf8 =
    "(?:#{us_ascii}|#{twobytes_utf8}|#{threebytes_utf8}|#{fourbytes_utf8})"
  UTF8Regexp = Regexp.new("\\A#{character_utf8}*\\z", nil, "NONE")

  def Charset.is_us_ascii(str)
    USASCIIRegexp =~ str
  end

  def Charset.is_utf8(str)
    UTF8Regexp =~ str
  end

  def Charset.is_euc(str)
    EUCRegexp =~ str
  end

  def Charset.is_sjis(str)
    SJISRegexp =~ str
  end

  def Charset.is_ces(str, code = $KCODE)
    case code
    when 'NONE'
      is_us_ascii(str)
    when 'UTF8'
      is_utf8(str)
    when 'EUC'
      is_euc(str)
    when 'SJIS'
      is_sjis(str)
    else
      raise UnknownCharsetError.new("Unknown charset: #{code}")
    end
  end
end


end
PK     Z\E+      xsd/iconvcharset.rbnu [        # XSD4R - Charset handling with iconv.
# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'iconv'


module XSD


class IconvCharset
  def self.safe_iconv(to, from, str)
    iconv = Iconv.new(to, from)
    out = ""
    begin
      out << iconv.iconv(str)
    rescue Iconv::IllegalSequence => e
      out << e.success
      ch, str = e.failed.split(//, 2)
      out << '?'
      warn("Failed to convert #{ch}")
      retry
    end
    return out
  end
end


end
PK     Z\o]      xsd/xmlparser.rbnu [        # XSD4R - XML Instance parser library.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/xmlparser/parser'


module XSD


module XMLParser
  def create_parser(host, opt)
    XSD::XMLParser::Parser.create_parser(host, opt)
  end
  module_function :create_parser

  # $1 is necessary.
  NSParseRegexp = Regexp.new('^xmlns:?(.*)$')

  def filter_ns(ns, attrs)
    return attrs if attrs.nil? or attrs.empty?
    newattrs = {}
    attrs.each do |key, value|
      if (NSParseRegexp =~ key)
	# '' means 'default namespace'.
	tag = $1 || ''
	ns.assign(value, tag)
      else
	newattrs[key] = value
      end
    end
    newattrs
  end
  module_function :filter_ns
end


end


# Try to load XML processor.
loaded = false
[
  'xsd/xmlparser/xmlparser',
  'xsd/xmlparser/xmlscanner',
  'xsd/xmlparser/rexmlparser',
].each do |lib|
  begin
    require lib
    loaded = true
    break
  rescue LoadError
  end
end
unless loaded
  raise RuntimeError.new("XML processor module not found.")
end
PK     Z\b )  )    xsd/codegen/classdef.rbnu [        # XSD4R - Generating class definition code
# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/codegen/gensupport'
require 'xsd/codegen/moduledef'
require 'xsd/codegen/methoddef'


module XSD
module CodeGen


class ClassDef < ModuleDef
  include GenSupport

  def initialize(name, baseclass = nil)
    super(name)
    @baseclass = baseclass
    @classvar = []
    @attrdef = []
  end

  def def_classvar(var, value)
    var = var.sub(/\A@@/, "")
    unless safevarname?(var)
      raise ArgumentError.new("#{var} seems to be unsafe")
    end
    @classvar << [var, value]
  end

  def def_attr(attrname, writable = true, varname = nil)
    unless safevarname?(varname || attrname)
      raise ArgumentError.new("#{varname || attrname} seems to be unsafe")
    end
    @attrdef << [attrname, writable, varname]
  end

  def dump
    buf = ""
    unless @requirepath.empty?
      buf << dump_requirepath 
    end
    buf << dump_emptyline unless buf.empty?
    package = @name.split(/::/)[0..-2]
    buf << dump_package_def(package) unless package.empty?
    buf << dump_comment if @comment
    buf << dump_class_def
    spacer = false
    unless @classvar.empty?
      spacer = true
      buf << dump_classvar
    end
    unless @const.empty?
      buf << dump_emptyline if spacer
      spacer = true
      buf << dump_const
    end
    unless @code.empty?
      buf << dump_emptyline if spacer
      spacer = true
      buf << dump_code
    end
    unless @attrdef.empty?
      buf << dump_emptyline if spacer
      spacer = true
      buf << dump_attributes
    end
    unless @methoddef.empty?
      buf << dump_emptyline if spacer
      spacer = true
      buf << dump_methods
    end
    buf << dump_class_def_end
    buf << dump_package_def_end(package) unless package.empty?
    buf.gsub(/^\s+$/, '')
  end

private

  def dump_class_def
    name = @name.to_s.split(/::/)
    if @baseclass
      format("class #{name.last} < #{@baseclass}")
    else
      format("class #{name.last}")
    end
  end

  def dump_class_def_end
    str = format("end")
  end

  def dump_classvar
    dump_static(
      @classvar.collect { |var, value|
        %Q(@@#{var.sub(/^@@/, "")} = #{dump_value(value)})
      }.join("\n")
    )
  end

  def dump_attributes
    str = ""
    @attrdef.each do |attrname, writable, varname|
      varname ||= attrname
      if attrname == varname
        str << format(dump_accessor(attrname, writable), 2)
      end
    end
    @attrdef.each do |attrname, writable, varname|
      varname ||= attrname
      if attrname != varname
        str << "\n" unless str.empty?
        str << format(dump_attribute(attrname, writable, varname), 2)
      end
    end
    str
  end

  def dump_accessor(attrname, writable)
    if writable
      "attr_accessor :#{attrname}"
    else
      "attr_reader :#{attrname}"
    end
  end

  def dump_attribute(attrname, writable, varname)
    str = nil
    mr = MethodDef.new(attrname)
    mr.definition = "@#{varname}"
    str = mr.dump
    if writable
      mw = MethodDef.new(attrname + "=", 'value')
      mw.definition = "@#{varname} = value"
      str << "\n" + mw.dump
    end
    str
  end
end


end
end


if __FILE__ == $0
  require 'xsd/codegen/classdef'
  include XSD::CodeGen
  c = ClassDef.new("Foo::Bar::HobbitName", String)
  c.def_require("foo/bar")
  c.comment = <<-EOD
      foo
    bar
      baz
  EOD
  c.def_const("FOO", 1)
  c.def_classvar("@@foo", "var".dump)
  c.def_classvar("baz", "1".dump)
  c.def_attr("Foo", true, "foo")
  c.def_attr("bar")
  c.def_attr("baz", true)
  c.def_attr("Foo2", true, "foo2")
  c.def_attr("foo3", false, "foo3")
  c.def_method("foo") do
    <<-EOD
        foo.bar = 1
\tbaz.each do |ele|
\t  ele
        end
    EOD
  end
  c.def_method("baz", "qux") do
    <<-EOD
      [1, 2, 3].each do |i|
        p i
      end
    EOD
  end

  m = MethodDef.new("qux", "quxx", "quxxx") do
    <<-EOD
    p quxx + quxxx
    EOD
  end
  m.comment = "hello world\n123"
  c.add_method(m)
  c.def_code <<-EOD
    Foo.new
    Bar.z
  EOD
  c.def_code <<-EOD
    Foo.new
    Bar.z
  EOD
  c.def_privatemethod("foo", "baz", "*arg", "&block")

  puts c.dump
end
PK     Z\w^  ^    xsd/codegen/commentdef.rbnu [        # XSD4R - Generating comment definition code
# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/codegen/gensupport'


module XSD
module CodeGen


module CommentDef
  include GenSupport

  attr_accessor :comment

private

  def dump_comment
    if /\A#/ =~ @comment
      format(@comment)
    else
      format(@comment).gsub(/^/, '# ')
    end
  end
end


end
end
PK     Z\ Y  Y    xsd/codegen/gensupport.rbnu [        # XSD4R - Code generation support
# Copyright (C) 2004, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


module XSD
module CodeGen

# from the file 'keywords' in 1.9.
KEYWORD = {}
%w(
__LINE__
__FILE__
BEGIN
END
alias
and
begin
break
case
class
def
defined?
do
else
elsif
end
ensure
false
for
if
in
module
next
nil
not
or
redo
rescue
retry
return
self
super
then
true
undef
unless
until
when
while
yield
).each { |k| KEYWORD[k] = nil }

module GenSupport
  def capitalize(target)
    target.sub(/^([a-z])/) { $1.tr!('[a-z]', '[A-Z]') }
  end
  module_function :capitalize

  def uncapitalize(target)
    target.sub(/^([A-Z])/) { $1.tr!('[A-Z]', '[a-z]') }
  end
  module_function :uncapitalize

  def safeconstname(name)
    safename = name.scan(/[a-zA-Z0-9_]+/).collect { |ele|
      GenSupport.capitalize(ele)
    }.join
    if /^[A-Z]/ !~ safename or keyword?(safename)
      safename = "C_#{safename}"
    end
    safename
  end
  module_function :safeconstname

  def safeconstname?(name)
    /\A[A-Z][a-zA-Z0-9_]*\z/ =~ name and !keyword?(name)
  end
  module_function :safeconstname?

  def safemethodname(name)
    safename = name.scan(/[a-zA-Z0-9_]+/).join('_')
    safename = uncapitalize(safename)
    if /^[a-z]/ !~ safename
      safename = "m_#{safename}"
    end
    safename
  end
  module_function :safemethodname

  def safemethodname?(name)
    /\A[a-zA-Z_][a-zA-Z0-9_]*[=!?]?\z/ =~ name
  end
  module_function :safemethodname?

  def safevarname(name)
    safename = uncapitalize(name.scan(/[a-zA-Z0-9_]+/).join('_'))
    if /^[a-z]/ !~ safename or keyword?(safename)
      "v_#{safename}"
    else
      safename
    end
  end
  module_function :safevarname

  def safevarname?(name)
    /\A[a-z_][a-zA-Z0-9_]*\z/ =~ name and !keyword?(name)
  end
  module_function :safevarname?

  def keyword?(word)
    KEYWORD.key?(word)
  end
  module_function :keyword?

  def format(str, indent = nil)
    str = trim_eol(str)
    str = trim_indent(str)
    if indent
      str.gsub(/^/, " " * indent)
    else
      str
    end
  end

private

  def trim_eol(str)
    str.collect { |line|
      line.sub(/\r?\n\z/, "") + "\n"
    }.join
  end

  def trim_indent(str)
    indent = nil
    str = str.collect { |line| untab(line) }.join
    str.each do |line|
      head = line.index(/\S/)
      if !head.nil? and (indent.nil? or head < indent)
        indent = head
      end
    end
    return str unless indent
    str.collect { |line|
      line.sub(/^ {0,#{indent}}/, "")
    }.join
  end

  def untab(line, ts = 8)
    while pos = line.index(/\t/)
      line = line.sub(/\t/, " " * (ts - (pos % ts)))
    end
    line
  end

  def dump_emptyline
    "\n"
  end
end


end
end
PK     Z\Sb4;      xsd/codegen/moduledef.rbnu [        # XSD4R - Generating module definition code
# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/codegen/gensupport'
require 'xsd/codegen/methoddef'
require 'xsd/codegen/commentdef'


module XSD
module CodeGen


class ModuleDef
  include GenSupport
  include CommentDef

  def initialize(name)
    @name = name
    @comment = nil
    @const = []
    @code = []
    @requirepath = []
    @methoddef = []
  end

  def def_require(path)
    @requirepath << path
  end

  def def_const(const, value)
    unless safeconstname?(const)
      raise ArgumentError.new("#{const} seems to be unsafe")
    end
    @const << [const, value]
  end

  def def_code(code)
    @code << code
  end

  def def_method(name, *params)
    add_method(MethodDef.new(name, *params) { yield if block_given? }, :public)
  end
  alias def_publicmethod def_method

  def def_protectedmethod(name, *params)
    add_method(MethodDef.new(name, *params) { yield if block_given? },
      :protected)
  end

  def def_privatemethod(name, *params)
    add_method(MethodDef.new(name, *params) { yield if block_given? }, :private)
  end

  def add_method(m, visibility = :public)
    @methoddef << [visibility, m]
  end

  def dump
    buf = ""
    unless @requirepath.empty?
      buf << dump_requirepath 
    end
    buf << dump_emptyline unless buf.empty?
    package = @name.split(/::/)[0..-2]
    buf << dump_package_def(package) unless package.empty?
    buf << dump_comment if @comment
    buf << dump_module_def
    spacer = false
    unless @const.empty?
      buf << dump_emptyline if spacer
      spacer = true
      buf << dump_const
    end
    unless @code.empty?
      buf << dump_emptyline if spacer
      spacer = true
      buf << dump_code
    end
    unless @methoddef.empty?
      buf << dump_emptyline if spacer
      spacer = true
      buf << dump_methods
    end
    buf << dump_module_def_end
    buf << dump_package_def_end(package) unless package.empty?
    buf.gsub(/^\s+$/, '')
  end

private

  def dump_requirepath
    format(
      @requirepath.collect { |path|
        %Q(require '#{path}')
      }.join("\n")
    )
  end

  def dump_const
    dump_static(
      @const.sort.collect { |var, value|
        %Q(#{var} = #{dump_value(value)})
      }.join("\n")
    )
  end

  def dump_code
    dump_static(@code.join("\n"))
  end

  def dump_static(str)
    format(str, 2)
  end

  def dump_methods
    methods = {}
    @methoddef.each do |visibility, method|
      (methods[visibility] ||= []) << method
    end
    str = ""
    [:public, :protected, :private].each do |visibility|
      if methods[visibility]
        str << "\n" unless str.empty?
        str << visibility.to_s << "\n\n" unless visibility == :public
        str << methods[visibility].collect { |m| format(m.dump, 2) }.join("\n")
      end
    end
    str
  end

  def dump_value(value)
    if value.respond_to?(:to_src)
      value.to_src
    else
      value
    end
  end

  def dump_package_def(package)
    format(package.collect { |ele| "module #{ele}" }.join("; ")) + "\n\n"
  end

  def dump_package_def_end(package)
    "\n\n" + format(package.collect { |ele| "end" }.join("; "))
  end

  def dump_module_def
    name = @name.to_s.split(/::/)
    format("module #{name.last}")
  end

  def dump_module_def_end
    format("end")
  end
end


end
end


if __FILE__ == $0
  require 'xsd/codegen/moduledef'
  include XSD::CodeGen
  m = ModuleDef.new("Foo::Bar::HobbitName")
  m.def_require("foo/bar")
  m.def_require("baz")
  m.comment = <<-EOD
    foo
    bar
    baz
  EOD
  m.def_method("foo") do
    <<-EOD
      foo.bar = 1
      baz.each do |ele|
        ele + 1
      end
    EOD
  end
  m.def_method("baz", "qux")
  #m.def_protectedmethod("aaa")
  m.def_privatemethod("bbb")
  puts m.dump
end
PK     Z\uD<      xsd/codegen/methoddef.rbnu [        # XSD4R - Generating method definition code
# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/codegen/gensupport'
require 'xsd/codegen/commentdef'


module XSD
module CodeGen


class MethodDef
  include GenSupport
  include CommentDef

  attr_accessor :definition

  def initialize(name, *params)
    unless safemethodname?(name)
      raise ArgumentError.new("name '#{name}' seems to be unsafe")
    end
    @name = name
    @params = params
    @comment = nil
    @definition = yield if block_given?
  end

  def dump
    buf = ""
    buf << dump_comment if @comment
    buf << dump_method_def
    buf << dump_definition if @definition and !@definition.empty?
    buf << dump_method_def_end
    buf
  end

private

  def dump_method_def
    if @params.empty?
      format("def #{@name}")
    else
      format("def #{@name}(#{@params.join(", ")})")
    end
  end

  def dump_method_def_end
    format("end")
  end

  def dump_definition
    format(@definition, 2)
  end
end


end
end
PK     Z\r
  
  	  xsd/ns.rbnu [        # XSD4R - XML Schema Namespace library
# Copyright (C) 2000-2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/datatypes'


module XSD


class NS
  class Assigner
    def initialize
      @count = 0
    end

    def assign(ns)
      @count += 1
      "n#{@count}"
    end
  end

  attr_reader :default_namespace

  class FormatError < Error; end

public

  def initialize(tag2ns = {})
    @tag2ns = tag2ns
    @assigner = nil
    @ns2tag = {}
    @tag2ns.each do |tag, ns|
      @ns2tag[ns] = tag
    end
    @default_namespace = nil
  end

  def assign(ns, tag = nil)
    if (tag == '')
      @default_namespace = ns
      tag
    else
      @assigner ||= Assigner.new
      tag ||= @assigner.assign(ns)
      @ns2tag[ns] = tag
      @tag2ns[tag] = ns
      tag
    end
  end

  def assigned?(ns)
    @default_namespace == ns or @ns2tag.key?(ns)
  end

  def assigned_tag?(tag)
    @tag2ns.key?(tag)
  end

  def clone_ns
    cloned = NS.new(@tag2ns.dup)
    cloned.assigner = @assigner
    cloned.assign(@default_namespace, '') if @default_namespace
    cloned
  end

  def name(name)
    if (name.namespace == @default_namespace)
      name.name
    elsif @ns2tag.key?(name.namespace)
      "#{@ns2tag[name.namespace]}:#{name.name}"
    else
      raise FormatError.new("namespace: #{name.namespace} not defined yet")
    end
  end

  def compare(ns, name, rhs)
    if (ns == @default_namespace)
      return true if (name == rhs)
    end
    @tag2ns.each do |assigned_tag, assigned_ns|
      if assigned_ns == ns && "#{assigned_tag}:#{name}" == rhs
	return true
      end
    end
    false
  end

  # $1 and $2 are necessary.
  ParseRegexp = Regexp.new('^([^:]+)(?::(.+))?$')

  def parse(str, local = false)
    if ParseRegexp =~ str
      if (name = $2) and (ns = @tag2ns[$1])
        return XSD::QName.new(ns, name)
      end
    end
    XSD::QName.new(local ? nil : @default_namespace, str)
  end

  # For local attribute key parsing
  #   <foo xmlns="urn:a" xmlns:n1="urn:a" bar="1" n1:baz="2" />
  #     =>
  #   {}bar, {urn:a}baz
  def parse_local(elem)
    ParseRegexp =~ elem
    if $2
      ns = @tag2ns[$1]
      name = $2
      if !ns
	raise FormatError.new("unknown namespace qualifier: #{$1}")
      end
    elsif $1
      ns = nil
      name = $1
    else
      raise FormatError.new("illegal element format: #{elem}")
    end
    XSD::QName.new(ns, name)
  end

  def each_ns
    @ns2tag.each do |ns, tag|
      yield(ns, tag)
    end
  end

protected

  def assigner=(assigner)
    @assigner = assigner
  end
end


end
PK     Z\      xsd/mapping.rbnu [        # XSD4R - XML Mapping for Ruby
# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require "soap/parser"
require 'soap/encodingstyle/literalHandler'
require "soap/generator"
require "soap/mapping"
require "soap/mapping/wsdlliteralregistry"


module XSD


module Mapping
  MappingRegistry = SOAP::Mapping::WSDLLiteralRegistry.new
  MappingOpt = {:default_encodingstyle => SOAP::LiteralNamespace}

  def self.obj2xml(obj, elename = nil, io = nil)
    if !elename.nil? and !elename.is_a?(XSD::QName)
      elename = XSD::QName.new(nil, elename)
    end
    elename ||= XSD::QName.new(nil, SOAP::Mapping.name2elename(obj.class.to_s))
    soap = SOAP::Mapping.obj2soap(obj, MappingRegistry)
    soap.elename = elename
    generator = SOAP::SOAPGenerator.new(MappingOpt)
    generator.generate(soap, io)
  end

  def self.xml2obj(stream)
    parser = SOAP::Parser.new(MappingOpt)
    soap = parser.parse(stream)
    SOAP::Mapping.soap2obj(soap, MappingRegistry)
  end
end


end
PK     Z\8v
  
    xsd/xmlparser/xmlscanner.rbnu [        # XSD4R - XMLScan XML parser library.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/xmlparser'
require 'xmlscan/scanner'


module XSD
module XMLParser


class XMLScanner < XSD::XMLParser::Parser
  include XMLScan::Visitor

  def do_parse(string_or_readable)
    @attrs = {}
    @curattr = nil
    @scanner = XMLScan::XMLScanner.new(self)
    @scanner.kcode = XSD::Charset.charset_str(charset) if charset
    @scanner.parse(string_or_readable)
  end

  def scanner_kcode=(charset)
    @scanner.kcode = XSD::Charset.charset_str(charset) if charset
    self.xmldecl_encoding = charset
  end

  ENTITY_REF_MAP = {
    'lt' => '<',
    'gt' => '>',
    'amp' => '&',
    'quot' => '"',
    'apos' => '\''
  }

  def parse_error(msg)
    raise ParseError.new(msg)
  end

  def wellformed_error(msg)
    raise NotWellFormedError.new(msg)
  end

  def valid_error(msg)
    raise NotValidError.new(msg)
  end

  def warning(msg)
    p msg if $DEBUG
  end

  # def on_xmldecl; end

  def on_xmldecl_version(str)
    # 1.0 expected.
  end

  def on_xmldecl_encoding(str)
    self.scanner_kcode = str
  end

  # def on_xmldecl_standalone(str); end

  # def on_xmldecl_other(name, value); end

  # def on_xmldecl_end; end

  # def on_doctype(root, pubid, sysid); end

  # def on_prolog_space(str); end

  # def on_comment(str); end

  # def on_pi(target, pi); end

  def on_chardata(str)
    characters(str)
  end

  # def on_cdata(str); end

  def on_etag(name)
    end_element(name)
  end

  def on_entityref(ref)
    characters(ENTITY_REF_MAP[ref])
  end

  def on_charref(code)
    characters([code].pack('U'))
  end

  def on_charref_hex(code)
    on_charref(code)
  end

  # def on_start_document; end

  # def on_end_document; end

  def on_stag(name)
    @attrs = {}
  end

  def on_attribute(name)
    @attrs[name] = @curattr = ''
  end

  def on_attr_value(str)
    @curattr << str
  end

  def on_attr_entityref(ref)
    @curattr << ENTITY_REF_MAP[ref]
  end

  def on_attr_charref(code)
    @curattr << [code].pack('U')
  end

  def on_attr_charref_hex(code)
    on_attr_charref(code)
  end

  # def on_attribute_end(name); end

  def on_stag_end_empty(name)
    on_stag_end(name)
    on_etag(name)
  end

  def on_stag_end(name)
    start_element(name, @attrs)
  end

  add_factory(self)
end


end
end
PK     Z\Vn  n    xsd/xmlparser/xmlparser.rbnu [        # XSD4R - XMLParser XML parser library.
# Copyright (C) 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/xmlparser'
require 'xml/parser'


module XSD
module XMLParser


class XMLParser < XSD::XMLParser::Parser
  class Listener < XML::Parser
    begin
      require 'xml/encoding-ja'
      include XML::Encoding_ja
    rescue LoadError
      # uconv may not be installed.
    end
  end

  def do_parse(string_or_readable)
    # XMLParser passes a String in utf-8.
    @charset = 'utf-8'
    @parser = Listener.new
    @parser.parse(string_or_readable) do |type, name, data|
      case type
      when XML::Parser::START_ELEM
	start_element(name, data)
      when XML::Parser::END_ELEM
	end_element(name)
      when XML::Parser::CDATA
	characters(data)
      else
	raise FormatDecodeError.new("Unexpected XML: #{ type }/#{ name }/#{ data }.")
      end
    end
  end

  add_factory(self)
end


end
end
PK     Z\);T_  _    xsd/xmlparser/parser.rbnu [        # XSD4R - XML Instance parser library.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/qname'
require 'xsd/ns'
require 'xsd/charset'


module XSD
module XMLParser


class Parser
  class ParseError < Error; end
  class FormatDecodeError < ParseError; end
  class UnknownElementError < FormatDecodeError; end
  class UnknownAttributeError < FormatDecodeError; end
  class UnexpectedElementError < FormatDecodeError; end
  class ElementConstraintError < FormatDecodeError; end

  @@parser_factory = nil

  def self.factory
    @@parser_factory
  end

  def self.create_parser(host, opt = {})
    @@parser_factory.new(host, opt)
  end

  def self.add_factory(factory)
    if $DEBUG
      puts "Set #{ factory } as XML processor."
    end
    @@parser_factory = factory
  end

public

  attr_accessor :charset

  def initialize(host, opt = {})
    @host = host
    @charset = opt[:charset] || nil
  end

  def parse(string_or_readable)
    @textbuf = ''
    prologue
    do_parse(string_or_readable)
    epilogue
  end

private

  def do_parse(string_or_readable)
    raise NotImplementError.new(
      'Method do_parse must be defined in derived class.')
  end

  def start_element(name, attrs)
    @host.start_element(name, attrs)
  end

  def characters(text)
    @host.characters(text)
  end

  def end_element(name)
    @host.end_element(name)
  end

  def prologue
  end

  def epilogue
  end

  def xmldecl_encoding=(charset)
    if @charset.nil?
      @charset = charset
    else
      # Definition in a stream (like HTTP) has a priority.
      p "encoding definition: #{ charset } is ignored." if $DEBUG
    end
  end
end


end
end
PK     Z\hG  G    xsd/xmlparser/rexmlparser.rbnu [        # XSD4R - REXMLParser XML parser library.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/xmlparser'
require 'rexml/streamlistener'
require 'rexml/document'


module XSD
module XMLParser


class REXMLParser < XSD::XMLParser::Parser
  include REXML::StreamListener

  def do_parse(string_or_readable)
    source = nil
    source = REXML::SourceFactory.create_from(string_or_readable)
    source.encoding = charset if charset
    # Listener passes a String in utf-8.
    @charset = 'utf-8'
    REXML::Document.parse_stream(source, self)
  end

  def epilogue
  end

  def tag_start(name, attrs)
    start_element(name, attrs)
  end

  def tag_end(name)
    end_element(name)
  end

  def text(text)
    characters(text)
  end

  def xmldecl(version, encoding, standalone)
    # Version should be checked.
  end

  add_factory(self)
end


end
end
PK     	Z\3);#  ;#    delegate.rbnu [        # = delegate -- Support for the Delegation Pattern
#
# Documentation by James Edward Gray II and Gavin Sinclair
#
# == Introduction
#
# This library provides three different ways to delegate method calls to an
# object.  The easiest to use is SimpleDelegator.  Pass an object to the
# constructor and all methods supported by the object will be delegated.  This
# object can be changed later.
#
# Going a step further, the top level DelegateClass method allows you to easily
# setup delegation through class inheritance.  This is considerably more
# flexible and thus probably the most common use for this library.
#
# Finally, if you need full control over the delegation scheme, you can inherit
# from the abstract class Delegator and customize as needed.  (If you find
# yourself needing this control, have a look at _forwardable_, also in the
# standard library.  It may suit your needs better.)
#
# == Notes
#
# Be advised, RDoc will not detect delegated methods.
#
# <b>delegate.rb provides full-class delegation via the
# DelegateClass() method.  For single-method delegation via
# def_delegator(), see forwardable.rb.</b>
#
# == Examples
#
# === SimpleDelegator
#
# Here's a simple example that takes advantage of the fact that
# SimpleDelegator's delegation object can be changed at any time.
#
#   class Stats
#     def initialize
#       @source = SimpleDelegator.new([])
#     end
#     
#     def stats( records )
#       @source.__setobj__(records)
#       	
#       "Elements:  #{@source.size}\n" +
#       " Non-Nil:  #{@source.compact.size}\n" +
#       "  Unique:  #{@source.uniq.size}\n"
#     end
#   end
#   
#   s = Stats.new
#   puts s.stats(%w{James Edward Gray II})
#   puts
#   puts s.stats([1, 2, 3, nil, 4, 5, 1, 2])
#
# <i>Prints:</i>
#
#   Elements:  4
#    Non-Nil:  4
#     Unique:  4
# 
#   Elements:  8
#    Non-Nil:  7
#     Unique:  6
#
# === DelegateClass()
#
# Here's a sample of use from <i>tempfile.rb</i>.
#
# A _Tempfile_ object is really just a _File_ object with a few special rules
# about storage location and/or when the File should be deleted.  That makes for
# an almost textbook perfect example of how to use delegation.
#
#   class Tempfile < DelegateClass(File)
#     # constant and class member data initialization...
#   
#     def initialize(basename, tmpdir=Dir::tmpdir)
#       # build up file path/name in var tmpname...
#     
#       @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)
#     
#       # ...
#     
#       super(@tmpfile)
#     
#       # below this point, all methods of File are supported...
#     end
#   
#     # ...
#   end
#
# === Delegator
#
# SimpleDelegator's implementation serves as a nice example here.
#
#    class SimpleDelegator < Delegator
#      def initialize(obj)
#        super             # pass obj to Delegator constructor, required
#        @_sd_obj = obj    # store obj for future use
#      end
# 
#      def __getobj__
#        @_sd_obj          # return object we are delegating to, required
#      end
# 
#      def __setobj__(obj)
#        @_sd_obj = obj    # change delegation object, a feature we're providing
#      end
# 
#      # ...
#    end

#
# Delegator is an abstract class used to build delegator pattern objects from
# subclasses.  Subclasses should redefine \_\_getobj\_\_.  For a concrete
# implementation, see SimpleDelegator.
#
class Delegator
  IgnoreBacktracePat = %r"\A#{Regexp.quote(__FILE__)}:\d+:in `"

  #
  # Pass in the _obj_ to delegate method calls to.  All methods supported by
  # _obj_ will be delegated to.
  #
  def initialize(obj)
    preserved = ::Kernel.public_instance_methods(false)
    preserved -= ["to_s","to_a","inspect","==","=~","==="]
    for t in self.class.ancestors
      preserved |= t.public_instance_methods(false)
      preserved |= t.private_instance_methods(false)
      preserved |= t.protected_instance_methods(false)
      break if t == Delegator
    end
    preserved << "singleton_method_added"
    for method in obj.methods
      next if preserved.include? method
      begin
	eval <<-EOS, nil, __FILE__, __LINE__+1
	  def self.#{method}(*args, &block)
	    begin
	      __getobj__.__send__(:#{method}, *args, &block)
	    ensure
	      $@.delete_if{|s|IgnoreBacktracePat=~s} if $@
	    end
	  end
	EOS
      rescue SyntaxError
        raise NameError, "invalid identifier %s" % method, caller(4)
      end
    end
  end
  alias initialize_methods initialize

  # Handles the magic of delegation through \_\_getobj\_\_.
  def method_missing(m, *args, &block)
    target = self.__getobj__
    unless target.respond_to?(m)
      super(m, *args, &block)
    end
    target.__send__(m, *args, &block)
  end

  # 
  # Checks for a method provided by this the delegate object by fowarding the 
  # call through \_\_getobj\_\_.
  # 
  def respond_to?(m, include_private = false)
    return true if super
    return self.__getobj__.respond_to?(m, include_private)
  end

  #
  # This method must be overridden by subclasses and should return the object
  # method calls are being delegated to.
  #
  def __getobj__
    raise NotImplementedError, "need to define `__getobj__'"
  end

  # Serialization support for the object returned by \_\_getobj\_\_.
  def marshal_dump
    __getobj__
  end
  # Reinitializes delegation from a serialized object.
  def marshal_load(obj)
    initialize_methods(obj)
    __setobj__(obj)
  end
end

#
# A concrete implementation of Delegator, this class provides the means to
# delegate all supported method calls to the object passed into the constructor
# and even to change the object being delegated to at a later time with
# \_\_setobj\_\_ .
#
class SimpleDelegator<Delegator

  # Pass in the _obj_ you would like to delegate method calls to.
  def initialize(obj)
    super
    @_sd_obj = obj
  end

  # Returns the current object method calls are being delegated to.
  def __getobj__
    @_sd_obj
  end

  #
  # Changes the delegate object to _obj_.
  #
  # It's important to note that this does *not* cause SimpleDelegator's methods
  # to change.  Because of this, you probably only want to change delegation
  # to objects of the same type as the original delegate.
  #
  # Here's an example of changing the delegation object.
  #
  #   names = SimpleDelegator.new(%w{James Edward Gray II})
  #   puts names[1]    # => Edward
  #   names.__setobj__(%w{Gavin Sinclair})
  #   puts names[1]    # => Sinclair
  #
  def __setobj__(obj)
    raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
    @_sd_obj = obj
  end

  # Clone support for the object returned by \_\_getobj\_\_.
  def clone
    new = super
    new.__setobj__(__getobj__.clone)
    new
  end
  # Duplication support for the object returned by \_\_getobj\_\_.
  def dup
    new = super
    new.__setobj__(__getobj__.clone)
    new
  end
end

# :stopdoc:
# backward compatibility ^_^;;;
Delegater = Delegator
SimpleDelegater = SimpleDelegator
# :startdoc:

#
# The primary interface to this library.  Use to setup delegation when defining
# your class.
#
#   class MyClass < DelegateClass( ClassToDelegateTo )    # Step 1
#     def initialize
#       super(obj_of_ClassToDelegateTo)                   # Step 2
#     end
#   end
#
def DelegateClass(superclass)
  klass = Class.new
  methods = superclass.public_instance_methods(true)
  methods -= ::Kernel.public_instance_methods(false)
  methods |= ["to_s","to_a","inspect","==","=~","==="]
  klass.module_eval {
    def initialize(obj)  # :nodoc:
      @_dc_obj = obj
    end
    def method_missing(m, *args, &block)  # :nodoc:
      unless @_dc_obj.respond_to?(m)
        super(m, *args, &block)
      end
      @_dc_obj.__send__(m, *args, &block)
    end
    def respond_to?(m, include_private = false)  # :nodoc:
      return true if super
      return @_dc_obj.respond_to?(m, include_private)
    end
    def __getobj__  # :nodoc:
      @_dc_obj
    end
    def __setobj__(obj)  # :nodoc:
      raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
      @_dc_obj = obj
    end
    def clone  # :nodoc:
      new = super
      new.__setobj__(__getobj__.clone)
      new
    end
    def dup  # :nodoc:
      new = super
      new.__setobj__(__getobj__.clone)
      new
    end
  }
  for method in methods
    begin
      klass.module_eval <<-EOS, __FILE__, __LINE__+1
        def #{method}(*args, &block)
	  begin
	    @_dc_obj.__send__(:#{method}, *args, &block)
	  ensure
	    $@.delete_if{|s| ::Delegator::IgnoreBacktracePat =~ s} if $@
	  end
	end
      EOS
    rescue SyntaxError
      raise NameError, "invalid identifier %s" % method, caller(3)
    end
  end
  return klass
end

# :enddoc:

if __FILE__ == $0
  class ExtArray<DelegateClass(Array)
    def initialize()
      super([])
    end
  end

  ary = ExtArray.new
  p ary.class
  ary.push 25
  p ary

  foo = Object.new
  def foo.test
    25
  end
  def foo.error
    raise 'this is OK'
  end
  foo2 = SimpleDelegator.new(foo)
  p foo.test == foo2.test	# => true
  foo2.error			# raise error!
end
PK     	Z\]&  &    un.rbnu [        # 
# = un.rb
# 
# Copyright (c) 2003 WATANABE Hirofumi <eban@ruby-lang.org>
# 
# This program is free software.
# You can distribute/modify this program under the same terms of Ruby.
# 
# == Utilities to replace common UNIX commands in Makefiles etc
#
# == SYNOPSIS
#
#   ruby -run -e cp -- [OPTION] SOURCE DEST
#   ruby -run -e ln -- [OPTION] TARGET LINK_NAME
#   ruby -run -e mv -- [OPTION] SOURCE DEST
#   ruby -run -e rm -- [OPTION] FILE
#   ruby -run -e mkdir -- [OPTION] DIRS
#   ruby -run -e rmdir -- [OPTION] DIRS
#   ruby -run -e install -- [OPTION] SOURCE DEST
#   ruby -run -e chmod -- [OPTION] OCTAL-MODE FILE
#   ruby -run -e touch -- [OPTION] FILE
#   ruby -run -e help [COMMAND]

require "fileutils"
require "optparse"

module FileUtils
#  @fileutils_label = ""
  @fileutils_output = $stdout
end

def setup(options = "")
  ARGV.map! do |x|
    case x
    when /^-/
      x.delete "^-#{options}v"
    when /[*?\[{]/
      Dir[x]
    else
      x
    end
  end
  ARGV.flatten!
  ARGV.delete_if{|x| x == "-"}
  opt_hash = {}
  OptionParser.new do |o|
    options.scan(/.:?/) do |s|
      o.on("-" + s.tr(":", " ")) do |val|
        opt_hash[s.delete(":").intern] = val
      end
    end
    o.on("-v") do opt_hash[:verbose] = true end
    o.parse!
  end
  yield ARGV, opt_hash
end

##
# Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY
#
#   ruby -run -e cp -- [OPTION] SOURCE DEST
#
#   -p		preserve file attributes if possible
#   -r		copy recursively
#   -v		verbose
#

def cp
  setup("pr") do |argv, options|
    cmd = "cp"
    cmd += "_r" if options.delete :r
    options[:preserve] = true if options.delete :p
    dest = argv.pop
    argv = argv[0] if argv.size == 1
    FileUtils.send cmd, argv, dest, options
  end
end

##
# Create a link to the specified TARGET with LINK_NAME.
#
#   ruby -run -e ln -- [OPTION] TARGET LINK_NAME
#
#   -s		make symbolic links instead of hard links
#   -f		remove existing destination files
#   -v		verbose
#

def ln
  setup("sf") do |argv, options|
    cmd = "ln"
    cmd += "_s" if options.delete :s
    options[:force] = true if options.delete :f
    dest = argv.pop
    argv = argv[0] if argv.size == 1
    FileUtils.send cmd, argv, dest, options
  end
end

##
# Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.
#
#   ruby -run -e mv -- [OPTION] SOURCE DEST
#
#   -v		verbose
#

def mv
  setup do |argv, options|
    dest = argv.pop
    argv = argv[0] if argv.size == 1
    FileUtils.mv argv, dest, options
  end
end

##
# Remove the FILE
#
#   ruby -run -e rm -- [OPTION] FILE
#
#   -f		ignore nonexistent files
#   -r		remove the contents of directories recursively
#   -v		verbose
#

def rm
  setup("fr") do |argv, options|
    cmd = "rm"
    cmd += "_r" if options.delete :r
    options[:force] = true if options.delete :f
    FileUtils.send cmd, argv, options
  end
end

##
# Create the DIR, if they do not already exist.
#
#   ruby -run -e mkdir -- [OPTION] DIR
#
#   -p		no error if existing, make parent directories as needed
#   -v		verbose
#

def mkdir
  setup("p") do |argv, options|
    cmd = "mkdir"
    cmd += "_p" if options.delete :p
    FileUtils.send cmd, argv, options
  end
end

##
# Remove the DIR.
#
#   ruby -run -e rmdir -- [OPTION] DIR
#
#   -v		verbose
#

def rmdir
  setup do |argv, options|
    FileUtils.rmdir argv, options
  end
end

##
# Copy SOURCE to DEST.
#
#   ruby -run -e install -- [OPTION] SOURCE DEST
#
#   -p		apply access/modification times of SOURCE files to
#  		corresponding destination files
#   -m		set permission mode (as in chmod), instead of 0755
#   -v		verbose
#

def install
  setup("pm:") do |argv, options|
    options[:mode] = (mode = options.delete :m) ? mode.oct : 0755
    options[:preserve] = true if options.delete :p
    dest = argv.pop
    argv = argv[0] if argv.size == 1
    FileUtils.install argv, dest, options
  end
end

##
# Change the mode of each FILE to OCTAL-MODE.
#
#   ruby -run -e chmod -- [OPTION] OCTAL-MODE FILE
#
#   -v		verbose
#

def chmod
  setup do |argv, options|
    mode = argv.shift.oct
    FileUtils.chmod mode, argv, options
  end
end

##
# Update the access and modification times of each FILE to the current time.
#
#   ruby -run -e touch -- [OPTION] FILE
#
#   -v		verbose
#

def touch
  setup do |argv, options|
    FileUtils.touch argv, options
  end
end

##
# Display help message.
#
#   ruby -run -e help [COMMAND]
#

def help
  setup do |argv,|
    all = argv.empty?
    open(__FILE__) do |me|
      while me.gets("##\n")
	if help = me.gets("\n\n")
	  if all or argv.delete help[/-e \w+/].sub(/-e /, "")
	    print help.gsub(/^# ?/, "")
	  end
	end
      end
    end
  end
end
PK     
Z\    	  tmpdir.rbnu [        #
# tmpdir - retrieve temporary directory path
#
# $Id: tmpdir.rb 21776 2009-01-26 02:12:10Z shyouhei $
#

require 'fileutils'

class Dir

  @@systmpdir = '/tmp'

  begin
    require 'Win32API'
    CSIDL_LOCAL_APPDATA = 0x001c
    max_pathlen = 260
    windir = "\0"*(max_pathlen+1)
    begin
      getdir = Win32API.new('shell32', 'SHGetFolderPath', 'LLLLP', 'L')
      raise RuntimeError if getdir.call(0, CSIDL_LOCAL_APPDATA, 0, 0, windir) != 0
      windir = File.expand_path(windir.rstrip)
    rescue RuntimeError
      begin
        getdir = Win32API.new('kernel32', 'GetSystemWindowsDirectory', 'PL', 'L')
      rescue RuntimeError
        getdir = Win32API.new('kernel32', 'GetWindowsDirectory', 'PL', 'L')
      end
      len = getdir.call(windir, windir.size)
      windir = File.expand_path(windir[0, len])
    end
    temp = File.join(windir.untaint, 'temp')
    @@systmpdir = temp if File.directory?(temp) and File.writable?(temp)
  rescue LoadError
  end

  ##
  # Returns the operating system's temporary file path.

  def Dir::tmpdir
    tmp = '.'
    if $SAFE > 0
      tmp = @@systmpdir
    else
      for dir in [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'],
	          ENV['USERPROFILE'], @@systmpdir, '/tmp']
	if dir and File.directory?(dir) and File.writable?(dir)
	  tmp = dir
	  break
	end
      end
      File.expand_path(tmp)
    end
  end

  # Dir.mktmpdir creates a temporary directory.
  #
  # The directory is created with 0700 permission.
  #
  # The prefix and suffix of the name of the directory is specified by
  # the optional first argument, <i>prefix_suffix</i>.
  # - If it is not specified or nil, "d" is used as the prefix and no suffix is used.
  # - If it is a string, it is used as the prefix and no suffix is used.
  # - If it is an array, first element is used as the prefix and second element is used as a suffix.
  #
  #  Dir.mktmpdir {|dir| dir is ".../d..." }
  #  Dir.mktmpdir("foo") {|dir| dir is ".../foo..." }
  #  Dir.mktmpdir(["foo", "bar"]) {|dir| dir is ".../foo...bar" }
  #
  # The directory is created under Dir.tmpdir or
  # the optional second argument <i>tmpdir</i> if non-nil value is given.
  #
  #  Dir.mktmpdir {|dir| dir is "#{Dir.tmpdir}/d..." }
  #  Dir.mktmpdir(nil, "/var/tmp") {|dir| dir is "/var/tmp/d..." }
  #
  # If a block is given,
  # it is yielded with the path of the directory.
  # The directory and its contents are removed
  # using FileUtils.remove_entry_secure before Dir.mktmpdir returns.
  # The value of the block is returned.
  #
  #  Dir.mktmpdir {|dir|
  #    # use the directory...
  #    open("#{dir}/foo", "w") { ... }
  #  }
  #
  # If a block is not given,
  # The path of the directory is returned.
  # In this case, Dir.mktmpdir doesn't remove the directory.
  #
  #  dir = Dir.mktmpdir
  #  begin
  #    # use the directory...
  #    open("#{dir}/foo", "w") { ... }
  #  ensure
  #    # remove the directory.
  #    FileUtils.remove_entry_secure dir
  #  end
  #
  def Dir.mktmpdir(prefix_suffix=nil, tmpdir=nil)
    case prefix_suffix
    when nil
      prefix = "d"
      suffix = ""
    when String
      prefix = prefix_suffix
      suffix = ""
    when Array
      prefix = prefix_suffix[0]
      suffix = prefix_suffix[1]
    else
      raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
    end
    tmpdir ||= Dir.tmpdir
    t = Time.now.strftime("%Y%m%d")
    n = nil
    begin
      path = "#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"
      path << "-#{n}" if n
      path << suffix
      Dir.mkdir(path, 0700)
    rescue Errno::EEXIST
      n ||= 0
      n += 1
      retry
    end

    if block_given?
      begin
        yield path
      ensure
        FileUtils.remove_entry_secure path
      end
    else
      path
    end
  end
end
PK     
Z\р    	  ftools.rbnu [        # 
# = ftools.rb: Extra tools for the File class
#
# Author:: WATANABE, Hirofumi
# Documentation:: Zachary Landau
#
# This library can be distributed under the terms of the Ruby license.
# You can freely distribute/modify this library.
#
# It is included in the Ruby standard library.
#
# == Description
#
# ftools adds several (class, not instance) methods to the File class, for
# copying, moving, deleting, installing, and comparing files, as well as
# creating a directory path.  See the File class for details.
#
# FileUtils contains all or nearly all the same functionality and more, and
# is a recommended option over ftools 
#
# When you
#
#   require 'ftools'
#
# then the File class aquires some utility methods for copying, moving, and
# deleting files, and more.
#
# See the method descriptions below, and consider using FileUtils as it is
# more comprehensive.
#
class File
end

class << File

  BUFSIZE = 8 * 1024

  #
  # If +to+ is a valid directory, +from+ will be appended to +to+, adding
  # and escaping backslashes as necessary. Otherwise, +to+ will be returned.
  # Useful for appending +from+ to +to+ only if the filename was not specified
  # in +to+. 
  #
  def catname(from, to)
    if directory? to
      join to.sub(%r([/\\]$), ''), basename(from)
    else
      to
    end
  end

  #
  # Copies a file +from+ to +to+. If +to+ is a directory, copies +from+
  # to <tt>to/from</tt>.
  #
  def syscopy(from, to)
    to = catname(from, to)

    fmode = stat(from).mode
    tpath = to
    not_exist = !exist?(tpath)

    from = open(from, "rb")
    to = open(to, "wb")

    begin
      while true
	to.syswrite from.sysread(BUFSIZE)
      end
    rescue EOFError
      ret = true
    rescue
      ret = false
    ensure
      to.close
      from.close
    end
    chmod(fmode, tpath) if not_exist
    ret
  end

  #
  # Copies a file +from+ to +to+ using #syscopy. If +to+ is a directory,
  # copies +from+ to <tt>to/from</tt>. If +verbose+ is true, <tt>from -> to</tt>
  # is printed.
  #
  def copy(from, to, verbose = false)
    $stderr.print from, " -> ", catname(from, to), "\n" if verbose
    syscopy from, to
  end

  alias cp copy

  #
  # Moves a file +from+ to +to+ using #syscopy. If +to+ is a directory,
  # copies from +from+ to <tt>to/from</tt>. If +verbose+ is true, <tt>from ->
  # to</tt> is printed.
  #
  def move(from, to, verbose = false)
    to = catname(from, to)
    $stderr.print from, " -> ", to, "\n" if verbose

    if RUBY_PLATFORM =~ /djgpp|(cyg|ms|bcc)win|mingw/ and file? to
      unlink to
    end
    fstat = stat(from)
    begin
      rename from, to
    rescue
      begin
        symlink readlink(from), to and unlink from
      rescue
	from_stat = stat(from)
	syscopy from, to and unlink from
	utime(from_stat.atime, from_stat.mtime, to)
	begin
	  chown(fstat.uid, fstat.gid, to)
	rescue
	end
      end
    end
  end

  alias mv move

  #
  # Returns +true+ if and only if the contents of files +from+ and +to+ are
  # identical. If +verbose+ is +true+, <tt>from <=> to</tt> is printed.
  #
  def compare(from, to, verbose = false)
    $stderr.print from, " <=> ", to, "\n" if verbose

    return false if stat(from).size != stat(to).size

    from = open(from, "rb")
    to = open(to, "rb")

    ret = false
    fr = tr = ''

    begin
      while fr == tr
	fr = from.read(BUFSIZE)
	if fr
	  tr = to.read(fr.size)
	else
	  ret = to.read(BUFSIZE)
	  ret = !ret || ret.length == 0
	  break
	end
      end
    rescue
      ret = false
    ensure
      to.close
      from.close
    end
    ret
  end

  alias cmp compare

  #
  # Removes a list of files. Each parameter should be the name of the file to
  # delete. If the last parameter isn't a String, verbose mode will be enabled.
  # Returns the number of files deleted.
  #
  def safe_unlink(*files)
    verbose = if files[-1].is_a? String then false else files.pop end
    files.each do |file|
      begin
        unlink file
        $stderr.print "removing ", file, "\n" if verbose
      rescue Errno::EACCES # for Windows
        continue if symlink? file
        begin
          mode = stat(file).mode
          o_chmod mode | 0200, file
          unlink file
          $stderr.print "removing ", file, "\n" if verbose
        rescue
          o_chmod mode, file rescue nil
        end
      rescue
      end
    end
  end

  alias rm_f safe_unlink

  #
  # Creates a directory and all its parent directories.
  # For example,
  #
  #	File.makedirs '/usr/lib/ruby'
  #
  # causes the following directories to be made, if they do not exist.
  #	* /usr
  #	* /usr/lib
  #	* /usr/lib/ruby
  #
  # You can pass several directories, each as a parameter. If the last
  # parameter isn't a String, verbose mode will be enabled.
  #
  def makedirs(*dirs)
    verbose = if dirs[-1].is_a? String then false else dirs.pop end
    mode = 0755
    for dir in dirs
      parent = dirname(dir)
      next if parent == dir or directory? dir
      makedirs parent unless directory? parent
      $stderr.print "mkdir ", dir, "\n" if verbose
      if basename(dir) != ""
        begin
          Dir.mkdir dir, mode
        rescue SystemCallError
          raise unless directory? dir
        end
      end
    end
  end

  alias mkpath makedirs

  alias o_chmod chmod

  vsave, $VERBOSE = $VERBOSE, false

  #
  # Changes permission bits on +files+ to the bit pattern represented
  # by +mode+. If the last parameter isn't a String, verbose mode will
  # be enabled.
  #
  #   File.chmod 0755, 'somecommand'
  #   File.chmod 0644, 'my.rb', 'your.rb', true
  #
  def chmod(mode, *files)
    verbose = if files[-1].is_a? String then false else files.pop end
    $stderr.printf "chmod %04o %s\n", mode, files.join(" ") if verbose
    o_chmod mode, *files
  end
  $VERBOSE = vsave

  #
  # If +src+ is not the same as +dest+, copies it and changes the permission
  # mode to +mode+. If +dest+ is a directory, destination is <tt>dest/src</tt>.
  # If +mode+ is not set, default is used. If +verbose+ is set to true, the
  # name of each file copied will be printed.
  #
  def install(from, to, mode = nil, verbose = false)
    to = catname(from, to)
    unless exist? to and cmp from, to
      safe_unlink to if exist? to
      cp from, to, verbose
      chmod mode, to, verbose if mode
    end
  end

end

# vi:set sw=2:
PK     Z\a ?      fileutils.rbnu [        # 
# = fileutils.rb
# 
# Copyright (c) 2000-2006 Minero Aoki
# 
# This program is free software.
# You can distribute/modify this program under the same terms of ruby.
# 
# == module FileUtils
# 
# Namespace for several file utility methods for copying, moving, removing, etc.
# 
# === Module Functions
# 
#   cd(dir, options)
#   cd(dir, options) {|dir| .... }
#   pwd()
#   mkdir(dir, options)
#   mkdir(list, options)
#   mkdir_p(dir, options)
#   mkdir_p(list, options)
#   rmdir(dir, options)
#   rmdir(list, options)
#   ln(old, new, options)
#   ln(list, destdir, options)
#   ln_s(old, new, options)
#   ln_s(list, destdir, options)
#   ln_sf(src, dest, options)
#   cp(src, dest, options)
#   cp(list, dir, options)
#   cp_r(src, dest, options)
#   cp_r(list, dir, options)
#   mv(src, dest, options)
#   mv(list, dir, options)
#   rm(list, options)
#   rm_r(list, options)
#   rm_rf(list, options)
#   install(src, dest, mode = <src's>, options)
#   chmod(mode, list, options)
#   chmod_R(mode, list, options)
#   chown(user, group, list, options)
#   chown_R(user, group, list, options)
#   touch(list, options)
#
# The <tt>options</tt> parameter is a hash of options, taken from the list
# <tt>:force</tt>, <tt>:noop</tt>, <tt>:preserve</tt>, and <tt>:verbose</tt>.
# <tt>:noop</tt> means that no changes are made.  The other two are obvious.
# Each method documents the options that it honours.
#
# All methods that have the concept of a "source" file or directory can take
# either one file or a list of files in that argument.  See the method
# documentation for examples.
#
# There are some `low level' methods, which do not accept any option:
#
#   copy_entry(src, dest, preserve = false, dereference = false)
#   copy_file(src, dest, preserve = false, dereference = true)
#   copy_stream(srcstream, deststream)
#   remove_entry(path, force = false)
#   remove_entry_secure(path, force = false)
#   remove_file(path, force = false)
#   compare_file(path_a, path_b)
#   compare_stream(stream_a, stream_b)
#   uptodate?(file, cmp_list)
#
# == module FileUtils::Verbose
# 
# This module has all methods of FileUtils module, but it outputs messages
# before acting.  This equates to passing the <tt>:verbose</tt> flag to methods
# in FileUtils.
# 
# == module FileUtils::NoWrite
# 
# This module has all methods of FileUtils module, but never changes
# files/directories.  This equates to passing the <tt>:noop</tt> flag to methods
# in FileUtils.
# 
# == module FileUtils::DryRun
# 
# This module has all methods of FileUtils module, but never changes
# files/directories.  This equates to passing the <tt>:noop</tt> and
# <tt>:verbose</tt> flags to methods in FileUtils.
# 

module FileUtils

  def self.private_module_function(name)   #:nodoc:
    module_function name
    private_class_method name
  end

  # This hash table holds command options.
  OPT_TABLE = {}   #:nodoc: internal use only

  #
  # Options: (none)
  #
  # Returns the name of the current directory.
  #
  def pwd
    Dir.pwd
  end
  module_function :pwd

  alias getwd pwd
  module_function :getwd

  #
  # Options: verbose
  # 
  # Changes the current directory to the directory +dir+.
  # 
  # If this method is called with block, resumes to the old
  # working directory after the block execution finished.
  # 
  #   FileUtils.cd('/', :verbose => true)   # chdir and report it
  # 
  def cd(dir, options = {}, &block) # :yield: dir
    fu_check_options options, OPT_TABLE['cd']
    fu_output_message "cd #{dir}" if options[:verbose]
    Dir.chdir(dir, &block)
    fu_output_message 'cd -' if options[:verbose] and block
  end
  module_function :cd

  alias chdir cd
  module_function :chdir

  OPT_TABLE['cd']    =
  OPT_TABLE['chdir'] = [:verbose]

  #
  # Options: (none)
  # 
  # Returns true if +newer+ is newer than all +old_list+.
  # Non-existent files are older than any file.
  # 
  #   FileUtils.uptodate?('hello.o', %w(hello.c hello.h)) or \
  #       system 'make hello.o'
  # 
  def uptodate?(new, old_list, options = nil)
    raise ArgumentError, 'uptodate? does not accept any option' if options

    return false unless File.exist?(new)
    new_time = File.mtime(new)
    old_list.each do |old|
      if File.exist?(old)
        return false unless new_time > File.mtime(old)
      end
    end
    true
  end
  module_function :uptodate?

  #
  # Options: mode noop verbose
  # 
  # Creates one or more directories.
  # 
  #   FileUtils.mkdir 'test'
  #   FileUtils.mkdir %w( tmp data )
  #   FileUtils.mkdir 'notexist', :noop => true  # Does not really create.
  #   FileUtils.mkdir 'tmp', :mode => 0700
  # 
  def mkdir(list, options = {})
    fu_check_options options, OPT_TABLE['mkdir']
    list = fu_list(list)
    fu_output_message "mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose]
    return if options[:noop]

    list.each do |dir|
      fu_mkdir dir, options[:mode]
    end
  end
  module_function :mkdir

  OPT_TABLE['mkdir'] = [:mode, :noop, :verbose]

  #
  # Options: mode noop verbose
  # 
  # Creates a directory and all its parent directories.
  # For example,
  # 
  #   FileUtils.mkdir_p '/usr/local/lib/ruby'
  # 
  # causes to make following directories, if it does not exist.
  #     * /usr
  #     * /usr/local
  #     * /usr/local/lib
  #     * /usr/local/lib/ruby
  #
  # You can pass several directories at a time in a list.
  # 
  def mkdir_p(list, options = {})
    fu_check_options options, OPT_TABLE['mkdir_p']
    list = fu_list(list)
    fu_output_message "mkdir -p #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose]
    return *list if options[:noop]

    list.map {|path| path.sub(%r</\z>, '') }.each do |path|
      # optimize for the most common case
      begin
        fu_mkdir path, options[:mode]
        next
      rescue SystemCallError
        next if File.directory?(path)
      end

      stack = []
      until path == stack.last   # dirname("/")=="/", dirname("C:/")=="C:/"
        stack.push path
        path = File.dirname(path)
      end
      stack.reverse_each do |path|
        begin
          fu_mkdir path, options[:mode]
        rescue SystemCallError => err
          raise unless File.directory?(path)
        end
      end
    end

    return *list
  end
  module_function :mkdir_p

  alias mkpath    mkdir_p
  alias makedirs  mkdir_p
  module_function :mkpath
  module_function :makedirs

  OPT_TABLE['mkdir_p']  =
  OPT_TABLE['mkpath']   =
  OPT_TABLE['makedirs'] = [:mode, :noop, :verbose]

  def fu_mkdir(path, mode)   #:nodoc:
    path = path.sub(%r</\z>, '')
    if mode
      Dir.mkdir path, mode
      File.chmod mode, path
    else
      Dir.mkdir path
    end
  end
  private_module_function :fu_mkdir

  #
  # Options: noop, verbose
  # 
  # Removes one or more directories.
  # 
  #   FileUtils.rmdir 'somedir'
  #   FileUtils.rmdir %w(somedir anydir otherdir)
  #   # Does not really remove directory; outputs message.
  #   FileUtils.rmdir 'somedir', :verbose => true, :noop => true
  # 
  def rmdir(list, options = {})
    fu_check_options options, OPT_TABLE['rmdir']
    list = fu_list(list)
    fu_output_message "rmdir #{list.join ' '}" if options[:verbose]
    return if options[:noop]
    list.each do |dir|
      Dir.rmdir dir.sub(%r</\z>, '')
    end
  end
  module_function :rmdir

  OPT_TABLE['rmdir'] = [:noop, :verbose]

  #
  # Options: force noop verbose
  #
  # <b><tt>ln(old, new, options = {})</tt></b>
  #
  # Creates a hard link +new+ which points to +old+.
  # If +new+ already exists and it is a directory, creates a link +new/old+.
  # If +new+ already exists and it is not a directory, raises Errno::EEXIST.
  # But if :force option is set, overwrite +new+.
  # 
  #   FileUtils.ln 'gcc', 'cc', :verbose => true
  #   FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'
  # 
  # <b><tt>ln(list, destdir, options = {})</tt></b>
  # 
  # Creates several hard links in a directory, with each one pointing to the
  # item in +list+.  If +destdir+ is not a directory, raises Errno::ENOTDIR.
  # 
  #   include FileUtils
  #   cd '/sbin'
  #   FileUtils.ln %w(cp mv mkdir), '/bin'   # Now /sbin/cp and /bin/cp are linked.
  # 
  def ln(src, dest, options = {})
    fu_check_options options, OPT_TABLE['ln']
    fu_output_message "ln#{options[:force] ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
    return if options[:noop]
    fu_each_src_dest0(src, dest) do |s,d|
      remove_file d, true if options[:force]
      File.link s, d
    end
  end
  module_function :ln

  alias link ln
  module_function :link

  OPT_TABLE['ln']   =
  OPT_TABLE['link'] = [:force, :noop, :verbose]

  #
  # Options: force noop verbose
  #
  # <b><tt>ln_s(old, new, options = {})</tt></b>
  # 
  # Creates a symbolic link +new+ which points to +old+.  If +new+ already
  # exists and it is a directory, creates a symbolic link +new/old+.  If +new+
  # already exists and it is not a directory, raises Errno::EEXIST.  But if
  # :force option is set, overwrite +new+.
  # 
  #   FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
  #   FileUtils.ln_s 'verylongsourcefilename.c', 'c', :force => true
  # 
  # <b><tt>ln_s(list, destdir, options = {})</tt></b>
  # 
  # Creates several symbolic links in a directory, with each one pointing to the
  # item in +list+.  If +destdir+ is not a directory, raises Errno::ENOTDIR.
  #
  # If +destdir+ is not a directory, raises Errno::ENOTDIR.
  # 
  #   FileUtils.ln_s Dir.glob('bin/*.rb'), '/home/aamine/bin'
  # 
  def ln_s(src, dest, options = {})
    fu_check_options options, OPT_TABLE['ln_s']
    fu_output_message "ln -s#{options[:force] ? 'f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
    return if options[:noop]
    fu_each_src_dest0(src, dest) do |s,d|
      remove_file d, true if options[:force]
      File.symlink s, d
    end
  end
  module_function :ln_s

  alias symlink ln_s
  module_function :symlink

  OPT_TABLE['ln_s']    =
  OPT_TABLE['symlink'] = [:force, :noop, :verbose]

  #
  # Options: noop verbose
  # 
  # Same as
  #   #ln_s(src, dest, :force)
  # 
  def ln_sf(src, dest, options = {})
    fu_check_options options, OPT_TABLE['ln_sf']
    options = options.dup
    options[:force] = true
    ln_s src, dest, options
  end
  module_function :ln_sf

  OPT_TABLE['ln_sf'] = [:noop, :verbose]

  #
  # Options: preserve noop verbose
  #
  # Copies a file content +src+ to +dest+.  If +dest+ is a directory,
  # copies +src+ to +dest/src+.
  #
  # If +src+ is a list of files, then +dest+ must be a directory.
  #
  #   FileUtils.cp 'eval.c', 'eval.c.org'
  #   FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'
  #   FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', :verbose => true
  #   FileUtils.cp 'symlink', 'dest'   # copy content, "dest" is not a symlink
  # 
  def cp(src, dest, options = {})
    fu_check_options options, OPT_TABLE['cp']
    fu_output_message "cp#{options[:preserve] ? ' -p' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
    return if options[:noop]
    fu_each_src_dest(src, dest) do |s, d|
      copy_file s, d, options[:preserve]
    end
  end
  module_function :cp

  alias copy cp
  module_function :copy

  OPT_TABLE['cp']   =
  OPT_TABLE['copy'] = [:preserve, :noop, :verbose]

  #
  # Options: preserve noop verbose dereference_root remove_destination
  # 
  # Copies +src+ to +dest+. If +src+ is a directory, this method copies
  # all its contents recursively. If +dest+ is a directory, copies
  # +src+ to +dest/src+.
  #
  # +src+ can be a list of files.
  # 
  #   # Installing ruby library "mylib" under the site_ruby
  #   FileUtils.rm_r site_ruby + '/mylib', :force
  #   FileUtils.cp_r 'lib/', site_ruby + '/mylib'
  # 
  #   # Examples of copying several files to target directory.
  #   FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
  #   FileUtils.cp_r Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop => true, :verbose => true
  #
  #   # If you want to copy all contents of a directory instead of the
  #   # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
  #   # use following code.
  #   FileUtils.cp_r 'src/.', 'dest'     # cp_r('src', 'dest') makes src/dest,
  #                                      # but this doesn't.
  # 
  def cp_r(src, dest, options = {})
    fu_check_options options, OPT_TABLE['cp_r']
    fu_output_message "cp -r#{options[:preserve] ? 'p' : ''}#{options[:remove_destination] ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
    return if options[:noop]
    options = options.dup
    options[:dereference_root] = true unless options.key?(:dereference_root)
    fu_each_src_dest(src, dest) do |s, d|
      copy_entry s, d, options[:preserve], options[:dereference_root], options[:remove_destination]
    end
  end
  module_function :cp_r

  OPT_TABLE['cp_r'] = [:preserve, :noop, :verbose,
                       :dereference_root, :remove_destination]

  #
  # Copies a file system entry +src+ to +dest+.
  # If +src+ is a directory, this method copies its contents recursively.
  # This method preserves file types, c.f. symlink, directory...
  # (FIFO, device files and etc. are not supported yet)
  #
  # Both of +src+ and +dest+ must be a path name.
  # +src+ must exist, +dest+ must not exist.
  #
  # If +preserve+ is true, this method preserves owner, group, permissions
  # and modified time.
  #
  # If +dereference_root+ is true, this method dereference tree root.
  #
  # If +remove_destination+ is true, this method removes each destination file before copy.
  #
  def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
    Entry_.new(src, nil, dereference_root).traverse do |ent|
      destent = Entry_.new(dest, ent.rel, false)
      File.unlink destent.path if remove_destination && File.file?(destent.path)
      ent.copy destent.path
      ent.copy_metadata destent.path if preserve
    end
  end
  module_function :copy_entry

  #
  # Copies file contents of +src+ to +dest+.
  # Both of +src+ and +dest+ must be a path name.
  #
  def copy_file(src, dest, preserve = false, dereference = true)
    ent = Entry_.new(src, nil, dereference)
    ent.copy_file dest
    ent.copy_metadata dest if preserve
  end
  module_function :copy_file

  #
  # Copies stream +src+ to +dest+.
  # +src+ must respond to #read(n) and
  # +dest+ must respond to #write(str).
  #
  def copy_stream(src, dest)
    fu_copy_stream0 src, dest, fu_stream_blksize(src, dest)
  end
  module_function :copy_stream

  #
  # Options: force noop verbose
  # 
  # Moves file(s) +src+ to +dest+.  If +file+ and +dest+ exist on the different
  # disk partition, the file is copied instead.
  # 
  #   FileUtils.mv 'badname.rb', 'goodname.rb'
  #   FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', :force => true  # no error
  # 
  #   FileUtils.mv %w(junk.txt dust.txt), '/home/aamine/.trash/'
  #   FileUtils.mv Dir.glob('test*.rb'), 'test', :noop => true, :verbose => true
  # 
  def mv(src, dest, options = {})
    fu_check_options options, OPT_TABLE['mv']
    fu_output_message "mv#{options[:force] ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
    return if options[:noop]
    fu_each_src_dest(src, dest) do |s, d|
      destent = Entry_.new(d, nil, true)
      begin
        if destent.exist?
          if destent.directory?
            raise Errno::EEXIST, dest
          else
            destent.remove_file if rename_cannot_overwrite_file?
          end
        end
        begin
          File.rename s, d
        rescue Errno::EXDEV
          copy_entry s, d, true
          if options[:secure]
            remove_entry_secure s, options[:force]
          else
            remove_entry s, options[:force]
          end
        end
      rescue SystemCallError
        raise unless options[:force]
      end
    end
  end
  module_function :mv

  alias move mv
  module_function :move

  OPT_TABLE['mv']   =
  OPT_TABLE['move'] = [:force, :noop, :verbose, :secure]

  def rename_cannot_overwrite_file?   #:nodoc:
    /djgpp|cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
  end
  private_module_function :rename_cannot_overwrite_file?

  #
  # Options: force noop verbose
  # 
  # Remove file(s) specified in +list+.  This method cannot remove directories.
  # All StandardErrors are ignored when the :force option is set.
  # 
  #   FileUtils.rm %w( junk.txt dust.txt )
  #   FileUtils.rm Dir.glob('*.so')
  #   FileUtils.rm 'NotExistFile', :force => true   # never raises exception
  # 
  def rm(list, options = {})
    fu_check_options options, OPT_TABLE['rm']
    list = fu_list(list)
    fu_output_message "rm#{options[:force] ? ' -f' : ''} #{list.join ' '}" if options[:verbose]
    return if options[:noop]

    list.each do |path|
      remove_file path, options[:force]
    end
  end
  module_function :rm

  alias remove rm
  module_function :remove

  OPT_TABLE['rm']     =
  OPT_TABLE['remove'] = [:force, :noop, :verbose]

  #
  # Options: noop verbose
  # 
  # Equivalent to
  #
  #   #rm(list, :force => true)
  #
  def rm_f(list, options = {})
    fu_check_options options, OPT_TABLE['rm_f']
    options = options.dup
    options[:force] = true
    rm list, options
  end
  module_function :rm_f

  alias safe_unlink rm_f
  module_function :safe_unlink

  OPT_TABLE['rm_f']        =
  OPT_TABLE['safe_unlink'] = [:noop, :verbose]

  #
  # Options: force noop verbose secure
  # 
  # remove files +list+[0] +list+[1]... If +list+[n] is a directory,
  # removes its all contents recursively. This method ignores
  # StandardError when :force option is set.
  # 
  #   FileUtils.rm_r Dir.glob('/tmp/*')
  #   FileUtils.rm_r '/', :force => true          #  :-)
  #
  # WARNING: This method causes local vulnerability
  # if one of parent directories or removing directory tree are world
  # writable (including /tmp, whose permission is 1777), and the current
  # process has strong privilege such as Unix super user (root), and the
  # system has symbolic link.  For secure removing, read the documentation
  # of #remove_entry_secure carefully, and set :secure option to true.
  # Default is :secure=>false.
  #
  # NOTE: This method calls #remove_entry_secure if :secure option is set.
  # See also #remove_entry_secure.
  # 
  def rm_r(list, options = {})
    fu_check_options options, OPT_TABLE['rm_r']
    # options[:secure] = true unless options.key?(:secure)
    list = fu_list(list)
    fu_output_message "rm -r#{options[:force] ? 'f' : ''} #{list.join ' '}" if options[:verbose]
    return if options[:noop]
    list.each do |path|
      if options[:secure]
        remove_entry_secure path, options[:force]
      else
        remove_entry path, options[:force]
      end
    end
  end
  module_function :rm_r

  OPT_TABLE['rm_r'] = [:force, :noop, :verbose, :secure]

  #
  # Options: noop verbose secure
  # 
  # Equivalent to
  #
  #   #rm_r(list, :force => true)
  #
  # WARNING: This method causes local vulnerability.
  # Read the documentation of #rm_r first.
  # 
  def rm_rf(list, options = {})
    fu_check_options options, OPT_TABLE['rm_rf']
    options = options.dup
    options[:force] = true
    rm_r list, options
  end
  module_function :rm_rf

  alias rmtree rm_rf
  module_function :rmtree

  OPT_TABLE['rm_rf']  =
  OPT_TABLE['rmtree'] = [:noop, :verbose, :secure]

  #
  # This method removes a file system entry +path+.  +path+ shall be a
  # regular file, a directory, or something.  If +path+ is a directory,
  # remove it recursively.  This method is required to avoid TOCTTOU
  # (time-of-check-to-time-of-use) local security vulnerability of #rm_r.
  # #rm_r causes security hole when:
  #
  #   * Parent directory is world writable (including /tmp).
  #   * Removing directory tree includes world writable directory.
  #   * The system has symbolic link.
  #
  # To avoid this security hole, this method applies special preprocess.
  # If +path+ is a directory, this method chown(2) and chmod(2) all
  # removing directories.  This requires the current process is the
  # owner of the removing whole directory tree, or is the super user (root).
  #
  # WARNING: You must ensure that *ALL* parent directories cannot be
  # moved by other untrusted users.  For example, parent directories
  # should not be owned by untrusted users, and should not be world
  # writable except when the sticky bit set.
  #
  # WARNING: Only the owner of the removing directory tree, or Unix super
  # user (root) should invoke this method.  Otherwise this method does not
  # work.
  #
  # For details of this security vulnerability, see Perl's case:
  #
  #   http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
  #   http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
  #
  # For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
  #
  def remove_entry_secure(path, force = false)
    unless fu_have_symlink?
      remove_entry path, force
      return
    end
    fullpath = File.expand_path(path)
    st = File.lstat(fullpath)
    unless st.directory?
      File.unlink fullpath
      return
    end
    # is a directory.
    parent_st = File.stat(File.dirname(fullpath))
    unless fu_world_writable?(parent_st)
      remove_entry path, force
      return
    end
    unless parent_st.sticky?
      raise ArgumentError, "parent directory is world writable, FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})"
    end
    # freeze tree root
    euid = Process.euid
    File.open(fullpath + '/.') {|f|
      unless fu_stat_identical_entry?(st, f.stat)
        # symlink (TOC-to-TOU attack?)
        File.unlink fullpath
        return
      end
      f.chown euid, -1
      f.chmod 0700
      unless fu_stat_identical_entry?(st, File.lstat(fullpath))
        # TOC-to-TOU attack?
        File.unlink fullpath
        return
      end
    }
    # ---- tree root is frozen ----
    root = Entry_.new(path)
    root.preorder_traverse do |ent|
      if ent.directory?
        ent.chown euid, -1
        ent.chmod 0700
      end
    end
    root.postorder_traverse do |ent|
      begin
        ent.remove
      rescue
        raise unless force
      end
    end
  rescue
    raise unless force
  end
  module_function :remove_entry_secure

  def fu_world_writable?(st)
    (st.mode & 0002) != 0
  end
  private_module_function :fu_world_writable?

  def fu_have_symlink?   #:nodoc
    File.symlink nil, nil
  rescue NotImplementedError
    return false
  rescue
    return true
  end
  private_module_function :fu_have_symlink?

  def fu_stat_identical_entry?(a, b)   #:nodoc:
    a.dev == b.dev and a.ino == b.ino
  end
  private_module_function :fu_stat_identical_entry?

  #
  # This method removes a file system entry +path+.
  # +path+ might be a regular file, a directory, or something.
  # If +path+ is a directory, remove it recursively.
  #
  # See also #remove_entry_secure.
  #
  def remove_entry(path, force = false)
    Entry_.new(path).postorder_traverse do |ent|
      begin
        ent.remove
      rescue
        raise unless force
      end
    end
  rescue
    raise unless force
  end
  module_function :remove_entry

  #
  # Removes a file +path+.
  # This method ignores StandardError if +force+ is true.
  #
  def remove_file(path, force = false)
    Entry_.new(path).remove_file
  rescue
    raise unless force
  end
  module_function :remove_file

  #
  # Removes a directory +dir+ and its contents recursively.
  # This method ignores StandardError if +force+ is true.
  #
  def remove_dir(path, force = false)
    remove_entry path, force   # FIXME?? check if it is a directory
  end
  module_function :remove_dir

  #
  # Returns true if the contents of a file A and a file B are identical.
  # 
  #   FileUtils.compare_file('somefile', 'somefile')  #=> true
  #   FileUtils.compare_file('/bin/cp', '/bin/mv')    #=> maybe false
  #
  def compare_file(a, b)
    return false unless File.size(a) == File.size(b)
    File.open(a, 'rb') {|fa|
      File.open(b, 'rb') {|fb|
        return compare_stream(fa, fb)
      }
    }
  end
  module_function :compare_file

  alias identical? compare_file
  alias cmp compare_file
  module_function :identical?
  module_function :cmp

  #
  # Returns true if the contents of a stream +a+ and +b+ are identical.
  #
  def compare_stream(a, b)
    bsize = fu_stream_blksize(a, b)
    sa = sb = nil
    while sa == sb
      sa = a.read(bsize)
      sb = b.read(bsize)
      unless sa and sb
        if sa.nil? and sb.nil?
          return true
        end
      end
    end
    false
  end
  module_function :compare_stream

  #
  # Options: mode preserve noop verbose
  # 
  # If +src+ is not same as +dest+, copies it and changes the permission
  # mode to +mode+.  If +dest+ is a directory, destination is +dest+/+src+.
  # This method removes destination before copy.
  # 
  #   FileUtils.install 'ruby', '/usr/local/bin/ruby', :mode => 0755, :verbose => true
  #   FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :verbose => true
  # 
  def install(src, dest, options = {})
    fu_check_options options, OPT_TABLE['install']
    fu_output_message "install -c#{options[:preserve] && ' -p'}#{options[:mode] ? (' -m 0%o' % options[:mode]) : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
    return if options[:noop]
    fu_each_src_dest(src, dest) do |s, d|
      unless File.exist?(d) and compare_file(s, d)
        remove_file d, true
        st = File.stat(s) if options[:preserve]
        copy_file s, d
        File.utime st.atime, st.mtime, d if options[:preserve]
        File.chmod options[:mode], d if options[:mode]
      end
    end
  end
  module_function :install

  OPT_TABLE['install'] = [:mode, :preserve, :noop, :verbose]

  #
  # Options: noop verbose
  # 
  # Changes permission bits on the named files (in +list+) to the bit pattern
  # represented by +mode+.
  # 
  #   FileUtils.chmod 0755, 'somecommand'
  #   FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
  #   FileUtils.chmod 0755, '/usr/bin/ruby', :verbose => true
  # 
  def chmod(mode, list, options = {})
    fu_check_options options, OPT_TABLE['chmod']
    list = fu_list(list)
    fu_output_message sprintf('chmod %o %s', mode, list.join(' ')) if options[:verbose]
    return if options[:noop]
    list.each do |path|
      Entry_.new(path).chmod mode
    end
  end
  module_function :chmod

  OPT_TABLE['chmod'] = [:noop, :verbose]

  #
  # Options: noop verbose force
  # 
  # Changes permission bits on the named files (in +list+)
  # to the bit pattern represented by +mode+.
  # 
  #   FileUtils.chmod_R 0700, "/tmp/app.#{$$}"
  # 
  def chmod_R(mode, list, options = {})
    fu_check_options options, OPT_TABLE['chmod_R']
    list = fu_list(list)
    fu_output_message sprintf('chmod -R%s %o %s',
                              (options[:force] ? 'f' : ''),
                              mode, list.join(' ')) if options[:verbose]
    return if options[:noop]
    list.each do |root|
      Entry_.new(root).traverse do |ent|
        begin
          ent.chmod mode
        rescue
          raise unless options[:force]
        end
      end
    end
  end
  module_function :chmod_R

  OPT_TABLE['chmod_R'] = [:noop, :verbose, :force]

  #
  # Options: noop verbose
  # 
  # Changes owner and group on the named files (in +list+)
  # to the user +user+ and the group +group+.  +user+ and +group+
  # may be an ID (Integer/String) or a name (String).
  # If +user+ or +group+ is nil, this method does not change
  # the attribute.
  # 
  #   FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
  #   FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :verbose => true
  # 
  def chown(user, group, list, options = {})
    fu_check_options options, OPT_TABLE['chown']
    list = fu_list(list)
    fu_output_message sprintf('chown %s%s',
                              [user,group].compact.join(':') + ' ',
                              list.join(' ')) if options[:verbose]
    return if options[:noop]
    uid = fu_get_uid(user)
    gid = fu_get_gid(group)
    list.each do |path|
      Entry_.new(path).chown uid, gid
    end
  end
  module_function :chown

  OPT_TABLE['chown'] = [:noop, :verbose]

  #
  # Options: noop verbose force
  # 
  # Changes owner and group on the named files (in +list+)
  # to the user +user+ and the group +group+ recursively.
  # +user+ and +group+ may be an ID (Integer/String) or
  # a name (String).  If +user+ or +group+ is nil, this
  # method does not change the attribute.
  # 
  #   FileUtils.chown_R 'www', 'www', '/var/www/htdocs'
  #   FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', :verbose => true
  # 
  def chown_R(user, group, list, options = {})
    fu_check_options options, OPT_TABLE['chown_R']
    list = fu_list(list)
    fu_output_message sprintf('chown -R%s %s%s',
                              (options[:force] ? 'f' : ''),
                              [user,group].compact.join(':') + ' ',
                              list.join(' ')) if options[:verbose]
    return if options[:noop]
    uid = fu_get_uid(user)
    gid = fu_get_gid(group)
    return unless uid or gid
    list.each do |root|
      Entry_.new(root).traverse do |ent|
        begin
          ent.chown uid, gid
        rescue
          raise unless options[:force]
        end
      end
    end
  end
  module_function :chown_R

  OPT_TABLE['chown_R'] = [:noop, :verbose, :force]

  begin
    require 'etc'

    def fu_get_uid(user)   #:nodoc:
      return nil unless user
      user = user.to_s
      if /\A\d+\z/ =~ user
      then user.to_i
      else Etc.getpwnam(user).uid
      end
    end
    private_module_function :fu_get_uid

    def fu_get_gid(group)   #:nodoc:
      return nil unless group
      group = group.to_s
      if /\A\d+\z/ =~ group
      then group.to_i
      else Etc.getgrnam(group).gid
      end
    end
    private_module_function :fu_get_gid

  rescue LoadError
    # need Win32 support???

    def fu_get_uid(user)   #:nodoc:
      user    # FIXME
    end
    private_module_function :fu_get_uid

    def fu_get_gid(group)   #:nodoc:
      group   # FIXME
    end
    private_module_function :fu_get_gid
  end

  #
  # Options: noop verbose
  # 
  # Updates modification time (mtime) and access time (atime) of file(s) in
  # +list+.  Files are created if they don't exist.
  # 
  #   FileUtils.touch 'timestamp'
  #   FileUtils.touch Dir.glob('*.c');  system 'make'
  # 
  def touch(list, options = {})
    fu_check_options options, OPT_TABLE['touch']
    list = fu_list(list)
    created = nocreate = options[:nocreate]
    t = options[:mtime]
    if options[:verbose]
      fu_output_message "touch #{nocreate ? '-c ' : ''}#{t ? t.strftime('-t %Y%m%d%H%M.%S ') : ''}#{list.join ' '}"
    end
    return if options[:noop]
    list.each do |path|
      created = nocreate
      begin
        File.utime(t, t, path)
      rescue Errno::ENOENT
        raise if created
        File.open(path, 'a') {
          ;
        }
        created = true
        retry if t
      end
    end
  end
  module_function :touch

  OPT_TABLE['touch'] = [:noop, :verbose, :mtime, :nocreate]

  private

  module StreamUtils_
    private

    def fu_windows?
      /mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
    end

    def fu_copy_stream0(src, dest, blksize)   #:nodoc:
      # FIXME: readpartial?
      while s = src.read(blksize)
        dest.write s
      end
    end

    def fu_stream_blksize(*streams)
      streams.each do |s|
        next unless s.respond_to?(:stat)
        size = fu_blksize(s.stat)
        return size if size
      end
      fu_default_blksize()
    end

    def fu_blksize(st)
      s = st.blksize
      return nil unless s
      return nil if s == 0
      s
    end

    def fu_default_blksize
      1024
    end
  end

  include StreamUtils_
  extend StreamUtils_

  class Entry_   #:nodoc: internal use only
    include StreamUtils_

    def initialize(a, b = nil, deref = false)
      @prefix = @rel = @path = nil
      if b
        @prefix = a
        @rel = b
      else
        @path = a
      end
      @deref = deref
      @stat = nil
      @lstat = nil
    end

    def inspect
      "\#<#{self.class} #{path()}>"
    end

    def path
      if @path
        @path.to_str
      else
        join(@prefix, @rel)
      end
    end

    def prefix
      @prefix || @path
    end

    def rel
      @rel
    end

    def dereference?
      @deref
    end

    def exist?
      lstat! ? true : false
    end

    def file?
      s = lstat!
      s and s.file?
    end

    def directory?
      s = lstat!
      s and s.directory?
    end

    def symlink?
      s = lstat!
      s and s.symlink?
    end

    def chardev?
      s = lstat!
      s and s.chardev?
    end

    def blockdev?
      s = lstat!
      s and s.blockdev?
    end

    def socket?
      s = lstat!
      s and s.socket?
    end

    def pipe?
      s = lstat!
      s and s.pipe?
    end

    S_IF_DOOR = 0xD000

    def door?
      s = lstat!
      s and (s.mode & 0xF000 == S_IF_DOOR)
    end

    def entries
      Dir.entries(path())\
          .reject {|n| n == '.' or n == '..' }\
          .map {|n| Entry_.new(prefix(), join(rel(), n.untaint)) }
    end

    def stat
      return @stat if @stat
      if lstat() and lstat().symlink?
        @stat = File.stat(path())
      else
        @stat = lstat()
      end
      @stat
    end

    def stat!
      return @stat if @stat
      if lstat! and lstat!.symlink?
        @stat = File.stat(path())
      else
        @stat = lstat!
      end
      @stat
    rescue SystemCallError
      nil
    end

    def lstat
      if dereference?
        @lstat ||= File.stat(path())
      else
        @lstat ||= File.lstat(path())
      end
    end

    def lstat!
      lstat()
    rescue SystemCallError
      nil
    end

    def chmod(mode)
      if symlink?
        File.lchmod mode, path() if have_lchmod?
      else
        File.chmod mode, path()
      end
    end

    def chown(uid, gid)
      if symlink?
        File.lchown uid, gid, path() if have_lchown?
      else
        File.chown uid, gid, path()
      end
    end

    def copy(dest)
      case
      when file?
        copy_file dest
      when directory?
        begin
          Dir.mkdir dest
        rescue
          raise unless File.directory?(dest)
        end
      when symlink?
        File.symlink File.readlink(path()), dest
      when chardev?
        raise "cannot handle device file" unless File.respond_to?(:mknod)
        mknod dest, ?c, 0666, lstat().rdev
      when blockdev?
        raise "cannot handle device file" unless File.respond_to?(:mknod)
        mknod dest, ?b, 0666, lstat().rdev
      when socket?
        raise "cannot handle socket" unless File.respond_to?(:mknod)
        mknod dest, nil, lstat().mode, 0
      when pipe?
        raise "cannot handle FIFO" unless File.respond_to?(:mkfifo)
        mkfifo dest, 0666
      when door?
        raise "cannot handle door: #{path()}"
      else
        raise "unknown file type: #{path()}"
      end
    end

    def copy_file(dest)
      st = stat()
      File.open(path(),  'rb') {|r|
        File.open(dest, 'wb', st.mode) {|w|
          fu_copy_stream0 r, w, (fu_blksize(st) || fu_default_blksize())
        }
      }
    end

    def copy_metadata(path)
      st = lstat()
      File.utime st.atime, st.mtime, path
      begin
        File.chown st.uid, st.gid, path
      rescue Errno::EPERM
        # clear setuid/setgid
        File.chmod st.mode & 01777, path
      else
        File.chmod st.mode, path
      end
    end

    def remove
      if directory?
        remove_dir1
      else
        remove_file
      end
    end

    def remove_dir1
      platform_support {
        Dir.rmdir path().sub(%r</\z>, '')
      }
    end

    def remove_file
      platform_support {
        File.unlink path
      }
    end

    def platform_support
      return yield unless fu_windows?
      first_time_p = true
      begin
        yield
      rescue Errno::ENOENT
        raise
      rescue => err
        if first_time_p
          first_time_p = false
          begin
            File.chmod 0700, path()   # Windows does not have symlink
            retry
          rescue SystemCallError
          end
        end
        raise err
      end
    end

    def preorder_traverse
      stack = [self]
      while ent = stack.pop
        yield ent
        stack.concat ent.entries.reverse if ent.directory?
      end
    end

    alias traverse preorder_traverse

    def postorder_traverse
      if directory?
        entries().each do |ent|
          ent.postorder_traverse do |e|
            yield e
          end
        end
      end
      yield self
    end

    private

    $fileutils_rb_have_lchmod = nil

    def have_lchmod?
      # This is not MT-safe, but it does not matter.
      if $fileutils_rb_have_lchmod == nil
        $fileutils_rb_have_lchmod = check_have_lchmod?
      end
      $fileutils_rb_have_lchmod
    end

    def check_have_lchmod?
      return false unless File.respond_to?(:lchmod)
      File.lchmod 0
      return true
    rescue NotImplementedError
      return false
    end

    $fileutils_rb_have_lchown = nil

    def have_lchown?
      # This is not MT-safe, but it does not matter.
      if $fileutils_rb_have_lchown == nil
        $fileutils_rb_have_lchown = check_have_lchown?
      end
      $fileutils_rb_have_lchown
    end

    def check_have_lchown?
      return false unless File.respond_to?(:lchown)
      File.lchown nil, nil
      return true
    rescue NotImplementedError
      return false
    end

    def join(dir, base)
      return dir.to_str if not base or base == '.'
      return base.to_str if not dir or dir == '.'
      File.join(dir, base)
    end
  end   # class Entry_

  def fu_list(arg)   #:nodoc:
    [arg].flatten.map {|path| path.to_str }
  end
  private_module_function :fu_list

  def fu_each_src_dest(src, dest)   #:nodoc:
    fu_each_src_dest0(src, dest) do |s, d|
      raise ArgumentError, "same file: #{s} and #{d}" if fu_same?(s, d)
      yield s, d
    end
  end
  private_module_function :fu_each_src_dest

  def fu_each_src_dest0(src, dest)   #:nodoc:
    if src.is_a?(Array)
      src.each do |s|
        s = s.to_str
        yield s, File.join(dest, File.basename(s))
      end
    else
      src = src.to_str
      if File.directory?(dest)
        yield src, File.join(dest, File.basename(src))
      else
        yield src, dest.to_str
      end
    end
  end
  private_module_function :fu_each_src_dest0

  def fu_same?(a, b)   #:nodoc:
    if fu_have_st_ino?
      st1 = File.stat(a)
      st2 = File.stat(b)
      st1.dev == st2.dev and st1.ino == st2.ino
    else
      File.expand_path(a) == File.expand_path(b)
    end
  rescue Errno::ENOENT
    return false
  end
  private_module_function :fu_same?

  def fu_have_st_ino?   #:nodoc:
    not fu_windows?
  end
  private_module_function :fu_have_st_ino?

  def fu_check_options(options, optdecl)   #:nodoc:
    h = options.dup
    optdecl.each do |opt|
      h.delete opt
    end
    raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless h.empty?
  end
  private_module_function :fu_check_options

  def fu_update_option(args, new)   #:nodoc:
    if args.last.is_a?(Hash)
      args[-1] = args.last.dup.update(new)
    else
      args.push new
    end
    args
  end
  private_module_function :fu_update_option

  @fileutils_output = $stderr
  @fileutils_label  = ''

  def fu_output_message(msg)   #:nodoc:
    @fileutils_output ||= $stderr
    @fileutils_label  ||= ''
    @fileutils_output.puts @fileutils_label + msg
  end
  private_module_function :fu_output_message

  #
  # Returns an Array of method names which have any options.
  #
  #   p FileUtils.commands  #=> ["chmod", "cp", "cp_r", "install", ...]
  #
  def FileUtils.commands
    OPT_TABLE.keys
  end

  #
  # Returns an Array of option names.
  #
  #   p FileUtils.options  #=> ["noop", "force", "verbose", "preserve", "mode"]
  #
  def FileUtils.options
    OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s }
  end

  #
  # Returns true if the method +mid+ have an option +opt+.
  #
  #   p FileUtils.have_option?(:cp, :noop)     #=> true
  #   p FileUtils.have_option?(:rm, :force)    #=> true
  #   p FileUtils.have_option?(:rm, :perserve) #=> false
  #
  def FileUtils.have_option?(mid, opt)
    li = OPT_TABLE[mid.to_s] or raise ArgumentError, "no such method: #{mid}"
    li.include?(opt)
  end

  #
  # Returns an Array of option names of the method +mid+.
  #
  #   p FileUtils.options(:rm)  #=> ["noop", "verbose", "force"]
  #
  def FileUtils.options_of(mid)
    OPT_TABLE[mid.to_s].map {|sym| sym.to_s }
  end

  #
  # Returns an Array of method names which have the option +opt+.
  #
  #   p FileUtils.collect_method(:preserve) #=> ["cp", "cp_r", "copy", "install"]
  #
  def FileUtils.collect_method(opt)
    OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) }
  end

  METHODS = singleton_methods() - %w( private_module_function
      commands options have_option? options_of collect_method )

  # 
  # This module has all methods of FileUtils module, but it outputs messages
  # before acting.  This equates to passing the <tt>:verbose</tt> flag to
  # methods in FileUtils.
  # 
  module Verbose
    include FileUtils
    @fileutils_output  = $stderr
    @fileutils_label   = ''
    ::FileUtils.collect_method(:verbose).each do |name|
      module_eval(<<-EOS, __FILE__, __LINE__ + 1)
        def #{name}(*args)
          super(*fu_update_option(args, :verbose => true))
        end
        private :#{name}
      EOS
    end
    extend self
    class << self
      ::FileUtils::METHODS.each do |m|
        public m
      end
    end
  end

  # 
  # This module has all methods of FileUtils module, but never changes
  # files/directories.  This equates to passing the <tt>:noop</tt> flag
  # to methods in FileUtils.
  # 
  module NoWrite
    include FileUtils
    @fileutils_output  = $stderr
    @fileutils_label   = ''
    ::FileUtils.collect_method(:noop).each do |name|
      module_eval(<<-EOS, __FILE__, __LINE__ + 1)
        def #{name}(*args)
          super(*fu_update_option(args, :noop => true))
        end
        private :#{name}
      EOS
    end
    extend self
    class << self
      ::FileUtils::METHODS.each do |m|
        public m
      end
    end
  end

  # 
  # This module has all methods of FileUtils module, but never changes
  # files/directories, with printing message before acting.
  # This equates to passing the <tt>:noop</tt> and <tt>:verbose</tt> flag
  # to methods in FileUtils.
  # 
  module DryRun
    include FileUtils
    @fileutils_output  = $stderr
    @fileutils_label   = ''
    ::FileUtils.collect_method(:noop).each do |name|
      module_eval(<<-EOS, __FILE__, __LINE__ + 1)
        def #{name}(*args)
          super(*fu_update_option(args, :noop => true, :verbose => true))
        end
        private :#{name}
      EOS
    end
    extend self
    class << self
      ::FileUtils::METHODS.each do |m|
        public m
      end
    end
  end

end
PK     Z\ojV      md5.rbnu [        # just for compatibility; requiring "md5" is obsoleted
#
# $RoughId: md5.rb,v 1.4 2001/07/13 15:38:27 knu Exp $
# $Id: md5.rb 12007 2007-03-06 10:09:51Z knu $

require 'digest/md5'

class MD5 < Digest::MD5
  class << self
    alias orig_new new
    def new(str = nil)
      if str
        orig_new.update(str)
      else
        orig_new
      end
    end

    def md5(*args)
      new(*args)
    end
  end
end
PK     Z\      ping.rbnu [        #
# = ping.rb: Check a host for upness
#
# Author:: Yukihiro Matsumoto
# Documentation:: Konrad Meyer
# 
# Performs the function of the basic network testing tool, ping.
# See: Ping.
#

require 'timeout'
require "socket"

# 
# Ping contains routines to test for the reachability of remote hosts.
# Currently the only routine implemented is pingecho().
#
# Ping.pingecho uses a TCP echo (not an ICMP echo) to determine if the
# remote host is reachable. This is usually adequate to tell that a remote
# host is available to telnet, ftp, or ssh to.
#
# Warning: Ping.pingecho may block for a long time if DNS resolution is
# slow. Requiring 'resolv-replace' allows non-blocking name resolution.
#
# Usage:
# 
#   require 'ping'
#
#   puts "'jimmy' is alive and kicking" if Ping.pingecho('jimmy', 10)
#
module Ping

  # 
  # Return true if we can open a connection to the hostname or IP address
  # +host+ on port +service+ (which defaults to the "echo" port) waiting up
  # to +timeout+ seconds.
  #
  # Example:
  #
  #   require 'ping'
  #
  #   Ping.pingecho "google.com", 10, 80
  #
  def pingecho(host, timeout=5, service="echo")
    begin
      timeout(timeout) do
	s = TCPSocket.new(host, service)
	s.close
      end
    rescue Errno::ECONNREFUSED
      return true
    rescue Timeout::Error, StandardError
      return false
    end
    return true
  end
  module_function :pingecho
end

if $0 == __FILE__
  host = ARGV[0]
  host ||= "localhost"
  printf("%s alive? - %s\n", host,  Ping::pingecho(host, 5))
end
PK     Z\0mr  r    date/format.rbnu [        # format.rb: Written by Tadayoshi Funaba 1999-2008
# $Id: format.rb,v 2.43 2008-01-17 20:16:31+09 tadf Exp $

require 'rational'

class Date

  module Format # :nodoc:

    MONTHS = {
      'january'  => 1, 'february' => 2, 'march'    => 3, 'april'    => 4,
      'may'      => 5, 'june'     => 6, 'july'     => 7, 'august'   => 8,
      'september'=> 9, 'october'  =>10, 'november' =>11, 'december' =>12
    }

    DAYS = {
      'sunday'   => 0, 'monday'   => 1, 'tuesday'  => 2, 'wednesday'=> 3,
      'thursday' => 4, 'friday'   => 5, 'saturday' => 6
    }

    ABBR_MONTHS = {
      'jan'      => 1, 'feb'      => 2, 'mar'      => 3, 'apr'      => 4,
      'may'      => 5, 'jun'      => 6, 'jul'      => 7, 'aug'      => 8,
      'sep'      => 9, 'oct'      =>10, 'nov'      =>11, 'dec'      =>12
    }

    ABBR_DAYS = {
      'sun'      => 0, 'mon'      => 1, 'tue'      => 2, 'wed'      => 3,
      'thu'      => 4, 'fri'      => 5, 'sat'      => 6
    }

    ZONES = {
      'ut'  =>  0*3600, 'gmt' =>  0*3600, 'est' => -5*3600, 'edt' => -4*3600,
      'cst' => -6*3600, 'cdt' => -5*3600, 'mst' => -7*3600, 'mdt' => -6*3600,
      'pst' => -8*3600, 'pdt' => -7*3600,
      'a'   =>  1*3600, 'b'   =>  2*3600, 'c'   =>  3*3600, 'd'   =>  4*3600,
      'e'   =>  5*3600, 'f'   =>  6*3600, 'g'   =>  7*3600, 'h'   =>  8*3600,
      'i'   =>  9*3600, 'k'   => 10*3600, 'l'   => 11*3600, 'm'   => 12*3600,
      'n'   => -1*3600, 'o'   => -2*3600, 'p'   => -3*3600, 'q'   => -4*3600,
      'r'   => -5*3600, 's'   => -6*3600, 't'   => -7*3600, 'u'   => -8*3600,
      'v'   => -9*3600, 'w'   =>-10*3600, 'x'   =>-11*3600, 'y'   =>-12*3600,
      'z'   =>  0*3600,

      'utc' =>  0*3600, 'wet' =>  0*3600,
      'at'  => -2*3600, 'brst'=> -2*3600, 'ndt' => -(2*3600+1800),
      'art' => -3*3600, 'adt' => -3*3600, 'brt' => -3*3600, 'clst'=> -3*3600,
      'nst' => -(3*3600+1800),
      'ast' => -4*3600, 'clt' => -4*3600,
      'akdt'=> -8*3600, 'ydt' => -8*3600,
      'akst'=> -9*3600, 'hadt'=> -9*3600, 'hdt' => -9*3600, 'yst' => -9*3600,
      'ahst'=>-10*3600, 'cat' =>-10*3600, 'hast'=>-10*3600, 'hst' =>-10*3600,
      'nt'  =>-11*3600,
      'idlw'=>-12*3600,
      'bst' =>  1*3600, 'cet' =>  1*3600, 'fwt' =>  1*3600, 'met' =>  1*3600,
      'mewt'=>  1*3600, 'mez' =>  1*3600, 'swt' =>  1*3600, 'wat' =>  1*3600,
      'west'=>  1*3600,
      'cest'=>  2*3600, 'eet' =>  2*3600, 'fst' =>  2*3600, 'mest'=>  2*3600,
      'mesz'=>  2*3600, 'sast'=>  2*3600, 'sst' =>  2*3600,
      'bt'  =>  3*3600, 'eat' =>  3*3600, 'eest'=>  3*3600, 'msk' =>  3*3600,
      'msd' =>  4*3600, 'zp4' =>  4*3600,
      'zp5' =>  5*3600, 'ist' =>  (5*3600+1800),
      'zp6' =>  6*3600,
      'wast'=>  7*3600,
      'cct' =>  8*3600, 'sgt' =>  8*3600, 'wadt'=>  8*3600,
      'jst' =>  9*3600, 'kst' =>  9*3600,
      'east'=> 10*3600, 'gst' => 10*3600,
      'eadt'=> 11*3600,
      'idle'=> 12*3600, 'nzst'=> 12*3600, 'nzt' => 12*3600,
      'nzdt'=> 13*3600,

      'afghanistan'           =>   16200, 'alaskan'               =>  -32400,
      'arab'                  =>   10800, 'arabian'               =>   14400,
      'arabic'                =>   10800, 'atlantic'              =>  -14400,
      'aus central'           =>   34200, 'aus eastern'           =>   36000,
      'azores'                =>   -3600, 'canada central'        =>  -21600,
      'cape verde'            =>   -3600, 'caucasus'              =>   14400,
      'cen. australia'        =>   34200, 'central america'       =>  -21600,
      'central asia'          =>   21600, 'central europe'        =>    3600,
      'central european'      =>    3600, 'central pacific'       =>   39600,
      'central'               =>  -21600, 'china'                 =>   28800,
      'dateline'              =>  -43200, 'e. africa'             =>   10800,
      'e. australia'          =>   36000, 'e. europe'             =>    7200,
      'e. south america'      =>  -10800, 'eastern'               =>  -18000,
      'egypt'                 =>    7200, 'ekaterinburg'          =>   18000,
      'fiji'                  =>   43200, 'fle'                   =>    7200,
      'greenland'             =>  -10800, 'greenwich'             =>       0,
      'gtb'                   =>    7200, 'hawaiian'              =>  -36000,
      'india'                 =>   19800, 'iran'                  =>   12600,
      'jerusalem'             =>    7200, 'korea'                 =>   32400,
      'mexico'                =>  -21600, 'mid-atlantic'          =>   -7200,
      'mountain'              =>  -25200, 'myanmar'               =>   23400,
      'n. central asia'       =>   21600, 'nepal'                 =>   20700,
      'new zealand'           =>   43200, 'newfoundland'          =>  -12600,
      'north asia east'       =>   28800, 'north asia'            =>   25200,
      'pacific sa'            =>  -14400, 'pacific'               =>  -28800,
      'romance'               =>    3600, 'russian'               =>   10800,
      'sa eastern'            =>  -10800, 'sa pacific'            =>  -18000,
      'sa western'            =>  -14400, 'samoa'                 =>  -39600,
      'se asia'               =>   25200, 'malay peninsula'       =>   28800,
      'south africa'          =>    7200, 'sri lanka'             =>   21600,
      'taipei'                =>   28800, 'tasmania'              =>   36000,
      'tokyo'                 =>   32400, 'tonga'                 =>   46800,
      'us eastern'            =>  -18000, 'us mountain'           =>  -25200,
      'vladivostok'           =>   36000, 'w. australia'          =>   28800,
      'w. central africa'     =>    3600, 'w. europe'             =>    3600,
      'west asia'             =>   18000, 'west pacific'          =>   36000,
      'yakutsk'               =>   32400
    }

    [MONTHS, DAYS, ABBR_MONTHS, ABBR_DAYS, ZONES].each do |x|
      x.freeze
    end

    class Bag # :nodoc:

      def initialize
	@elem = {}
      end

      def method_missing(t, *args, &block)
	t = t.to_s
	set = t.chomp!('=')
	t = t.intern
	if set
	  @elem[t] = args[0]
	else
	  @elem[t]
	end
      end

      def to_hash
	@elem.reject{|k, v| /\A_/ =~ k.to_s || v.nil?}
      end

    end

  end

  def emit(e, f) # :nodoc:
    case e
    when Numeric
      sign = %w(+ + -)[e <=> 0]
      e = e.abs
    end

    s = e.to_s

    if f[:s] && f[:p] == '0'
      f[:w] -= 1
    end

    if f[:s] && f[:p] == "\s"
      s[0,0] = sign
    end

    if f[:p] != '-'
      s = s.rjust(f[:w], f[:p])
    end

    if f[:s] && f[:p] != "\s"
      s[0,0] = sign
    end

    s = s.upcase if f[:u]
    s = s.downcase if f[:d]
    s
  end

  def emit_w(e, w, f) # :nodoc:
    f[:w] = [f[:w], w].compact.max
    emit(e, f)
  end

  def emit_n(e, w, f) # :nodoc:
    f[:p] ||= '0'
    emit_w(e, w, f)
  end

  def emit_sn(e, w, f) # :nodoc:
    if e < 0
      w += 1
      f[:s] = true
    end
    emit_n(e, w, f)
  end

  def emit_z(e, w, f) # :nodoc:
    w += 1
    f[:s] = true
    emit_n(e, w, f)
  end

  def emit_a(e, w, f) # :nodoc:
    f[:p] ||= "\s"
    emit_w(e, w, f)
  end

  def emit_ad(e, w, f) # :nodoc:
    if f[:x]
      f[:u] = true
      f[:d] = false
    end
    emit_a(e, w, f)
  end

  def emit_au(e, w, f) # :nodoc:
    if f[:x]
      f[:u] = false
      f[:d] = true
    end
    emit_a(e, w, f)
  end

  private :emit, :emit_w, :emit_n, :emit_sn, :emit_z,
	  :emit_a, :emit_ad, :emit_au

  def strftime(fmt='%F')
    fmt.gsub(/%([-_0^#]+)?(\d+)?([EO]?(?::{1,3}z|.))/m) do |m|
      f = {}
      a = $&
      s, w, c = $1, $2, $3
      if s
	s.scan(/./) do |k|
	  case k
	  when '-'; f[:p] = '-'
	  when '_'; f[:p] = "\s"
	  when '0'; f[:p] = '0'
	  when '^'; f[:u] = true
	  when '#'; f[:x] = true
	  end
	end
      end
      if w
	f[:w] = w.to_i
      end
      case c
      when 'A'; emit_ad(DAYNAMES[wday], 0, f)
      when 'a'; emit_ad(ABBR_DAYNAMES[wday], 0, f)
      when 'B'; emit_ad(MONTHNAMES[mon], 0, f)
      when 'b'; emit_ad(ABBR_MONTHNAMES[mon], 0, f)
      when 'C', 'EC'; emit_sn((year / 100).floor, 2, f)
      when 'c', 'Ec'; emit_a(strftime('%a %b %e %H:%M:%S %Y'), 0, f)
      when 'D'; emit_a(strftime('%m/%d/%y'), 0, f)
      when 'd', 'Od'; emit_n(mday, 2, f)
      when 'e', 'Oe'; emit_a(mday, 2, f)
      when 'F'
	if m == '%F'
	  format('%.4d-%02d-%02d', year, mon, mday) # 4p
	else
	  emit_a(strftime('%Y-%m-%d'), 0, f)
	end
      when 'G'; emit_sn(cwyear, 4, f)
      when 'g'; emit_n(cwyear % 100, 2, f)
      when 'H', 'OH'; emit_n(hour, 2, f)
      when 'h'; emit_ad(strftime('%b'), 0, f)
      when 'I', 'OI'; emit_n((hour % 12).nonzero? || 12, 2, f)
      when 'j'; emit_n(yday, 3, f)
      when 'k'; emit_a(hour, 2, f)
      when 'L'
	emit_n((sec_fraction / MILLISECONDS_IN_DAY).floor, 3, f)
      when 'l'; emit_a((hour % 12).nonzero? || 12, 2, f)
      when 'M', 'OM'; emit_n(min, 2, f)
      when 'm', 'Om'; emit_n(mon, 2, f)
      when 'N'
	emit_n((sec_fraction / NANOSECONDS_IN_DAY).floor, 9, f)
      when 'n'; "\n"
      when 'P'; emit_ad(strftime('%p').downcase, 0, f)
      when 'p'; emit_au(if hour < 12 then 'AM' else 'PM' end, 0, f)
      when 'Q'
	s = ((ajd - UNIX_EPOCH_IN_AJD) / MILLISECONDS_IN_DAY).round
	emit_sn(s, 1, f)
      when 'R'; emit_a(strftime('%H:%M'), 0, f)
      when 'r'; emit_a(strftime('%I:%M:%S %p'), 0, f)
      when 'S', 'OS'; emit_n(sec, 2, f)
      when 's'
	s = ((ajd - UNIX_EPOCH_IN_AJD) / SECONDS_IN_DAY).round
	emit_sn(s, 1, f)
      when 'T'
	if m == '%T'
	  format('%02d:%02d:%02d', hour, min, sec) # 4p
	else
	  emit_a(strftime('%H:%M:%S'), 0, f)
	end
      when 't'; "\t"
      when 'U', 'W', 'OU', 'OW'
	emit_n(if c[-1,1] == 'U' then wnum0 else wnum1 end, 2, f)
      when 'u', 'Ou'; emit_n(cwday, 1, f)
      when 'V', 'OV'; emit_n(cweek, 2, f)
      when 'v'; emit_a(strftime('%e-%b-%Y'), 0, f)
      when 'w', 'Ow'; emit_n(wday, 1, f)
      when 'X', 'EX'; emit_a(strftime('%H:%M:%S'), 0, f)
      when 'x', 'Ex'; emit_a(strftime('%m/%d/%y'), 0, f)
      when 'Y', 'EY'; emit_sn(year, 4, f)
      when 'y', 'Ey', 'Oy'; emit_n(year % 100, 2, f)
      when 'Z'; emit_au(strftime('%:z'), 0, f)
      when /\A(:{0,3})z/
	t = $1.size
	sign = if offset < 0 then -1 else +1 end
	fr = offset.abs
	ss = fr.div(SECONDS_IN_DAY) # 4p
	hh, ss = ss.divmod(3600)
	mm, ss = ss.divmod(60)
	if t == 3
	  if    ss.nonzero? then t =  2
	  elsif mm.nonzero? then t =  1
	  else                   t = -1
	  end
	end
	case t
	when -1
	  tail = []
	  sep = ''
	when 0
	  f[:w] -= 2 if f[:w]
	  tail = ['%02d' % mm]
	  sep = ''
	when 1
	  f[:w] -= 3 if f[:w]
	  tail = ['%02d' % mm]
	  sep = ':'
	when 2
	  f[:w] -= 6 if f[:w]
	  tail = ['%02d' % mm, '%02d' % ss]
	  sep = ':'
	end
	([emit_z(sign * hh, 2, f)] + tail).join(sep)
      when '%'; emit_a('%', 0, f)
      when '+'; emit_a(strftime('%a %b %e %H:%M:%S %Z %Y'), 0, f)
      when '1'
	if $VERBOSE
	  warn("warning: strftime: %1 is deprecated; forget this")
	end
	emit_n(jd, 1, f)
      when '2'
	if $VERBOSE
	  warn("warning: strftime: %2 is deprecated; use '%Y-%j'")
	end
	emit_a(strftime('%Y-%j'), 0, f)
      when '3'
	if $VERBOSE
	  warn("warning: strftime: %3 is deprecated; use '%F'")
	end
	emit_a(strftime('%F'), 0, f)
      else
	a
      end
    end
  end

# alias_method :format, :strftime

  def asctime() strftime('%c') end

  alias_method :ctime, :asctime

=begin
  def iso8601() strftime('%F') end

  def rfc3339() iso8601 end

  def rfc2822() strftime('%a, %-d %b %Y %T %z') end

  alias_method :rfc822, :rfc2822

  def jisx0301
    if jd < 2405160
      iso8601
    else
      case jd
      when 2405160...2419614
	g = 'M%02d' % (year - 1867)
      when 2419614...2424875
	g = 'T%02d' % (year - 1911)
      when 2424875...2447535
	g = 'S%02d' % (year - 1925)
      else
	g = 'H%02d' % (year - 1988)
      end
      g + strftime('.%m.%d')
    end
  end

  def beat(n=0)
    i, f = (new_offset(HOURS_IN_DAY).day_fraction * 1000).divmod(1)
    ('@%03d' % i) +
      if n < 1
	''
      else
	'.%0*d' % [n, (f / Rational(1, 10**n)).round]
      end
  end
=end

  def self.num_pattern? (s) # :nodoc:
    /\A%[EO]?[CDdeFGgHIjkLlMmNQRrSsTUuVvWwXxYy\d]/ =~ s || /\A\d/ =~ s
  end

  private_class_method :num_pattern?

  def self._strptime_i(str, fmt, e) # :nodoc:
    fmt.scan(/%([EO]?(?::{1,3}z|.))|(.)/m) do |s, c|
      a = $&
      if s
	case s
	when 'A', 'a'
	  return unless str.sub!(/\A(#{Format::DAYS.keys.join('|')})/io, '') ||
			str.sub!(/\A(#{Format::ABBR_DAYS.keys.join('|')})/io, '')
	  val = Format::DAYS[$1.downcase] || Format::ABBR_DAYS[$1.downcase]
	  return unless val
	  e.wday = val
	when 'B', 'b', 'h'
	  return unless str.sub!(/\A(#{Format::MONTHS.keys.join('|')})/io, '') ||
			str.sub!(/\A(#{Format::ABBR_MONTHS.keys.join('|')})/io, '')
	  val = Format::MONTHS[$1.downcase] || Format::ABBR_MONTHS[$1.downcase]
	  return unless val
	  e.mon = val
	when 'C', 'EC'
	  return unless str.sub!(if num_pattern?($')
				 then /\A([-+]?\d{1,2})/
				 else /\A([-+]?\d{1,})/
				 end, '')
	  val = $1.to_i
	  e._cent = val
	when 'c', 'Ec'
	  return unless _strptime_i(str, '%a %b %e %H:%M:%S %Y', e)
	when 'D'
	  return unless _strptime_i(str, '%m/%d/%y', e)
	when 'd', 'e', 'Od', 'Oe'
	  return unless str.sub!(/\A( \d|\d{1,2})/, '')
	  val = $1.to_i
	  return unless (1..31) === val
	  e.mday = val
	when 'F'
	  return unless _strptime_i(str, '%Y-%m-%d', e)
	when 'G'
	  return unless str.sub!(if num_pattern?($')
				 then /\A([-+]?\d{1,4})/
				 else /\A([-+]?\d{1,})/
				 end, '')
	  val = $1.to_i
	  e.cwyear = val
	when 'g'
	  return unless str.sub!(/\A(\d{1,2})/, '')
	  val = $1.to_i
	  return unless (0..99) === val
	  e.cwyear = val
	  e._cent ||= if val >= 69 then 19 else 20 end
	when 'H', 'k', 'OH'
	  return unless str.sub!(/\A( \d|\d{1,2})/, '')
	  val = $1.to_i
	  return unless (0..24) === val
	  e.hour = val
	when 'I', 'l', 'OI'
	  return unless str.sub!(/\A( \d|\d{1,2})/, '')
	  val = $1.to_i
	  return unless (1..12) === val
	  e.hour = val
	when 'j'
	  return unless str.sub!(/\A(\d{1,3})/, '')
	  val = $1.to_i
	  return unless (1..366) === val
	  e.yday = val
	when 'L'
	  return unless str.sub!(if num_pattern?($')
				 then /\A([-+]?\d{1,3})/
				 else /\A([-+]?\d{1,})/
				 end, '')
#	  val = Rational($1.to_i, 10**3)
	  val = Rational($1.to_i, 10**$1.size)
	  e.sec_fraction = val
	when 'M', 'OM'
	  return unless str.sub!(/\A(\d{1,2})/, '')
	  val = $1.to_i
	  return unless (0..59) === val
	  e.min = val
	when 'm', 'Om'
	  return unless str.sub!(/\A(\d{1,2})/, '')
	  val = $1.to_i
	  return unless (1..12) === val
	  e.mon = val
	when 'N'
	  return unless str.sub!(if num_pattern?($')
				 then /\A([-+]?\d{1,9})/
				 else /\A([-+]?\d{1,})/
				 end, '')
#	  val = Rational($1.to_i, 10**9)
	  val = Rational($1.to_i, 10**$1.size)
	  e.sec_fraction = val
	when 'n', 't'
	  return unless _strptime_i(str, "\s", e)
	when 'P', 'p'
	  return unless str.sub!(/\A([ap])(?:m\b|\.m\.)/i, '')
	  e._merid = if $1.downcase == 'a' then 0 else 12 end
	when 'Q'
	  return unless str.sub!(/\A(-?\d{1,})/, '')
	  val = Rational($1.to_i, 10**3)
	  e.seconds = val
	when 'R'
	  return unless _strptime_i(str, '%H:%M', e)
	when 'r'
	  return unless _strptime_i(str, '%I:%M:%S %p', e)
	when 'S', 'OS'
	  return unless str.sub!(/\A(\d{1,2})/, '')
	  val = $1.to_i
	  return unless (0..60) === val
	  e.sec = val
	when 's'
	  return unless str.sub!(/\A(-?\d{1,})/, '')
	  val = $1.to_i
	  e.seconds = val
	when 'T'
	  return unless _strptime_i(str, '%H:%M:%S', e)
	when 'U', 'W', 'OU', 'OW'
	  return unless str.sub!(/\A(\d{1,2})/, '')
	  val = $1.to_i
	  return unless (0..53) === val
	  e.__send__(if s[-1,1] == 'U' then :wnum0= else :wnum1= end, val)
	when 'u', 'Ou'
	  return unless str.sub!(/\A(\d{1})/, '')
	  val = $1.to_i
	  return unless (1..7) === val
	  e.cwday = val
	when 'V', 'OV'
	  return unless str.sub!(/\A(\d{1,2})/, '')
	  val = $1.to_i
	  return unless (1..53) === val
	  e.cweek = val
	when 'v'
	  return unless _strptime_i(str, '%e-%b-%Y', e)
	when 'w'
	  return unless str.sub!(/\A(\d{1})/, '')
	  val = $1.to_i
	  return unless (0..6) === val
	  e.wday = val
	when 'X', 'EX'
	  return unless _strptime_i(str, '%H:%M:%S', e)
	when 'x', 'Ex'
	  return unless _strptime_i(str, '%m/%d/%y', e)
	when 'Y', 'EY'
	  return unless str.sub!(if num_pattern?($')
				 then /\A([-+]?\d{1,4})/
				 else /\A([-+]?\d{1,})/
				 end, '')
	  val = $1.to_i
	  e.year = val
	when 'y', 'Ey', 'Oy'
	  return unless str.sub!(/\A(\d{1,2})/, '')
	  val = $1.to_i
	  return unless (0..99) === val
	  e.year = val
	  e._cent ||= if val >= 69 then 19 else 20 end
	when 'Z', /\A:{0,3}z/
	  return unless str.sub!(/\A((?:gmt|utc?)?[-+]\d+(?:[,.:]\d+(?::\d+)?)?
				    |[[:alpha:].\s]+(?:standard|daylight)\s+time\b
				    |[[:alpha:]]+(?:\s+dst)?\b
				    )/ix, '')
	  val = $1
	  e.zone = val
	  offset = zone_to_diff(val)
	  e.offset = offset
	when '%'
	  return unless str.sub!(/\A%/, '')
	when '+'
	  return unless _strptime_i(str, '%a %b %e %H:%M:%S %Z %Y', e)
	when '1'
	  if $VERBOSE
	    warn("warning: strptime: %1 is deprecated; forget this")
	  end
	  return unless str.sub!(/\A(\d+)/, '')
	  val = $1.to_i
	  e.jd = val
	when '2'
	  if $VERBOSE
	    warn("warning: strptime: %2 is deprecated; use '%Y-%j'")
	  end
	  return unless _strptime_i(str, '%Y-%j', e)
	when '3'
	  if $VERBOSE
	    warn("warning: strptime: %3 is deprecated; use '%F'")
	  end
	  return unless _strptime_i(str, '%F', e)
	else
	  return unless str.sub!(Regexp.new('\\A' + Regexp.quote(a)), '')
	end
      else
	case c
	when /\A[\s\v]/
	  str.sub!(/\A[\s\v]+/, '')
	else
	  return unless str.sub!(Regexp.new('\\A' + Regexp.quote(a)), '')
	end
      end
    end
  end

  private_class_method :_strptime_i

  def self._strptime(str, fmt='%F')
    str = str.dup
    e = Format::Bag.new
    return unless _strptime_i(str, fmt, e)

    if e._cent
      if e.cwyear
	e.cwyear += e._cent * 100
      end
      if e.year
	e.  year += e._cent * 100
      end
    end

    if e._merid
      if e.hour
	e.hour %= 12
	e.hour += e._merid
      end
    end

    unless str.empty?
      e.leftover = str
    end

    e.to_hash
  end

  def self.s3e(e, y, m, d, bc=false)
    unless String === m
      m = m.to_s
    end

    if y && m && !d
      y, m, d = d, y, m
    end

    if y == nil
      if d && d.size > 2
	y = d
	d = nil
      end
      if d && d[0,1] == "'"
	y = d
	d = nil
      end
    end

    if y
      y.scan(/(\d+)(.+)?/)
      if $2
	y, d = d, $1
      end
    end

    if m
      if m[0,1] == "'" || m.size > 2
	y, m, d = m, d, y # us -> be
      end
    end

    if d
      if d[0,1] == "'" || d.size > 2
	y, d = d, y
      end
    end

    if y
      y =~ /([-+])?(\d+)/
      if $1 || $2.size > 2
	c = false
      end
      iy = $&.to_i
      if bc
	iy = -iy + 1
      end
      e.year = iy
    end

    if m
      m =~ /\d+/
      e.mon = $&.to_i
    end

    if d
      d =~ /\d+/
      e.mday = $&.to_i
    end

    if c != nil
      e._comp = c
    end

  end

  private_class_method :s3e

  def self._parse_day(str, e) # :nodoc:
    if str.sub!(/\b(#{Format::ABBR_DAYS.keys.join('|')})[^-\d\s]*/ino, ' ')
      e.wday = Format::ABBR_DAYS[$1.downcase]
      true
=begin
    elsif str.sub!(/\b(?!\dth)(su|mo|tu|we|th|fr|sa)\b/in, ' ')
      e.wday = %w(su mo tu we th fr sa).index($1.downcase)
      true
=end
    end
  end

  def self._parse_time(str, e) # :nodoc:
    if str.sub!(
		/(
		   (?:
		     \d+\s*:\s*\d+
		     (?:
		       \s*:\s*\d+(?:[,.]\d*)?
		     )?
		   |
		     \d+\s*h(?:\s*\d+m?(?:\s*\d+s?)?)?
		   )
		   (?:
		     \s*
		     [ap](?:m\b|\.m\.)
		   )?
		 |
		   \d+\s*[ap](?:m\b|\.m\.)
		 )
		 (?:
		   \s*
		   (
		     (?:gmt|utc?)?[-+]\d+(?:[,.:]\d+(?::\d+)?)?
		   |
		     [[:alpha:].\s]+(?:standard|daylight)\stime\b
		   |
		     [[:alpha:]]+(?:\sdst)?\b
		   )
		 )?
		/inx,
		' ')

      t = $1
      e.zone = $2 if $2

      t =~ /\A(\d+)h?
	      (?:\s*:?\s*(\d+)m?
		(?:
		  \s*:?\s*(\d+)(?:[,.](\d+))?s?
		)?
	      )?
	    (?:\s*([ap])(?:m\b|\.m\.))?/inx

      e.hour = $1.to_i
      e.min = $2.to_i if $2
      e.sec = $3.to_i if $3
      e.sec_fraction = Rational($4.to_i, 10**$4.size) if $4

      if $5
	e.hour %= 12
	if $5.downcase == 'p'
	  e.hour += 12
	end
      end
      true
    end
  end

=begin
  def self._parse_beat(str, e) # :nodoc:
    if str.sub!(/@\s*(\d+)(?:[,.](\d*))?/, ' ')
      beat = Rational($1.to_i)
      beat += Rational($2.to_i, 10**$2.size) if $2
      secs = Rational(beat, 1000)
      h, min, s, fr = self.day_fraction_to_time(secs)
      e.hour = h
      e.min = min
      e.sec = s
      e.sec_fraction = fr * 86400
      e.zone = '+01:00'
      true
    end
  end
=end

  def self._parse_eu(str, e) # :nodoc:
    if str.sub!(
		/'?(\d+)[^-\d\s]*
		 \s*
		 (#{Format::ABBR_MONTHS.keys.join('|')})[^-\d\s']*
		 (?:
		   \s*
		   (c(?:e|\.e\.)|b(?:ce|\.c\.e\.)|a(?:d|\.d\.)|b(?:c|\.c\.))?
		   \s*
		   ('?-?\d+(?:(?:st|nd|rd|th)\b)?)
		 )?
		/inox,
		' ') # '
      s3e(e, $4, Format::ABBR_MONTHS[$2.downcase], $1,
	  $3 && $3[0,1].downcase == 'b')
      true
    end
  end

  def self._parse_us(str, e) # :nodoc:
    if str.sub!(
		/\b(#{Format::ABBR_MONTHS.keys.join('|')})[^-\d\s']*
		 \s*
		 ('?\d+)[^-\d\s']*
		 (?:
		   \s*
		   (c(?:e|\.e\.)|b(?:ce|\.c\.e\.)|a(?:d|\.d\.)|b(?:c|\.c\.))?
		   \s*
		   ('?-?\d+)
		 )?
		/inox,
		' ') # '
      s3e(e, $4, Format::ABBR_MONTHS[$1.downcase], $2,
	  $3 && $3[0,1].downcase == 'b')
      true
    end
  end

  def self._parse_iso(str, e) # :nodoc:
    if str.sub!(/('?[-+]?\d+)-(\d+)-('?-?\d+)/n, ' ')
      s3e(e, $1, $2, $3)
      true
    end
  end

  def self._parse_iso2(str, e) # :nodoc:
    if str.sub!(/\b(\d{2}|\d{4})?-?w(\d{2})(?:-?(\d))?\b/in, ' ')
      e.cwyear = $1.to_i if $1
      e.cweek = $2.to_i
      e.cwday = $3.to_i if $3
      true
    elsif str.sub!(/-w-(\d)\b/in, ' ')
      e.cwday = $1.to_i
      true
    elsif str.sub!(/--(\d{2})?-(\d{2})\b/n, ' ')
      e.mon = $1.to_i if $1
      e.mday = $2.to_i
      true
    elsif str.sub!(/--(\d{2})(\d{2})?\b/n, ' ')
      e.mon = $1.to_i
      e.mday = $2.to_i if $2
      true
    elsif /[,.](\d{2}|\d{4})-\d{3}\b/n !~ str &&
	str.sub!(/\b(\d{2}|\d{4})-(\d{3})\b/n, ' ')
      e.year = $1.to_i
      e.yday = $2.to_i
      true
    elsif /\d-\d{3}\b/n !~ str &&
	str.sub!(/\b-(\d{3})\b/n, ' ')
      e.yday = $1.to_i
      true
    end
  end

  def self._parse_jis(str, e) # :nodoc:
    if str.sub!(/\b([mtsh])(\d+)\.(\d+)\.(\d+)/in, ' ')
      era = { 'm'=>1867,
	      't'=>1911,
	      's'=>1925,
	      'h'=>1988
	  }[$1.downcase]
      e.year = $2.to_i + era
      e.mon = $3.to_i
      e.mday = $4.to_i
      true
    end
  end

  def self._parse_vms(str, e) # :nodoc:
    if str.sub!(/('?-?\d+)-(#{Format::ABBR_MONTHS.keys.join('|')})[^-]*
		-('?-?\d+)/inox, ' ')
      s3e(e, $3, Format::ABBR_MONTHS[$2.downcase], $1)
      true
    elsif str.sub!(/\b(#{Format::ABBR_MONTHS.keys.join('|')})[^-]*
		-('?-?\d+)(?:-('?-?\d+))?/inox, ' ')
      s3e(e, $3, Format::ABBR_MONTHS[$1.downcase], $2)
      true
    end
  end

  def self._parse_sla(str, e) # :nodoc:
    if str.sub!(%r|('?-?\d+)/\s*('?\d+)(?:\D\s*('?-?\d+))?|n, ' ') # '
      s3e(e, $3, $1, $2)
      true
    end
  end

  def self._parse_dot(str, e) # :nodoc:
    if str.sub!(%r|('?-?\d+)\.\s*('?\d+)\.\s*('?-?\d+)|n, ' ') # '
      s3e(e, $1, $2, $3)
      true
    end
  end

  def self._parse_year(str, e) # :nodoc:
    if str.sub!(/'(\d+)\b/n, ' ')
      e.year = $1.to_i
      true
    end
  end

  def self._parse_mon(str, e) # :nodoc:
    if str.sub!(/\b(#{Format::ABBR_MONTHS.keys.join('|')})\S*/ino, ' ')
      e.mon = Format::ABBR_MONTHS[$1.downcase]
      true
    end
  end

  def self._parse_mday(str, e) # :nodoc:
    if str.sub!(/(\d+)(st|nd|rd|th)\b/in, ' ')
      e.mday = $1.to_i
      true
    end
  end

  def self._parse_ddd(str, e) # :nodoc:
    if str.sub!(
		/([-+]?)(\d{2,14})
		  (?:
		    \s*
		    t?
		    \s*
		    (\d{2,6})?(?:[,.](\d*))?
		  )?
		  (?:
		    \s*
		    (
		      z\b
		    |
		      [-+]\d{1,4}\b
		    |
		      \[[-+]?\d[^\]]*\]
		    )
		  )?
		/inx,
		' ')
      case $2.size
      when 2
	if $3.nil? && $4
	  e.sec  = $2[-2, 2].to_i
	else
	  e.mday = $2[ 0, 2].to_i
	end
      when 4
	if $3.nil? && $4
	  e.sec  = $2[-2, 2].to_i
	  e.min  = $2[-4, 2].to_i
	else
	  e.mon  = $2[ 0, 2].to_i
	  e.mday = $2[ 2, 2].to_i
	end
      when 6
	if $3.nil? && $4
	  e.sec  = $2[-2, 2].to_i
	  e.min  = $2[-4, 2].to_i
	  e.hour = $2[-6, 2].to_i
	else
	  e.year = ($1 + $2[ 0, 2]).to_i
	  e.mon  = $2[ 2, 2].to_i
	  e.mday = $2[ 4, 2].to_i
	end
      when 8, 10, 12, 14
	if $3.nil? && $4
	  e.sec  = $2[-2, 2].to_i
	  e.min  = $2[-4, 2].to_i
	  e.hour = $2[-6, 2].to_i
	  e.mday = $2[-8, 2].to_i
	  if $2.size >= 10
	    e.mon  = $2[-10, 2].to_i
	  end
	  if $2.size == 12
	    e.year = ($1 + $2[-12, 2]).to_i
	  end
	  if $2.size == 14
	    e.year = ($1 + $2[-14, 4]).to_i
	    e._comp = false
	  end
	else
	  e.year = ($1 + $2[ 0, 4]).to_i
	  e.mon  = $2[ 4, 2].to_i
	  e.mday = $2[ 6, 2].to_i
	  e.hour = $2[ 8, 2].to_i if $2.size >= 10
	  e.min  = $2[10, 2].to_i if $2.size >= 12
	  e.sec  = $2[12, 2].to_i if $2.size >= 14
	  e._comp = false
	end
      when 3
	if $3.nil? && $4
	  e.sec  = $2[-2, 2].to_i
	  e.min  = $2[-3, 1].to_i
	else
	  e.yday = $2[ 0, 3].to_i
	end
      when 5
	if $3.nil? && $4
	  e.sec  = $2[-2, 2].to_i
	  e.min  = $2[-4, 2].to_i
	  e.hour = $2[-5, 1].to_i
	else
	  e.year = ($1 + $2[ 0, 2]).to_i
	  e.yday = $2[ 2, 3].to_i
	end
      when 7
	if $3.nil? && $4
	  e.sec  = $2[-2, 2].to_i
	  e.min  = $2[-4, 2].to_i
	  e.hour = $2[-6, 2].to_i
	  e.mday = $2[-7, 1].to_i
	else
	  e.year = ($1 + $2[ 0, 4]).to_i
	  e.yday = $2[ 4, 3].to_i
	end
      end
      if $3
	if $4
	  case $3.size
	  when 2, 4, 6
	    e.sec  = $3[-2, 2].to_i
	    e.min  = $3[-4, 2].to_i if $3.size >= 4
	    e.hour = $3[-6, 2].to_i if $3.size >= 6
	  end
	else
	  case $3.size
	  when 2, 4, 6
	    e.hour = $3[ 0, 2].to_i
	    e.min  = $3[ 2, 2].to_i if $3.size >= 4
	    e.sec  = $3[ 4, 2].to_i if $3.size >= 6
	  end
	end
      end
      if $4
	e.sec_fraction = Rational($4.to_i, 10**$4.size)
      end
      if $5
	e.zone = $5
	if e.zone[0,1] == '['
	  o, n, = e.zone[1..-2].split(':')
	  e.zone = n || o
	  if /\A\d/ =~ o
	    o = format('+%s', o)
	  end
	  e.offset = zone_to_diff(o)
	end
      end
      true
    end
  end

  private_class_method :_parse_day, :_parse_time, # :_parse_beat,
	:_parse_eu, :_parse_us, :_parse_iso, :_parse_iso2,
	:_parse_jis, :_parse_vms, :_parse_sla, :_parse_dot,
	:_parse_year, :_parse_mon, :_parse_mday, :_parse_ddd

  def self._parse(str, comp=false)
    str = str.dup

    e = Format::Bag.new

    e._comp = comp

    str.gsub!(/[^-+',.\/:@[:alnum:]\[\]\x80-\xff]+/n, ' ')

    _parse_time(str, e) # || _parse_beat(str, e)
    _parse_day(str, e)

    _parse_eu(str, e)     ||
    _parse_us(str, e)     ||
    _parse_iso(str, e)    ||
    _parse_jis(str, e)    ||
    _parse_vms(str, e)    ||
    _parse_sla(str, e)    ||
    _parse_dot(str, e)    ||
    _parse_iso2(str, e)   ||
    _parse_year(str, e)   ||
    _parse_mon(str, e)    ||
    _parse_mday(str, e)   ||
    _parse_ddd(str, e)

    if str.sub!(/\b(bc\b|bce\b|b\.c\.|b\.c\.e\.)/in, ' ')
      if e.year
	e.year = -e.year + 1
      end
    end

    if str.sub!(/\A\s*(\d{1,2})\s*\z/n, ' ')
      if e.hour && !e.mday
	v = $1.to_i
	if (1..31) === v
	  e.mday = v
	end
      end
      if e.mday && !e.hour
	v = $1.to_i
	if (0..24) === v
	  e.hour = v
	end
      end
    end

    if e._comp
      if e.cwyear
	if e.cwyear >= 0 && e.cwyear <= 99
	  e.cwyear += if e.cwyear >= 69
		      then 1900 else 2000 end
	end
      end
      if e.year
	if e.year >= 0 && e.year <= 99
	  e.year += if e.year >= 69
		    then 1900 else 2000 end
	end
      end
    end

    e.offset ||= zone_to_diff(e.zone) if e.zone

    e.to_hash
  end

  def self.zone_to_diff(zone) # :nodoc:
    zone = zone.downcase
    if zone.sub!(/\s+(standard|daylight)\s+time\z/, '')
      dst = $1 == 'daylight'
    else
      dst = zone.sub!(/\s+dst\z/, '')
    end
    if Format::ZONES.include?(zone)
      offset = Format::ZONES[zone]
      offset += 3600 if dst
    elsif zone.sub!(/\A(?:gmt|utc?)?([-+])/, '')
      sign = $1
      if zone.include?(':')
	hour, min, sec, = zone.split(':')
      elsif zone.include?(',') || zone.include?('.')
	hour, fr, = zone.split(/[,.]/)
	min = Rational(fr.to_i, 10**fr.size) * 60
      else
	case zone.size
	when 3
	  hour = zone[0,1]
	  min = zone[1,2]
	else
	  hour = zone[0,2]
	  min = zone[2,2]
	  sec = zone[4,2]
	end
      end
      offset = hour.to_i * 3600 + min.to_i * 60 + sec.to_i
      offset *= -1 if sign == '-'
    end
    offset
  end

end

class DateTime < Date

  def strftime(fmt='%FT%T%:z')
    super(fmt)
  end

  def self._strptime(str, fmt='%FT%T%z')
    super(str, fmt)
  end

=begin
  def iso8601_timediv(n) # :nodoc:
    strftime('T%T' +
	     if n < 1
	       ''
	     else
	       '.%0*d' % [n, (sec_fraction / SECONDS_IN_DAY / (10**n)).round]
	     end +
	     '%:z')
  end

  private :iso8601_timediv

  def iso8601(n=0)
    super() + iso8601_timediv(n)
  end

  def rfc3339(n=0) iso8601(n) end

  def jisx0301(n=0)
    super() + iso8601_timediv(n)
  end
=end

end
PK     Z\׎1      wsdl/part.rbnu [        # WSDL4R - WSDL part definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL


class Part < Info
  attr_reader :name	# required
  attr_reader :element	# optional
  attr_reader :type	# optional

  def initialize
    super
    @name = nil
    @element = nil
    @type = nil
  end

  def parse_element(element)
    case element
    when DocumentationName
      o = Documentation.new
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when NameAttrName
      @name = value.source
    when ElementAttrName
      @element = value
    when TypeAttrName
      @type = value
    else
      nil
    end
  end
end


end
PK     Z\f      wsdl/wsdl.rbnu [        # WSDL4R - Base definitions.
# Copyright (C) 2000, 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/qname'


module WSDL


Version = '0.0.2'

Namespace = 'http://schemas.xmlsoap.org/wsdl/'
SOAPBindingNamespace ='http://schemas.xmlsoap.org/wsdl/soap/'

class Error < StandardError; end


end
PK     Z\>w@1	  1	    wsdl/data.rbnu [        # WSDL4R - WSDL data definitions.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/qname'
require 'wsdl/documentation'
require 'wsdl/definitions'
require 'wsdl/types'
require 'wsdl/message'
require 'wsdl/part'
require 'wsdl/portType'
require 'wsdl/operation'
require 'wsdl/param'
require 'wsdl/binding'
require 'wsdl/operationBinding'
require 'wsdl/service'
require 'wsdl/port'
require 'wsdl/import'


module WSDL


ArrayTypeAttrName = XSD::QName.new(Namespace, 'arrayType')
BindingName = XSD::QName.new(Namespace, 'binding')
DefinitionsName = XSD::QName.new(Namespace, 'definitions')
DocumentationName = XSD::QName.new(Namespace, 'documentation')
FaultName = XSD::QName.new(Namespace, 'fault')
ImportName = XSD::QName.new(Namespace, 'import')
InputName = XSD::QName.new(Namespace, 'input')
MessageName = XSD::QName.new(Namespace, 'message')
OperationName = XSD::QName.new(Namespace, 'operation')
OutputName = XSD::QName.new(Namespace, 'output')
PartName = XSD::QName.new(Namespace, 'part')
PortName = XSD::QName.new(Namespace, 'port')
PortTypeName = XSD::QName.new(Namespace, 'portType')
ServiceName = XSD::QName.new(Namespace, 'service')
TypesName = XSD::QName.new(Namespace, 'types')

SchemaName = XSD::QName.new(XSD::Namespace, 'schema')

SOAPAddressName = XSD::QName.new(SOAPBindingNamespace, 'address')
SOAPBindingName = XSD::QName.new(SOAPBindingNamespace, 'binding')
SOAPHeaderName = XSD::QName.new(SOAPBindingNamespace, 'header')
SOAPBodyName = XSD::QName.new(SOAPBindingNamespace, 'body')
SOAPFaultName = XSD::QName.new(SOAPBindingNamespace, 'fault')
SOAPOperationName = XSD::QName.new(SOAPBindingNamespace, 'operation')

BindingAttrName = XSD::QName.new(nil, 'binding')
ElementAttrName = XSD::QName.new(nil, 'element')
LocationAttrName = XSD::QName.new(nil, 'location')
MessageAttrName = XSD::QName.new(nil, 'message')
NameAttrName = XSD::QName.new(nil, 'name')
NamespaceAttrName = XSD::QName.new(nil, 'namespace')
ParameterOrderAttrName = XSD::QName.new(nil, 'parameterOrder')
TargetNamespaceAttrName = XSD::QName.new(nil, 'targetNamespace')
TypeAttrName = XSD::QName.new(nil, 'type')


end
PK     Z\}@9  9    wsdl/importer.rbnu [        # WSDL4R - WSDL importer library.
# Copyright (C) 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/xmlSchema/importer'
require 'wsdl/parser'


module WSDL


class Importer < WSDL::XMLSchema::Importer
  def self.import(location, originalroot = nil)
    new.import(location, originalroot)
  end

private

  def parse(content, location, originalroot)
    opt = {
      :location => location,
      :originalroot => originalroot
    }
    begin
      WSDL::Parser.new(opt).parse(content)
    rescue WSDL::Parser::ParseError
      super(content, location, originalroot)
    end
  end

end


end
PK     Z\4      wsdl/operationBinding.rbnu [        # WSDL4R - WSDL bound operation definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL


class OperationBinding < Info
  attr_reader :name		# required
  attr_reader :input
  attr_reader :output
  attr_reader :fault
  attr_reader :soapoperation

  def initialize
    super
    @name = nil
    @input = nil
    @output = nil
    @fault = []
    @soapoperation = nil
  end

  def targetnamespace
    parent.targetnamespace
  end

  def porttype
    root.porttype(parent.type)
  end

  def find_operation
    porttype.operations[@name] or raise RuntimeError.new("#{@name} not found")
  end

  def soapoperation_name
    if @soapoperation
      @soapoperation.input_info.op_name
    else
      find_operation.name
    end
  end

  def soapoperation_style
    style = nil
    if @soapoperation
      style = @soapoperation.operation_style
    elsif parent.soapbinding
      style = parent.soapbinding.style
    else
      raise TypeError.new("operation style definition not found")
    end
    style || :document
  end

  def soapaction
    if @soapoperation
      @soapoperation.soapaction
    else
      nil
    end
  end

  def parse_element(element)
    case element
    when InputName
      o = Param.new
      @input = o
      o
    when OutputName
      o = Param.new
      @output = o
      o
    when FaultName
      o = Param.new
      @fault << o
      o
    when SOAPOperationName
      o = WSDL::SOAP::Operation.new
      @soapoperation = o
      o
    when DocumentationName
      o = Documentation.new
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when NameAttrName
      @name = XSD::QName.new(targetnamespace, value.source)
    else
      nil
    end
  end
end


end
PK     Z\	[      wsdl/types.rbnu [        # WSDL4R - WSDL types definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL


class Types < Info
  attr_reader :schemas

  def initialize
    super
    @schemas = []
  end

  def parse_element(element)
    case element
    when SchemaName
      o = XMLSchema::Schema.new
      @schemas << o
      o
    when DocumentationName
      o = Documentation.new
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    nil
  end
end


end
PK     Z\Iƽ&e  e     wsdl/xmlSchema/complexContent.rbnu [        # WSDL4R - XMLSchema complexContent definition for WSDL.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'xsd/namedelements'


module WSDL
module XMLSchema


class ComplexContent < Info
  attr_accessor :base
  attr_reader :derivetype
  attr_reader :content
  attr_reader :attributes

  def initialize
    super
    @base = nil
    @derivetype = nil
    @content = nil
    @attributes = XSD::NamedElements.new
    @basetype = nil
  end

  def targetnamespace
    parent.targetnamespace
  end

  def elementformdefault
    parent.elementformdefault
  end

  def basetype
    @basetype ||= root.collect_complextypes[@base]
  end

  def parse_element(element)
    case element
    when RestrictionName, ExtensionName
      @derivetype = element.name
      self
    when AllName
      if @derivetype.nil?
	raise Parser::ElementConstraintError.new("base attr not found.")
      end
      @content = All.new
      @content
    when SequenceName
      if @derivetype.nil?
	raise Parser::ElementConstraintError.new("base attr not found.")
      end
      @content = Sequence.new
      @content
    when ChoiceName
      if @derivetype.nil?
	raise Parser::ElementConstraintError.new("base attr not found.")
      end
      @content = Choice.new
      @content
    when AttributeName
      if @derivetype.nil?
	raise Parser::ElementConstraintError.new("base attr not found.")
      end
      o = Attribute.new
      @attributes << o
      o
    end
  end

  def parse_attr(attr, value)
    if @derivetype.nil?
      return nil
    end
    case attr
    when BaseAttrName
      @base = value
    else
      nil
    end
  end
end


end
end
PK     Z\fU      wsdl/xmlSchema/complexType.rbnu [        # WSDL4R - XMLSchema complexType definition for WSDL.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'wsdl/xmlSchema/content'
require 'wsdl/xmlSchema/element'
require 'xsd/namedelements'


module WSDL
module XMLSchema


class ComplexType < Info
  attr_accessor :name
  attr_accessor :complexcontent
  attr_accessor :simplecontent
  attr_reader :content
  attr_accessor :final
  attr_accessor :mixed
  attr_reader :attributes

  def initialize(name = nil)
    super()
    @name = name
    @complexcontent = nil
    @simplecontent = nil
    @content = nil
    @final = nil
    @mixed = false
    @attributes = XSD::NamedElements.new
  end

  def targetnamespace
    # inner elements can be qualified
    # parent.is_a?(WSDL::XMLSchema::Element) ? nil : parent.targetnamespace
    parent.targetnamespace
  end

  def elementformdefault
    parent.elementformdefault
  end
 
  AnyAsElement = Element.new(XSD::QName.new(nil, 'any'), XSD::AnyTypeName)
  def each_element
    if content
      content.elements.each do |element|
        if element.is_a?(Any)
          yield(AnyAsElement)
        else
          yield(element)
        end
      end
    end
  end

  def find_element(name)
    if content
      content.elements.each do |element|
        if element.is_a?(Any)
          return AnyAsElement if name == AnyAsElement.name
        else
          return element if name == element.name
        end
      end
    end
    nil
  end

  def find_element_by_name(name)
    if content
      content.elements.each do |element|
        if element.is_a?(Any)
          return AnyAsElement if name == AnyAsElement.name.name
        else
          return element if name == element.name.name
        end
      end
    end
    nil
  end

  def sequence_elements=(elements)
    @content = Sequence.new
    elements.each do |element|
      @content << element
    end
  end

  def all_elements=(elements)
    @content = All.new
    elements.each do |element|
      @content << element
    end
  end

  def parse_element(element)
    case element
    when AllName
      @content = All.new
    when SequenceName
      @content = Sequence.new
    when ChoiceName
      @content = Choice.new
    when ComplexContentName
      @complexcontent = ComplexContent.new
    when SimpleContentName
      @simplecontent = SimpleContent.new
    when AttributeName
      o = Attribute.new
      @attributes << o
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when FinalAttrName
      @final = value.source
    when MixedAttrName
      @mixed = (value.source == 'true')
    when NameAttrName
      @name = XSD::QName.new(targetnamespace, value.source)
    else
      nil
    end
  end
end


end
end
PK     Z\	
t      wsdl/xmlSchema/data.rbnu [        # WSDL4R - XMLSchema data definitions.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/datatypes'
require 'wsdl/xmlSchema/annotation'
require 'wsdl/xmlSchema/schema'
require 'wsdl/xmlSchema/import'
require 'wsdl/xmlSchema/include'
require 'wsdl/xmlSchema/simpleType'
require 'wsdl/xmlSchema/simpleRestriction'
require 'wsdl/xmlSchema/simpleExtension'
require 'wsdl/xmlSchema/complexType'
require 'wsdl/xmlSchema/complexContent'
require 'wsdl/xmlSchema/simpleContent'
require 'wsdl/xmlSchema/any'
require 'wsdl/xmlSchema/element'
require 'wsdl/xmlSchema/all'
require 'wsdl/xmlSchema/choice'
require 'wsdl/xmlSchema/sequence'
require 'wsdl/xmlSchema/attribute'
require 'wsdl/xmlSchema/unique'
require 'wsdl/xmlSchema/enumeration'
require 'wsdl/xmlSchema/length'
require 'wsdl/xmlSchema/pattern'

module WSDL
module XMLSchema


AllName = XSD::QName.new(XSD::Namespace, 'all')
AnnotationName = XSD::QName.new(XSD::Namespace, 'annotation')
AnyName = XSD::QName.new(XSD::Namespace, 'any')
AttributeName = XSD::QName.new(XSD::Namespace, 'attribute')
ChoiceName = XSD::QName.new(XSD::Namespace, 'choice')
ComplexContentName = XSD::QName.new(XSD::Namespace, 'complexContent')
ComplexTypeName = XSD::QName.new(XSD::Namespace, 'complexType')
ElementName = XSD::QName.new(XSD::Namespace, 'element')
EnumerationName = XSD::QName.new(XSD::Namespace, 'enumeration')
ExtensionName = XSD::QName.new(XSD::Namespace, 'extension')
ImportName = XSD::QName.new(XSD::Namespace, 'import')
IncludeName = XSD::QName.new(XSD::Namespace, 'include')
LengthName = XSD::QName.new(XSD::Namespace, 'length')
PatternName = XSD::QName.new(XSD::Namespace, 'pattern')
RestrictionName = XSD::QName.new(XSD::Namespace, 'restriction')
SequenceName = XSD::QName.new(XSD::Namespace, 'sequence')
SchemaName = XSD::QName.new(XSD::Namespace, 'schema')
SimpleContentName = XSD::QName.new(XSD::Namespace, 'simpleContent')
SimpleTypeName = XSD::QName.new(XSD::Namespace, 'simpleType')
UniqueName = XSD::QName.new(XSD::Namespace, 'unique')

AttributeFormDefaultAttrName = XSD::QName.new(nil, 'attributeFormDefault')
BaseAttrName = XSD::QName.new(nil, 'base')
DefaultAttrName = XSD::QName.new(nil, 'default')
ElementFormDefaultAttrName = XSD::QName.new(nil, 'elementFormDefault')
FinalAttrName = XSD::QName.new(nil, 'final')
FixedAttrName = XSD::QName.new(nil, 'fixed')
FormAttrName = XSD::QName.new(nil, 'form')
IdAttrName = XSD::QName.new(nil, 'id')
MaxOccursAttrName = XSD::QName.new(nil, 'maxOccurs')
MinOccursAttrName = XSD::QName.new(nil, 'minOccurs')
MixedAttrName = XSD::QName.new(nil, 'mixed')
NameAttrName = XSD::QName.new(nil, 'name')
NamespaceAttrName = XSD::QName.new(nil, 'namespace')
NillableAttrName = XSD::QName.new(nil, 'nillable')
ProcessContentsAttrName = XSD::QName.new(nil, 'processContents')
RefAttrName = XSD::QName.new(nil, 'ref')
SchemaLocationAttrName = XSD::QName.new(nil, 'schemaLocation')
TargetNamespaceAttrName = XSD::QName.new(nil, 'targetNamespace')
TypeAttrName = XSD::QName.new(nil, 'type')
UseAttrName = XSD::QName.new(nil, 'use')
ValueAttrName = XSD::QName.new(nil, 'value')


end
end
PK     Z\@      wsdl/xmlSchema/importer.rbnu [        # WSDL4R - XSD importer library.
# Copyright (C) 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/httpconfigloader'
require 'wsdl/xmlSchema/parser'


module WSDL
module XMLSchema


class Importer
  def self.import(location, originalroot = nil)
    new.import(location, originalroot)
  end

  def initialize
    @web_client = nil
  end

  def import(location, originalroot = nil)
    unless location.is_a?(URI)
      location = URI.parse(location)
    end
    content = parse(fetch(location), location, originalroot)
    content.location = location
    content
  end

private

  def parse(content, location, originalroot)
    opt = {
      :location => location,
      :originalroot => originalroot
    }
    WSDL::XMLSchema::Parser.new(opt).parse(content)
  end

  def fetch(location)
    warn("importing: #{location}") if $DEBUG
    content = nil
    if location.scheme == 'file' or
        (location.relative? and FileTest.exist?(location.path))
      content = File.open(location.path).read
    elsif location.scheme and location.scheme.size == 1 and
        FileTest.exist?(location.to_s)
      # ToDo: remove this ugly workaround for a path with drive letter
      # (D://foo/bar)
      content = File.open(location.to_s).read
    else
      client = web_client.new(nil, "WSDL4R")
      client.proxy = ::SOAP::Env::HTTP_PROXY
      client.no_proxy = ::SOAP::Env::NO_PROXY
      if opt = ::SOAP::Property.loadproperty(::SOAP::PropertyName)
        ::SOAP::HTTPConfigLoader.set_options(client,
          opt["client.protocol.http"])
      end
      content = client.get_content(location)
    end
    content
  end

  def web_client
    @web_client ||= begin
	require 'http-access2'
	if HTTPAccess2::VERSION < "2.0"
	  raise LoadError.new("http-access/2.0 or later is required.")
	end
	HTTPAccess2::Client
      rescue LoadError
	warn("Loading http-access2 failed.  Net/http is used.") if $DEBUG
	require 'soap/netHttpClient'
	::SOAP::NetHttpClient
      end
    @web_client
  end
end


end
end
PK     Z\֩D      wsdl/xmlSchema/pattern.rbnu [        # WSDL4R - XMLSchema pattern definition for WSDL.
# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module XMLSchema


class Pattern < Info
  def initialize
    super
  end

  def parse_element(element)
    nil
  end

  def parse_attr(attr, value)
    case attr
    when ValueAttrName
      parent.pattern = /\A#{value.source}\z/n
      value.source
    end
  end
end


end
end
PK     Z\    #  wsdl/xmlSchema/simpleRestriction.rbnu [        # WSDL4R - XMLSchema simpleContent restriction definition for WSDL.
# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'xsd/namedelements'


module WSDL
module XMLSchema


class SimpleRestriction < Info
  attr_reader :base
  attr_reader :enumeration
  attr_accessor :length
  attr_accessor :pattern

  def initialize
    super
    @base = nil
    @enumeration = []   # NamedElements?
    @length = nil
    @pattern = nil
  end
  
  def valid?(value)
    return false unless check_restriction(value)
    return false unless check_length(value)
    return false unless check_pattern(value)
    true
  end

  def parse_element(element)
    case element
    when EnumerationName
      Enumeration.new   # just a parsing handler
    when LengthName
      Length.new   # just a parsing handler
    when PatternName
      Pattern.new   # just a parsing handler
    end
  end

  def parse_attr(attr, value)
    case attr
    when BaseAttrName
      @base = value
    end
  end

private

  def check_restriction(value)
    @enumeration.empty? or @enumeration.include?(value)
  end

  def check_length(value)
    @length.nil? or value.size == @length
  end

  def check_pattern(value)
    @pattern.nil? or @pattern =~ value
  end
end


end
end
PK     Z\(R  R    wsdl/xmlSchema/length.rbnu [        # WSDL4R - XMLSchema length definition for WSDL.
# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module XMLSchema


class Length < Info
  def initialize
    super
  end

  def parse_element(element)
    nil
  end

  def parse_attr(attr, value)
    case attr
    when ValueAttrName
      value.source
    end
  end
end


end
end
PK     Z\]  ]    wsdl/xmlSchema/content.rbnu [        # WSDL4R - XMLSchema complexType definition for WSDL.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module XMLSchema


class Content < Info
  attr_accessor :final
  attr_accessor :mixed
  attr_accessor :type
  attr_reader :contents
  attr_reader :elements

  def initialize
    super()
    @final = nil
    @mixed = false
    @type = nil
    @contents = []
    @elements = []
  end

  def targetnamespace
    parent.targetnamespace
  end

  def <<(content)
    @contents << content
    update_elements
  end

  def each
    @contents.each do |content|
      yield content
    end
  end

  def parse_element(element)
    case element
    when AllName, SequenceName, ChoiceName
      o = Content.new
      o.type = element.name
      @contents << o
      o
    when AnyName
      o = Any.new
      @contents << o
      o
    when ElementName
      o = Element.new
      @contents << o
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when FinalAttrName
      @final = value.source
    when MixedAttrName
      @mixed = (value.source == 'true')
    else
      nil
    end
  end

  def parse_epilogue
    update_elements
  end

private

  def update_elements
    @elements = []
    @contents.each do |content|
      if content.is_a?(Element)
	@elements << [content.name, content]
      end
    end
  end
end


end
end
PK     Z\TS      wsdl/xmlSchema/schema.rbnu [        # WSDL4R - XMLSchema schema definition for WSDL.
# Copyright (C) 2002, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'xsd/namedelements'


module WSDL
module XMLSchema


class Schema < Info
  attr_reader :targetnamespace	# required
  attr_reader :complextypes
  attr_reader :simpletypes
  attr_reader :elements
  attr_reader :attributes
  attr_reader :imports
  attr_accessor :attributeformdefault
  attr_accessor :elementformdefault

  attr_reader :importedschema

  def initialize
    super
    @targetnamespace = nil
    @complextypes = XSD::NamedElements.new
    @simpletypes = XSD::NamedElements.new
    @elements = XSD::NamedElements.new
    @attributes = XSD::NamedElements.new
    @imports = []
    @attributeformdefault = "unqualified"
    @elementformdefault = "unqualified"
    @importedschema = {}
    @location = nil
    @root = self
  end

  def location
    @location || (root.nil? ? nil : root.location)
  end

  def location=(location)
    @location = location
  end

  def parse_element(element)
    case element
    when ImportName
      o = Import.new
      @imports << o
      o
    when IncludeName
      o = Include.new
      @imports << o
      o
    when ComplexTypeName
      o = ComplexType.new
      @complextypes << o
      o
    when SimpleTypeName
      o = SimpleType.new
      @simpletypes << o
      o
    when ElementName
      o = Element.new
      @elements << o
      o
    when AttributeName
      o = Attribute.new
      @attributes << o
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when TargetNamespaceAttrName
      @targetnamespace = value.source
    when AttributeFormDefaultAttrName
      @attributeformdefault = value.source
    when ElementFormDefaultAttrName
      @elementformdefault = value.source
    else
      nil
    end
  end

  def collect_attributes
    result = XSD::NamedElements.new
    result.concat(@attributes)
    @imports.each do |import|
      result.concat(import.content.collect_attributes) if import.content
    end
    result
  end

  def collect_elements
    result = XSD::NamedElements.new
    result.concat(@elements)
    @imports.each do |import|
      result.concat(import.content.collect_elements) if import.content
    end
    result
  end

  def collect_complextypes
    result = XSD::NamedElements.new
    result.concat(@complextypes)
    @imports.each do |import|
      result.concat(import.content.collect_complextypes) if import.content
    end
    result
  end

  def collect_simpletypes
    result = XSD::NamedElements.new
    result.concat(@simpletypes)
    @imports.each do |import|
      result.concat(import.content.collect_simpletypes) if import.content
    end
    result
  end

  def self.parse_element(element)
    if element == SchemaName
      Schema.new
    else
      nil
    end
  end
end


end
end
PK     Z\H  H    wsdl/xmlSchema/unique.rbnu [        # WSDL4R - XMLSchema unique element.
# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module XMLSchema


class Unique < Info
  def initialize
    super
  end

  def parse_element(element)
    # Accepts any element.
    self
  end

  def parse_attr(attr, value)
    # Accepts any attribute.
    true
  end
end


end
end
PK      Z\rY  Y    wsdl/xmlSchema/annotation.rbnu [        # WSDL4R - WSDL SOAP documentation element.
# Copyright (C) 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module XMLSchema


class Annotation < Info
  def initialize
    super
  end

  def parse_element(element)
    # Accepts any element.
    self
  end

  def parse_attr(attr, value)
    # Accepts any attribute.
    true
  end
end


end
end
PK     !Z\Σu/      wsdl/xmlSchema/all.rbnu [        # WSDL4R - XMLSchema complexType definition for WSDL.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module XMLSchema


class All < Info
  attr_reader :minoccurs
  attr_reader :maxoccurs
  attr_reader :elements

  def initialize
    super()
    @minoccurs = '1'
    @maxoccurs = '1'
    @elements = []
  end

  def targetnamespace
    parent.targetnamespace
  end

  def elementformdefault
    parent.elementformdefault
  end

  def <<(element)
    @elements << element
  end

  def parse_element(element)
    case element
    when AnyName
      o = Any.new
      @elements << o
      o
    when ElementName
      o = Element.new
      @elements << o
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when MaxOccursAttrName
      @maxoccurs = value.source
    when MinOccursAttrName
      @minoccurs = value.source
    else
      nil
    end
  end
end


end
end
PK     !Z\	6%      wsdl/xmlSchema/sequence.rbnu [        # WSDL4R - XMLSchema complexType definition for WSDL.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module XMLSchema


class Sequence < Info
  attr_reader :minoccurs
  attr_reader :maxoccurs
  attr_reader :elements

  def initialize
    super()
    @minoccurs = '1'
    @maxoccurs = '1'
    @elements = []
  end

  def targetnamespace
    parent.targetnamespace
  end

  def elementformdefault
    parent.elementformdefault
  end

  def <<(element)
    @elements << element
  end

  def parse_element(element)
    case element
    when AnyName
      o = Any.new
      @elements << o
      o
    when ElementName
      o = Element.new
      @elements << o
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when MaxOccursAttrName
      @maxoccurs = value.source
    when MinOccursAttrName
      @minoccurs = value.source
    else
      nil
    end
  end
end


end
end
PK     "Z\Z
T  T    wsdl/xmlSchema/xsd2ruby.rbnu [        # XSD4R - XSD to ruby mapping library.
# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/codegen/gensupport'
require 'wsdl/xmlSchema/importer'
require 'wsdl/soap/classDefCreator'


module WSDL
module XMLSchema


class XSD2Ruby
  attr_accessor :location
  attr_reader :opt
  attr_accessor :logger
  attr_accessor :basedir

  def run
    unless @location
      raise RuntimeError, "XML Schema location not given"
    end
    @xsd = import(@location)
    @name = create_classname(@xsd)
    create_file
  end

private

  def initialize
    @location = nil
    @opt = {}
    @logger = Logger.new(STDERR)
    @basedir = nil
    @xsd = nil
    @name = nil
  end

  def create_file
    create_classdef
  end

  def create_classdef
    @logger.info { "Creating class definition." }
    @classdef_filename = @name + '.rb'
    check_file(@classdef_filename) or return
    write_file(@classdef_filename) do |f|
      f << WSDL::SOAP::ClassDefCreator.new(@xsd).dump
    end
  end

  def write_file(filename)
    if @basedir
      filename = File.join(basedir, filename)
    end
    File.open(filename, "w") do |f|
      yield f
    end
  end

  def check_file(filename)
    if @basedir
      filename = File.join(basedir, filename)
    end
    if FileTest.exist?(filename)
      if @opt.key?('force')
	@logger.warn {
	  "File '#{filename}' exists but overrides it."
	}
	true
      else
	@logger.warn {
	  "File '#{filename}' exists.  #{$0} did not override it."
	}
	false
      end
    else
      @logger.info { "Creates file '#{filename}'." }
      true
    end
  end

  def create_classname(xsd)
    name = nil
    if xsd.targetnamespace
      name = xsd.targetnamespace.scan(/[a-zA-Z0-9]+$/)[0]
    end
    if name.nil?
      'default'
    else
      XSD::CodeGen::GenSupport.safevarname(name)
    end
  end

  def import(location)
    WSDL::XMLSchema::Importer.import(location)
  end
end


end
end
PK     "Z\U%      wsdl/xmlSchema/enumeration.rbnu [        # WSDL4R - XMLSchema enumeration definition for WSDL.
# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module XMLSchema


class Enumeration < Info
  def initialize
    super
  end

  def parse_element(element)
    nil
  end

  def parse_attr(attr, value)
    case attr
    when ValueAttrName
      parent.enumeration << value.source
      value.source
    end
  end
end


end
end
PK     "Z\p      wsdl/xmlSchema/import.rbnu [        # WSDL4R - XMLSchema import definition.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'wsdl/xmlSchema/importer'


module WSDL
module XMLSchema


class Import < Info
  attr_reader :namespace
  attr_reader :schemalocation
  attr_reader :content

  def initialize
    super
    @namespace = nil
    @schemalocation = nil
    @content = nil
  end

  def parse_element(element)
    nil
  end

  def parse_attr(attr, value)
    case attr
    when NamespaceAttrName
      @namespace = value.source
    when SchemaLocationAttrName
      @schemalocation = URI.parse(value.source)
      if @schemalocation.relative? and !parent.location.nil? and
          !parent.location.relative?
        @schemalocation = parent.location + @schemalocation
      end
      if root.importedschema.key?(@schemalocation)
        @content = root.importedschema[@schemalocation]
      else
        root.importedschema[@schemalocation] = nil      # placeholder
        @content = import(@schemalocation)
        root.importedschema[@schemalocation] = @content
      end
      @schemalocation
    else
      nil
    end
  end

private

  def import(location)
    Importer.import(location, root)
  end
end


end
end
PK     #Z\8n      wsdl/xmlSchema/simpleContent.rbnu [        # WSDL4R - XMLSchema simpleContent definition for WSDL.
# Copyright (C) 2004, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'xsd/namedelements'


module WSDL
module XMLSchema


class SimpleContent < Info
  attr_reader :restriction
  attr_reader :extension

  def check_lexical_format(value)
    check(value)
  end

  def initialize
    super
    @restriction = nil
    @extension = nil
  end

  def base
    content.base
  end

  def targetnamespace
    parent.targetnamespace
  end

  def parse_element(element)
    case element
    when RestrictionName
      @restriction = SimpleRestriction.new
      @restriction
    when ExtensionName
      @extension = SimpleExtension.new
      @extension
    end
  end

private

  def content
    @restriction || @extension
  end

  def check(value)
    unless content.valid?(value)
      raise XSD::ValueSpaceError.new("#{@name}: cannot accept '#{value}'")
    end
  end
end


end
end
PK     $Z\#      wsdl/xmlSchema/choice.rbnu [        # WSDL4R - XMLSchema complexType definition for WSDL.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module XMLSchema


class Choice < Info
  attr_reader :minoccurs
  attr_reader :maxoccurs
  attr_reader :elements

  def initialize
    super()
    @minoccurs = '1'
    @maxoccurs = '1'
    @elements = []
  end

  def targetnamespace
    parent.targetnamespace
  end

  def elementformdefault
    parent.elementformdefault
  end

  def <<(element)
    @elements << element
  end

  def parse_element(element)
    case element
    when AnyName
      o = Any.new
      @elements << o
      o
    when ElementName
      o = Element.new
      @elements << o
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when MaxOccursAttrName
      @maxoccurs = value.source
    when MinOccursAttrName
      @minoccurs = value.source
    else
      nil
    end
  end
end


end
end
PK     %Z\.O      wsdl/xmlSchema/parser.rbnu [        # WSDL4R - WSDL XML Instance parser library.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/qname'
require 'xsd/ns'
require 'xsd/charset'
require 'xsd/datatypes'
require 'xsd/xmlparser'
require 'wsdl/xmlSchema/data'


module WSDL
module XMLSchema


class Parser
  include XSD

  class ParseError < Error; end
  class FormatDecodeError < ParseError; end
  class UnknownElementError < FormatDecodeError; end
  class UnknownAttributeError < FormatDecodeError; end
  class UnexpectedElementError < FormatDecodeError; end
  class ElementConstraintError < FormatDecodeError; end
  class AttributeConstraintError < FormatDecodeError; end

private

  class ParseFrame
    attr_reader :ns
    attr_reader :name
    attr_accessor :node

  private

    def initialize(ns, name, node)
      @ns = ns
      @name = name
      @node = node
    end
  end

public

  def initialize(opt = {})
    @parser = XSD::XMLParser.create_parser(self, opt)
    @parsestack = nil
    @lastnode = nil
    @ignored = {}
    @location = opt[:location]
    @originalroot = opt[:originalroot]
  end

  def parse(string_or_readable)
    @parsestack = []
    @lastnode = nil
    @textbuf = ''
    @parser.do_parse(string_or_readable)
    @lastnode
  end

  def charset
    @parser.charset
  end

  def start_element(name, attrs)
    lastframe = @parsestack.last
    ns = parent = nil
    if lastframe
      ns = lastframe.ns.clone_ns
      parent = lastframe.node
    else
      ns = XSD::NS.new
      parent = nil
    end
    attrs = XSD::XMLParser.filter_ns(ns, attrs)
    node = decode_tag(ns, name, attrs, parent)
    @parsestack << ParseFrame.new(ns, name, node)
  end

  def characters(text)
    lastframe = @parsestack.last
    if lastframe
      # Need not to be cloned because character does not have attr.
      ns = lastframe.ns
      decode_text(ns, text)
    else
      p text if $DEBUG
    end
  end

  def end_element(name)
    lastframe = @parsestack.pop
    unless name == lastframe.name
      raise UnexpectedElementError.new("closing element name '#{name}' does not match with opening element '#{lastframe.name}'")
    end
    decode_tag_end(lastframe.ns, lastframe.node)
    @lastnode = lastframe.node
  end

private

  def decode_tag(ns, name, attrs, parent)
    o = nil
    elename = ns.parse(name)
    if !parent
      if elename == SchemaName
	o = Schema.parse_element(elename)
        o.location = @location
      else
	raise UnknownElementError.new("unknown element: #{elename}")
      end
      o.root = @originalroot if @originalroot   # o.root = o otherwise
    else
      if elename == AnnotationName
        # only the first annotation element is allowed for each element.
        o = Annotation.new
      else
        o = parent.parse_element(elename)
      end
      unless o
        unless @ignored.key?(elename)
          warn("ignored element: #{elename} of #{parent.class}")
          @ignored[elename] = elename
        end
	o = Documentation.new	# which accepts any element.
      end
      # node could be a pseudo element.  pseudo element has its own parent.
      o.root = parent.root
      o.parent = parent if o.parent.nil?
    end
    attrs.each do |key, value|
      attr_ele = ns.parse(key, true)
      value_ele = ns.parse(value, true)
      value_ele.source = value  # for recovery; value may not be a QName
      if attr_ele == IdAttrName
	o.id = value_ele
      else
        unless o.parse_attr(attr_ele, value_ele)
          unless @ignored.key?(attr_ele)
            warn("ignored attr: #{attr_ele}")
            @ignored[attr_ele] = attr_ele
          end
        end
      end
    end
    o
  end

  def decode_tag_end(ns, node)
    node.parse_epilogue
  end

  def decode_text(ns, text)
    @textbuf << text
  end
end


end
end
PK     %Z\@  @    wsdl/xmlSchema/any.rbnu [        # WSDL4R - XMLSchema any definition for WSDL.
# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module XMLSchema


class Any < Info
  attr_accessor :maxoccurs
  attr_accessor :minoccurs
  attr_accessor :namespace
  attr_accessor :process_contents

  def initialize
    super()
    @maxoccurs = '1'
    @minoccurs = '1'
    @namespace = '##any'
    @process_contents = 'strict'
  end

  def targetnamespace
    parent.targetnamespace
  end

  def parse_element(element)
    nil
  end

  def parse_attr(attr, value)
    case attr
    when MaxOccursAttrName
      @maxoccurs = value.source
    when MinOccursAttrName
      @minoccurs = value.source
    when NamespaceAttrName
      @namespace = value.source
    when ProcessContentsAttrName
      @process_contents = value.source
    else
      nil
    end
  end
end


end
end
PK     &Z\L      wsdl/xmlSchema/include.rbnu [        # WSDL4R - XMLSchema include definition.
# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'wsdl/xmlSchema/importer'


module WSDL
module XMLSchema


class Include < Info
  attr_reader :schemalocation
  attr_reader :content

  def initialize
    super
    @schemalocation = nil
    @content = nil
  end

  def parse_element(element)
    nil
  end

  def parse_attr(attr, value)
    case attr
    when SchemaLocationAttrName
      @schemalocation = URI.parse(value.source)
      if @schemalocation.relative?
        @schemalocation = parent.location + @schemalocation
      end
      @content = import(@schemalocation)
      @schemalocation
    else
      nil
    end
  end

private

  def import(location)
    Importer.import(location)
  end
end


end
end
PK     'Z\#*{A  A    wsdl/xmlSchema/element.rbnu [        # WSDL4R - XMLSchema element definition for WSDL.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module XMLSchema


class Element < Info
  class << self
    if RUBY_VERSION > "1.7.0"
      def attr_reader_ref(symbol)
        name = symbol.to_s
        define_method(name) {
          instance_variable_get("@#{name}") ||
            (refelement ? refelement.__send__(name) : nil)
        }
      end
    else
      def attr_reader_ref(symbol)
        name = symbol.to_s
        module_eval <<-EOS
          def #{name}
            @#{name} || (refelement ? refelement.#{name} : nil)
          end
        EOS
      end
    end
  end

  attr_writer :name	# required
  attr_writer :form
  attr_writer :type
  attr_writer :local_simpletype
  attr_writer :local_complextype
  attr_writer :constraint
  attr_writer :maxoccurs
  attr_writer :minoccurs
  attr_writer :nillable

  attr_reader_ref :name
  attr_reader_ref :form
  attr_reader_ref :type
  attr_reader_ref :local_simpletype
  attr_reader_ref :local_complextype
  attr_reader_ref :constraint
  attr_reader_ref :maxoccurs
  attr_reader_ref :minoccurs
  attr_reader_ref :nillable

  attr_accessor :ref

  def initialize(name = nil, type = nil)
    super()
    @name = name
    @form = nil
    @type = type
    @local_simpletype = @local_complextype = nil
    @constraint = nil
    @maxoccurs = '1'
    @minoccurs = '1'
    @nillable = nil
    @ref = nil
    @refelement = nil
  end

  def refelement
    @refelement ||= (@ref ? root.collect_elements[@ref] : nil)
  end

  def targetnamespace
    parent.targetnamespace
  end

  def elementformdefault
    parent.elementformdefault
  end

  def elementform
    self.form.nil? ? parent.elementformdefault : self.form
  end

  def parse_element(element)
    case element
    when SimpleTypeName
      @local_simpletype = SimpleType.new
      @local_simpletype
    when ComplexTypeName
      @type = nil
      @local_complextype = ComplexType.new
      @local_complextype
    when UniqueName
      @constraint = Unique.new
      @constraint
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when NameAttrName
      # namespace may be nil
      if directelement? or elementform == 'qualified'
        @name = XSD::QName.new(targetnamespace, value.source)
      else
        @name = XSD::QName.new(nil, value.source)
      end
    when FormAttrName
      @form = value.source
    when TypeAttrName
      @type = value
    when RefAttrName
      @ref = value
    when MaxOccursAttrName
      if parent.is_a?(All)
	if value.source != '1'
	  raise Parser::AttrConstraintError.new(
            "cannot parse #{value} for #{attr}")
	end
      end
      @maxoccurs = value.source
    when MinOccursAttrName
      if parent.is_a?(All)
	unless ['0', '1'].include?(value.source)
	  raise Parser::AttrConstraintError.new(
            "cannot parse #{value} for #{attr}")
	end
      end
      @minoccurs = value.source
    when NillableAttrName
      @nillable = (value.source == 'true')
    else
      nil
    end
  end

private

  def directelement?
    parent.is_a?(Schema)
  end
end


end
end
PK     'Z\=t    !  wsdl/xmlSchema/simpleExtension.rbnu [        # WSDL4R - XMLSchema simpleType extension definition for WSDL.
# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'xsd/namedelements'


module WSDL
module XMLSchema


class SimpleExtension < Info
  attr_reader :base
  attr_reader :attributes

  def initialize
    super
    @base = nil
    @attributes = XSD::NamedElements.new
  end

  def targetnamespace
    parent.targetnamespace
  end
  
  def valid?(value)
    true
  end

  def parse_element(element)
    case element
    when AttributeName
      o = Attribute.new
      @attributes << o
      o
    end
  end

  def parse_attr(attr, value)
    case attr
    when BaseAttrName
      @base = value
    end
  end
end


end
end
PK     'Z\#~  ~    wsdl/xmlSchema/simpleType.rbnu [        # WSDL4R - XMLSchema simpleType definition for WSDL.
# Copyright (C) 2004, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'xsd/namedelements'


module WSDL
module XMLSchema


class SimpleType < Info
  attr_accessor :name
  attr_reader :restriction

  def check_lexical_format(value)
    if @restriction
      check_restriction(value)
    else
      raise ArgumentError.new("incomplete simpleType")
    end
  end

  def base
    if @restriction
      @restriction.base
    else
      raise ArgumentError.new("incomplete simpleType")
    end
  end

  def initialize(name = nil)
    super()
    @name = name
    @restriction = nil
  end

  def targetnamespace
    parent.targetnamespace
  end

  def parse_element(element)
    case element
    when RestrictionName
      @restriction = SimpleRestriction.new
      @restriction
    end
  end

  def parse_attr(attr, value)
    case attr
    when NameAttrName
      @name = XSD::QName.new(targetnamespace, value.source)
    end
  end

private

  def check_restriction(value)
    unless @restriction.valid?(value)
      raise XSD::ValueSpaceError.new("#{@name}: cannot accept '#{value}'")
    end
  end
end


end
end
PK     (Z\
  
    wsdl/xmlSchema/attribute.rbnu [        # WSDL4R - XMLSchema attribute definition for WSDL.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module XMLSchema


class Attribute < Info
  class << self
    if RUBY_VERSION > "1.7.0"
      def attr_reader_ref(symbol)
        name = symbol.to_s
        define_method(name) {
          instance_variable_get("@#{name}") ||
            (refelement ? refelement.__send__(name) : nil)
        }
      end
    else
      def attr_reader_ref(symbol)
        name = symbol.to_s
        module_eval <<-EOS
          def #{name}
            @#{name} || (refelement ? refelement.#{name} : nil)
          end
        EOS
      end
    end
  end

  attr_writer :use
  attr_writer :form
  attr_writer :name
  attr_writer :type
  attr_writer :local_simpletype
  attr_writer :default
  attr_writer :fixed

  attr_reader_ref :use
  attr_reader_ref :form
  attr_reader_ref :name
  attr_reader_ref :type
  attr_reader_ref :local_simpletype
  attr_reader_ref :default
  attr_reader_ref :fixed

  attr_accessor :ref
  attr_accessor :arytype

  def initialize
    super
    @use = nil
    @form = nil
    @name = nil
    @type = nil
    @local_simpletype = nil
    @default = nil
    @fixed = nil
    @ref = nil
    @refelement = nil
    @arytype = nil
  end

  def refelement
    @refelement ||= root.collect_attributes[@ref]
  end

  def targetnamespace
    parent.targetnamespace
  end

  def parse_element(element)
    case element
    when SimpleTypeName
      @local_simpletype = SimpleType.new
      @local_simpletype
    end
  end

  def parse_attr(attr, value)
    case attr
    when RefAttrName
      @ref = value
    when UseAttrName
      @use = value.source
    when FormAttrName
      @form = value.source
    when NameAttrName
      if directelement?
        @name = XSD::QName.new(targetnamespace, value.source)
      else
        @name = XSD::QName.new(nil, value.source)
      end
    when TypeAttrName
      @type = value
    when DefaultAttrName
      @default = value.source
    when FixedAttrName
      @fixed = value.source
    when ArrayTypeAttrName
      @arytype = if value.namespace.nil?
          XSD::QName.new(XSD::Namespace, value.source)
        else
          value
        end
    else
      nil
    end
  end

private

  def directelement?
    parent.is_a?(Schema)
  end
end


end
end
PK     (Z\^0  0    wsdl/info.rbnu [        # WSDL4R - WSDL information base.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


module WSDL


class Info
  attr_accessor :root
  attr_accessor :parent
  attr_accessor :id

  def initialize
    @root = nil
    @parent = nil
    @id = nil
  end

  def inspect
    if self.respond_to?(:name)
      sprintf("#<%s:0x%x %s>", self.class.name, __id__, self.name)
    else
      sprintf("#<%s:0x%x>", self.class.name, __id__)
    end
  end

  def parse_element(element); end	# abstract
  
  def parse_attr(attr, value); end	# abstract

  def parse_epilogue; end		# abstract
end


end
PK     (Z\J;      wsdl/definitions.rbnu [        # WSDL4R - WSDL definitions.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'xsd/namedelements'


module WSDL


class Definitions < Info
  attr_reader :name
  attr_reader :targetnamespace
  attr_reader :imports

  attr_accessor :location
  attr_reader :importedschema

  def initialize
    super
    @name = nil
    @targetnamespace = nil
    @location = nil
    @importedschema = {}

    @types = nil
    @imports = []
    @messages = XSD::NamedElements.new
    @porttypes = XSD::NamedElements.new
    @bindings = XSD::NamedElements.new
    @services = XSD::NamedElements.new

    @anontypes = XSD::NamedElements.new
    @root = self
  end

  def inspect
    sprintf("#<%s:0x%x %s>", self.class.name, __id__, @name || '(unnamed)')
  end

  def targetnamespace=(targetnamespace)
    @targetnamespace = targetnamespace
    if @name
      @name = XSD::QName.new(@targetnamespace, @name.name)
    end
  end

  def collect_attributes
    result = XSD::NamedElements.new
    if @types
      @types.schemas.each do |schema|
	result.concat(schema.collect_attributes)
      end
    end
    @imports.each do |import|
      result.concat(import.content.collect_attributes)
    end
    result
  end

  def collect_elements
    result = XSD::NamedElements.new
    if @types
      @types.schemas.each do |schema|
	result.concat(schema.collect_elements)
      end
    end
    @imports.each do |import|
      result.concat(import.content.collect_elements)
    end
    result
  end

  def collect_complextypes
    result = @anontypes.dup
    if @types
      @types.schemas.each do |schema|
	result.concat(schema.collect_complextypes)
      end
    end
    @imports.each do |import|
      result.concat(import.content.collect_complextypes)
    end
    result
  end

  def collect_simpletypes
    result = XSD::NamedElements.new
    if @types
      @types.schemas.each do |schema|
	result.concat(schema.collect_simpletypes)
      end
    end
    @imports.each do |import|
      result.concat(import.content.collect_simpletypes)
    end
    result
  end

  # ToDo: simpletype must be accepted...
  def add_type(complextype)
    @anontypes << complextype
  end

  def messages
    result = @messages.dup
    @imports.each do |import|
      result.concat(import.content.messages) if self.class === import.content
    end
    result
  end

  def porttypes
    result = @porttypes.dup
    @imports.each do |import|
      result.concat(import.content.porttypes) if self.class === import.content
    end
    result
  end

  def bindings
    result = @bindings.dup
    @imports.each do |import|
      result.concat(import.content.bindings) if self.class === import.content
    end
    result
  end

  def services
    result = @services.dup
    @imports.each do |import|
      result.concat(import.content.services) if self.class === import.content
    end
    result
  end

  def message(name)
    message = @messages[name]
    return message if message
    @imports.each do |import|
      message = import.content.message(name) if self.class === import.content
      return message if message
    end
    nil
  end

  def porttype(name)
    porttype = @porttypes[name]
    return porttype if porttype
    @imports.each do |import|
      porttype = import.content.porttype(name) if self.class === import.content
      return porttype if porttype
    end
    nil
  end

  def binding(name)
    binding = @bindings[name]
    return binding if binding
    @imports.each do |import|
      binding = import.content.binding(name) if self.class === import.content
      return binding if binding
    end
    nil
  end

  def service(name)
    service = @services[name]
    return service if service
    @imports.each do |import|
      service = import.content.service(name) if self.class === import.content
      return service if service
    end
    nil
  end

  def porttype_binding(name)
    binding = @bindings.find { |item| item.type == name }
    return binding if binding
    @imports.each do |import|
      binding = import.content.porttype_binding(name) if self.class === import.content
      return binding if binding
    end
    nil
  end

  def parse_element(element)
    case element
    when ImportName
      o = Import.new
      @imports << o
      o
    when TypesName
      o = Types.new
      @types = o
      o
    when MessageName
      o = Message.new
      @messages << o
      o
    when PortTypeName
      o = PortType.new
      @porttypes << o
      o
    when BindingName
      o = Binding.new
      @bindings << o
      o
    when ServiceName
      o = Service.new
      @services << o
      o
    when DocumentationName
      o = Documentation.new
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when NameAttrName
      @name = XSD::QName.new(targetnamespace, value.source)
    when TargetNamespaceAttrName
      self.targetnamespace = value.source
    else
      nil
    end
  end

  def self.parse_element(element)
    if element == DefinitionsName
      Definitions.new
    else
      nil
    end
  end

private

end


end
PK     )Z\_WA  A    wsdl/documentation.rbnu [        # WSDL4R - WSDL SOAP documentation element.
# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL


class Documentation < Info
  def initialize
    super
  end

  def parse_element(element)
    # Accepts any element.
    self
  end

  def parse_attr(attr, value)
    # Accepts any attribute.
    true
  end
end


end
PK     *Z\;pn      wsdl/message.rbnu [        # WSDL4R - WSDL message definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL


class Message < Info
  attr_reader :name	# required
  attr_reader :parts

  def initialize
    super
    @name = nil
    @parts = []
  end

  def targetnamespace
    parent.targetnamespace
  end

  def parse_element(element)
    case element
    when PartName
      o = Part.new
      @parts << o
      o
    when DocumentationName
      o = Documentation.new
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when NameAttrName
      @name = XSD::QName.new(parent.targetnamespace, value.source)
    else
      nil
    end
  end
end


end
PK     *Z\)J      wsdl/param.rbnu [        # WSDL4R - WSDL param definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL


class Param < Info
  attr_reader :message	# required
  attr_reader :name	# optional but required for fault.
  attr_reader :soapbody
  attr_reader :soapheader
  attr_reader :soapfault

  def initialize
    super
    @message = nil
    @name = nil
    @soapbody = nil
    @soapheader = []
    @soapfault = nil
  end

  def targetnamespace
    parent.targetnamespace
  end

  def find_message
    root.message(@message) or raise RuntimeError.new("#{@message} not found")
  end

  def soapbody_use
    if @soapbody
      @soapbody.use || :literal
    else
      raise RuntimeError.new("soap:body not found")
    end
  end

  def parse_element(element)
    case element
    when SOAPBodyName
      o = WSDL::SOAP::Body.new
      @soapbody = o
      o
    when SOAPHeaderName
      o = WSDL::SOAP::Header.new
      @soapheader << o
      o
    when SOAPFaultName
      o = WSDL::SOAP::Fault.new
      @soap_fault = o
      o
    when DocumentationName
      o = Documentation.new
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when MessageAttrName
      if value.namespace.nil?
        value = XSD::QName.new(targetnamespace, value.source)
      end
      @message = value
    when NameAttrName
      @name = XSD::QName.new(targetnamespace, value.source)
    else
      nil
    end
  end
end


end
PK     *Z\B      wsdl/binding.rbnu [        # WSDL4R - WSDL binding definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'xsd/namedelements'


module WSDL


class Binding < Info
  attr_reader :name		# required
  attr_reader :type		# required
  attr_reader :operations
  attr_reader :soapbinding

  def initialize
    super
    @name = nil
    @type = nil
    @operations = XSD::NamedElements.new
    @soapbinding = nil
  end

  def targetnamespace
    parent.targetnamespace
  end

  def parse_element(element)
    case element
    when OperationName
      o = OperationBinding.new
      @operations << o
      o
    when SOAPBindingName
      o = WSDL::SOAP::Binding.new
      @soapbinding = o
      o
    when DocumentationName
      o = Documentation.new
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when NameAttrName
      @name = XSD::QName.new(targetnamespace, value.source)
    when TypeAttrName
      @type = value
    else
      nil
    end
  end
end


end
PK     +Z\,;      wsdl/portType.rbnu [        # WSDL4R - WSDL portType definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'xsd/namedelements'


module WSDL


class PortType < Info
  attr_reader :name		# required
  attr_reader :operations

  def targetnamespace
    parent.targetnamespace
  end

  def initialize
    super
    @name = nil
    @operations = XSD::NamedElements.new
  end

  def find_binding
    root.bindings.find { |item| item.type == @name } or
      raise RuntimeError.new("#{@name} not found")
  end

  def locations
    bind_name = find_binding.name
    result = []
    root.services.each do |service|
      service.ports.each do |port|
        if port.binding == bind_name
          result << port.soap_address.location if port.soap_address
        end
      end
    end
    result
  end

  def parse_element(element)
    case element
    when OperationName
      o = Operation.new
      @operations << o
      o
    when DocumentationName
      o = Documentation.new
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when NameAttrName
      @name = XSD::QName.new(targetnamespace, value.source)
    else
      nil
    end
  end
end


end
PK     ,Z\˃ʱ      wsdl/import.rbnu [        # WSDL4R - WSDL import definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'wsdl/importer'


module WSDL


class Import < Info
  attr_reader :namespace
  attr_reader :location
  attr_reader :content

  def initialize
    super
    @namespace = nil
    @location = nil
    @content = nil
    @web_client = nil
  end

  def parse_element(element)
    case element
    when DocumentationName
      o = Documentation.new
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when NamespaceAttrName
      @namespace = value.source
      if @content
	@content.targetnamespace = @namespace
      end
      @namespace
    when LocationAttrName
      @location = URI.parse(value.source)
      if @location.relative? and !parent.location.nil? and
          !parent.location.relative?
        @location = parent.location + @location
      end
      if root.importedschema.key?(@location)
        @content = root.importedschema[@location]
      else
        root.importedschema[@location] = nil      # placeholder
        @content = import(@location)
        if @content.is_a?(Definitions)
          @content.root = root
          if @namespace
            @content.targetnamespace = @namespace
          end
        end
        root.importedschema[@location] = @content
      end
      @location
    else
      nil
    end
  end

private

  def import(location)
    Importer.import(location, root)
  end
end


end
PK     -Z\y5
  5
    wsdl/operation.rbnu [        # WSDL4R - WSDL operation definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL


class Operation < Info
  class NameInfo
    attr_reader :op_name
    attr_reader :optype_name
    attr_reader :parts
    def initialize(op_name, optype_name, parts)
      @op_name = op_name
      @optype_name = optype_name
      @parts = parts
    end
  end

  attr_reader :name		# required
  attr_reader :parameter_order	# optional
  attr_reader :input
  attr_reader :output
  attr_reader :fault
  attr_reader :type		# required

  def initialize
    super
    @name = nil
    @type = nil
    @parameter_order = nil
    @input = nil
    @output = nil
    @fault = []
  end

  def targetnamespace
    parent.targetnamespace
  end

  def input_info
    typename = input.find_message.name
    NameInfo.new(@name, typename, inputparts)
  end

  def output_info
    typename = output.find_message.name
    NameInfo.new(@name, typename, outputparts)
  end

  def inputparts
    sort_parts(input.find_message.parts)
  end

  def inputname
    XSD::QName.new(targetnamespace, input.name ? input.name.name : @name.name)
  end

  def outputparts
    sort_parts(output.find_message.parts)
  end

  def outputname
    XSD::QName.new(targetnamespace,
      output.name ? output.name.name : @name.name + 'Response')
  end

  def parse_element(element)
    case element
    when InputName
      o = Param.new
      @input = o
      o
    when OutputName
      o = Param.new
      @output = o
      o
    when FaultName
      o = Param.new
      @fault << o
      o
    when DocumentationName
      o = Documentation.new
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when NameAttrName
      @name = XSD::QName.new(targetnamespace, value.source)
    when TypeAttrName
      @type = value
    when ParameterOrderAttrName
      @parameter_order = value.source.split(/\s+/)
    else
      nil
    end
  end

private

  def sort_parts(parts)
    return parts.dup unless parameter_order
    result = []
    parameter_order.each do |orderitem|
      if (ele = parts.find { |part| part.name == orderitem })
	result << ele
      end
    end
    if result.length == 0
      return parts.dup
    end
    # result length can be shorter than parts's.
    # return part must not be a part of the parameterOrder.
    result
  end
end


end
PK     -Z\	      wsdl/parser.rbnu [        # WSDL4R - WSDL XML Instance parser library.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/qname'
require 'xsd/ns'
require 'xsd/charset'
require 'xsd/datatypes'
require 'xsd/xmlparser'
require 'wsdl/wsdl'
require 'wsdl/data'
require 'wsdl/xmlSchema/data'
require 'wsdl/soap/data'


module WSDL


class Parser
  include WSDL

  class ParseError < Error; end
  class FormatDecodeError < ParseError; end
  class UnknownElementError < FormatDecodeError; end
  class UnknownAttributeError < FormatDecodeError; end
  class UnexpectedElementError < FormatDecodeError; end
  class ElementConstraintError < FormatDecodeError; end
  class AttributeConstraintError < FormatDecodeError; end

private

  class ParseFrame
    attr_reader :ns
    attr_reader :name
    attr_accessor :node

  private

    def initialize(ns, name, node)
      @ns = ns
      @name = name
      @node = node
    end
  end

public

  def initialize(opt = {})
    @parser = XSD::XMLParser.create_parser(self, opt)
    @parsestack = nil
    @lastnode = nil
    @ignored = {}
    @location = opt[:location]
    @originalroot = opt[:originalroot]
  end

  def parse(string_or_readable)
    @parsestack = []
    @lastnode = nil
    @textbuf = ''
    @parser.do_parse(string_or_readable)
    @lastnode
  end

  def charset
    @parser.charset
  end

  def start_element(name, attrs)
    lastframe = @parsestack.last
    ns = parent = nil
    if lastframe
      ns = lastframe.ns.clone_ns
      parent = lastframe.node
    else
      ns = XSD::NS.new
      parent = nil
    end
    attrs = XSD::XMLParser.filter_ns(ns, attrs)
    node = decode_tag(ns, name, attrs, parent)
    @parsestack << ParseFrame.new(ns, name, node)
  end

  def characters(text)
    lastframe = @parsestack.last
    if lastframe
      # Need not to be cloned because character does not have attr.
      ns = lastframe.ns
      decode_text(ns, text)
    else
      p text if $DEBUG
    end
  end

  def end_element(name)
    lastframe = @parsestack.pop
    unless name == lastframe.name
      raise UnexpectedElementError.new("closing element name '#{name}' does not match with opening element '#{lastframe.name}'")
    end
    decode_tag_end(lastframe.ns, lastframe.node)
    @lastnode = lastframe.node
  end

private

  def decode_tag(ns, name, attrs, parent)
    o = nil
    elename = ns.parse(name)
    if !parent
      if elename == DefinitionsName
	o = Definitions.parse_element(elename)
        o.location = @location
      else
	raise UnknownElementError.new("unknown element: #{elename}")
      end
      o.root = @originalroot if @originalroot   # o.root = o otherwise
    else
      if elename == XMLSchema::AnnotationName
        # only the first annotation element is allowed for each xsd element.
        o = XMLSchema::Annotation.new
      else
        o = parent.parse_element(elename)
      end
      unless o
        unless @ignored.key?(elename)
          warn("ignored element: #{elename}")
          @ignored[elename] = elename
        end
	o = Documentation.new	# which accepts any element.
      end
      # node could be a pseudo element.  pseudo element has its own parent.
      o.root = parent.root
      o.parent = parent if o.parent.nil?
    end
    attrs.each do |key, value|
      attr_ele = ns.parse(key, true)
      value_ele = ns.parse(value, true)
      value_ele.source = value  # for recovery; value may not be a QName
      unless o.parse_attr(attr_ele, value_ele)
        unless @ignored.key?(attr_ele)
          warn("ignored attr: #{attr_ele}")
          @ignored[attr_ele] = attr_ele
        end
      end
    end
    o
  end

  def decode_tag_end(ns, node)
    node.parse_epilogue
  end

  def decode_text(ns, text)
    @textbuf << text
  end
end


end
PK     .Z\UIla  a    wsdl/service.rbnu [        # WSDL4R - WSDL service definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'xsd/namedelements'


module WSDL


class Service < Info
  attr_reader :name		# required
  attr_reader :ports
  attr_reader :soap_address

  def initialize
    super
    @name = nil
    @ports = XSD::NamedElements.new
    @soap_address = nil
  end

  def targetnamespace
    parent.targetnamespace
  end

  def parse_element(element)
    case element
    when PortName
      o = Port.new
      @ports << o
      o
    when SOAPAddressName
      o = WSDL::SOAP::Address.new
      @soap_address = o
      o
    when DocumentationName
      o = Documentation.new
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when NameAttrName
      @name = XSD::QName.new(targetnamespace, value.source)
    else
      nil
    end
  end
end


end
PK     .Z\G	  	  (  wsdl/soap/standaloneServerStubCreator.rbnu [        # WSDL4R - Creating standalone server stub code from WSDL.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'wsdl/soap/mappingRegistryCreator'
require 'wsdl/soap/methodDefCreator'
require 'wsdl/soap/classDefCreatorSupport'


module WSDL
module SOAP


class StandaloneServerStubCreator
  include ClassDefCreatorSupport

  attr_reader :definitions

  def initialize(definitions)
    @definitions = definitions
  end

  def dump(service_name)
    warn("- Standalone stub can have only 1 port for now.  So creating stub for the first port and rests are ignored.")
    warn("- Standalone server stub ignores port location defined in WSDL.  Location is http://localhost:10080/ by default.  Generated client from WSDL must be configured to point this endpoint manually.")
    port = @definitions.service(service_name).ports[0]
    dump_porttype(port.porttype.name)
  end

private

  def dump_porttype(name)
    class_name = create_class_name(name)
    methoddef, types = MethodDefCreator.new(@definitions).dump(name)
    mr_creator = MappingRegistryCreator.new(@definitions)

    c1 = XSD::CodeGen::ClassDef.new(class_name)
    c1.def_require("soap/rpc/standaloneServer")
    c1.def_require("soap/mapping/registry")
    c1.def_const("MappingRegistry", "::SOAP::Mapping::Registry.new")
    c1.def_code(mr_creator.dump(types))
    c1.def_code <<-EOD
Methods = [
#{methoddef.gsub(/^/, "  ")}
]
    EOD
    c2 = XSD::CodeGen::ClassDef.new(class_name + "App",
      "::SOAP::RPC::StandaloneServer")
    c2.def_method("initialize", "*arg") do
      <<-EOD
        super(*arg)
        servant = #{class_name}.new
        #{class_name}::Methods.each do |definitions|
          opt = definitions.last
          if opt[:request_style] == :document
            @router.add_document_operation(servant, *definitions)
          else
            @router.add_rpc_operation(servant, *definitions)
          end
        end
        self.mapping_registry = #{class_name}::MappingRegistry
      EOD
    end
    c1.dump + "\n" + c2.dump + format(<<-EOD)

      if $0 == __FILE__
        # Change listen port.
        server = #{class_name}App.new('app', nil, '0.0.0.0', 10080)
        trap(:INT) do
          server.shutdown
        end
        server.start
      end
    EOD
  end
end


end
end
PK     .Z\L!`  `    wsdl/soap/cgiStubCreator.rbnu [        # WSDL4R - Creating CGI stub code from WSDL.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'wsdl/soap/mappingRegistryCreator'
require 'wsdl/soap/methodDefCreator'
require 'wsdl/soap/classDefCreatorSupport'


module WSDL
module SOAP


class CGIStubCreator
  include ClassDefCreatorSupport

  attr_reader :definitions

  def initialize(definitions)
    @definitions = definitions
  end

  def dump(service_name)
    warn("CGI stub can have only 1 port.  Creating stub for the first port...  Rests are ignored.")
    port = @definitions.service(service_name).ports[0]
    dump_porttype(port.porttype.name)
  end

private

  def dump_porttype(name)
    class_name = create_class_name(name)
    methoddef, types = MethodDefCreator.new(@definitions).dump(name)
    mr_creator = MappingRegistryCreator.new(@definitions)
    c1 = XSD::CodeGen::ClassDef.new(class_name)
    c1.def_require("soap/rpc/cgistub")
    c1.def_require("soap/mapping/registry")
    c1.def_const("MappingRegistry", "::SOAP::Mapping::Registry.new")
    c1.def_code(mr_creator.dump(types))
    c1.def_code <<-EOD
Methods = [
#{methoddef.gsub(/^/, "  ")}
]
    EOD
    c2 = XSD::CodeGen::ClassDef.new(class_name + "App",
      "::SOAP::RPC::CGIStub")
    c2.def_method("initialize", "*arg") do
      <<-EOD
        super(*arg)
        servant = #{class_name}.new
        #{class_name}::Methods.each do |definitions|
          opt = definitions.last
          if opt[:request_style] == :document
            @router.add_document_operation(servant, *definitions)
          else
            @router.add_rpc_operation(servant, *definitions)
          end
        end
        self.mapping_registry = #{class_name}::MappingRegistry
        self.level = Logger::Severity::ERROR
      EOD
    end
    c1.dump + "\n" + c2.dump + format(<<-EOD)
      #{class_name}App.new('app', nil).start
    EOD
  end
end


end
end
PK     /Z\R͛      wsdl/soap/complexType.rbnu [        # WSDL4R - SOAP complexType definition for WSDL.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/xmlSchema/complexType'
require 'soap/mapping'


module WSDL
module XMLSchema


class ComplexType < Info
  def compoundtype
    @compoundtype ||= check_type
  end

  def check_type
    if content
      if attributes.empty? and
          content.elements.size == 1 and content.elements[0].maxoccurs != '1'
        if name == ::SOAP::Mapping::MapQName
          :TYPE_MAP
        else
          :TYPE_ARRAY
        end
      else
	:TYPE_STRUCT
      end
    elsif complexcontent
      if complexcontent.base == ::SOAP::ValueArrayName
        :TYPE_ARRAY
      else
        complexcontent.basetype.check_type
      end
    elsif simplecontent
      :TYPE_SIMPLE
    elsif !attributes.empty?
      :TYPE_STRUCT
    else # empty complexType definition (seen in partner.wsdl of salesforce)
      :TYPE_EMPTY
    end
  end

  def child_type(name = nil)
    case compoundtype
    when :TYPE_STRUCT
      if ele = find_element(name)
        ele.type
      elsif ele = find_element_by_name(name.name)
	ele.type
      end
    when :TYPE_ARRAY
      @contenttype ||= content_arytype
    when :TYPE_MAP
      item_ele = find_element_by_name("item") or
        raise RuntimeError.new("'item' element not found in Map definition.")
      content = item_ele.local_complextype or
        raise RuntimeError.new("No complexType definition for 'item'.")
      if ele = content.find_element(name)
        ele.type
      elsif ele = content.find_element_by_name(name.name)
        ele.type
      end
    else
      raise NotImplementedError.new("Unknown kind of complexType.")
    end
  end

  def child_defined_complextype(name)
    ele = nil
    case compoundtype
    when :TYPE_STRUCT, :TYPE_MAP
      unless ele = find_element(name)
       	if name.namespace.nil?
  	  ele = find_element_by_name(name.name)
   	end
      end
    when :TYPE_ARRAY
      if content.elements.size == 1
	ele = content.elements[0]
      else
	raise RuntimeError.new("Assert: must not reach.")
      end
    else
      raise RuntimeError.new("Assert: Not implemented.")
    end
    unless ele
      raise RuntimeError.new("Cannot find #{name} as a children of #{@name}.")
    end
    ele.local_complextype
  end

  def find_arytype
    unless compoundtype == :TYPE_ARRAY
      raise RuntimeError.new("Assert: not for array")
    end
    if complexcontent
      complexcontent.attributes.each do |attribute|
	if attribute.ref == ::SOAP::AttrArrayTypeName
	  return attribute.arytype
	end
      end
      if check_array_content(complexcontent.content)
        return element_simpletype(complexcontent.content.elements[0])
      end
    elsif check_array_content(content)
      return element_simpletype(content.elements[0])
    end
    raise RuntimeError.new("Assert: Unknown array definition.")
  end

  def find_aryelement
    unless compoundtype == :TYPE_ARRAY
      raise RuntimeError.new("Assert: not for array")
    end
    if complexcontent
      if check_array_content(complexcontent.content)
        return complexcontent.content.elements[0]
      end
    elsif check_array_content(content)
      return content.elements[0]
    end
    nil # use default item name
  end

private

  def element_simpletype(element)
    if element.type
      element.type 
    elsif element.local_simpletype
      element.local_simpletype.base
    else
      nil
    end
  end

  def check_array_content(content)
    content and content.elements.size == 1 and
      content.elements[0].maxoccurs != '1'
  end

  def content_arytype
    if arytype = find_arytype
      ns = arytype.namespace
      name = arytype.name.sub(/\[(?:,)*\]$/, '')
      XSD::QName.new(ns, name)
    else
      nil
    end
  end
end


end
end
PK     /Z\Q	  	    wsdl/soap/data.rbnu [        # WSDL4R - WSDL SOAP binding data definitions.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/qname'
require 'wsdl/soap/definitions'
require 'wsdl/soap/binding'
require 'wsdl/soap/operation'
require 'wsdl/soap/body'
require 'wsdl/soap/element'
require 'wsdl/soap/header'
require 'wsdl/soap/headerfault'
require 'wsdl/soap/fault'
require 'wsdl/soap/address'
require 'wsdl/soap/complexType'


module WSDL
module SOAP


HeaderFaultName = XSD::QName.new(SOAPBindingNamespace, 'headerfault')

LocationAttrName = XSD::QName.new(nil, 'location')
StyleAttrName = XSD::QName.new(nil, 'style')
TransportAttrName = XSD::QName.new(nil, 'transport')
UseAttrName = XSD::QName.new(nil, 'use')
PartsAttrName = XSD::QName.new(nil, 'parts')
PartAttrName = XSD::QName.new(nil, 'part')
NameAttrName = XSD::QName.new(nil, 'name')
MessageAttrName = XSD::QName.new(nil, 'message')
EncodingStyleAttrName = XSD::QName.new(nil, 'encodingStyle')
NamespaceAttrName = XSD::QName.new(nil, 'namespace')
SOAPActionAttrName = XSD::QName.new(nil, 'soapAction')


end
end
PK     /Z\7	(      wsdl/soap/address.rbnu [        # WSDL4R - WSDL SOAP address definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module SOAP


class Address < Info
  attr_reader :location

  def initialize
    super
    @location = nil
  end

  def parse_element(element)
    nil
  end

  def parse_attr(attr, value)
    case attr
    when LocationAttrName
      @location = value.source
    else
      nil
    end
  end
end


end
end
PK     1Z\7K:  :    wsdl/soap/headerfault.rbnu [        # WSDL4R - WSDL SOAP body definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module SOAP


class HeaderFault < Info
  attr_reader :message	# required
  attr_reader :part	# required
  attr_reader :use	# required
  attr_reader :encodingstyle
  attr_reader :namespace

  def initialize
    super
    @message = nil
    @part = nil
    @use = nil
    @encodingstyle = nil
    @namespace = nil
  end

  def parse_element(element)
    nil
  end

  def parse_attr(attr, value)
    case attr
    when MessageAttrName
      @message = value
    when PartAttrName
      @part = value.source
    when UseAttrName
      @use = value.source
    when EncodingStyleAttrName
      @encodingstyle = value.source
    when NamespaceAttrName
      @namespace = value.source
    else
      nil
    end
  end
end


end
end
PK     1Z\P0Y    "  wsdl/soap/servantSkeltonCreator.rbnu [        # WSDL4R - Creating servant skelton code from WSDL.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'wsdl/soap/classDefCreatorSupport'
require 'xsd/codegen'


module WSDL
module SOAP


class ServantSkeltonCreator
  include ClassDefCreatorSupport
  include XSD::CodeGen::GenSupport

  attr_reader :definitions

  def initialize(definitions)
    @definitions = definitions
  end

  def dump(porttype = nil)
    if porttype.nil?
      result = ""
      @definitions.porttypes.each do |type|
	result << dump_porttype(type.name)
	result << "\n"
      end
    else
      result = dump_porttype(porttype)
    end
    result
  end

private

  def dump_porttype(name)
    class_name = create_class_name(name)
    c = XSD::CodeGen::ClassDef.new(class_name)
    operations = @definitions.porttype(name).operations
    operations.each do |operation|
      name = safemethodname(operation.name.name)
      input = operation.input
      params = input.find_message.parts.collect { |part|
        safevarname(part.name)
      }
      m = XSD::CodeGen::MethodDef.new(name, params) do <<-EOD
            p [#{params.join(", ")}]
            raise NotImplementedError.new
          EOD
        end
      m.comment = dump_method_signature(operation)
      c.add_method(m)
    end
    c.dump
  end
end


end
end
PK     2Z\Z~  ~    wsdl/soap/definitions.rbnu [        # WSDL4R - WSDL additional definitions for SOAP.
# Copyright (C) 2002-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'xsd/namedelements'
require 'soap/mapping'


module WSDL


class Definitions < Info
  def self.soap_rpc_complextypes
    types = XSD::NamedElements.new
    types << array_complextype
    types << fault_complextype
    types << exception_complextype
    types
  end

  def self.array_complextype
    type = XMLSchema::ComplexType.new(::SOAP::ValueArrayName)
    type.complexcontent = XMLSchema::ComplexContent.new
    type.complexcontent.base = ::SOAP::ValueArrayName
    attr = XMLSchema::Attribute.new
    attr.ref = ::SOAP::AttrArrayTypeName
    anytype = XSD::AnyTypeName.dup
    anytype.name += '[]'
    attr.arytype = anytype
    type.complexcontent.attributes << attr
    type
  end

=begin
<xs:complexType name="Fault" final="extension">
  <xs:sequence>
    <xs:element name="faultcode" type="xs:QName" /> 
    <xs:element name="faultstring" type="xs:string" /> 
    <xs:element name="faultactor" type="xs:anyURI" minOccurs="0" /> 
    <xs:element name="detail" type="tns:detail" minOccurs="0" /> 
  </xs:sequence>
</xs:complexType>
=end
  def self.fault_complextype
    type = XMLSchema::ComplexType.new(::SOAP::EleFaultName)
    faultcode = XMLSchema::Element.new(::SOAP::EleFaultCodeName, XSD::XSDQName::Type)
    faultstring = XMLSchema::Element.new(::SOAP::EleFaultStringName, XSD::XSDString::Type)
    faultactor = XMLSchema::Element.new(::SOAP::EleFaultActorName, XSD::XSDAnyURI::Type)
    faultactor.minoccurs = 0
    detail = XMLSchema::Element.new(::SOAP::EleFaultDetailName, XSD::AnyTypeName)
    detail.minoccurs = 0
    type.all_elements = [faultcode, faultstring, faultactor, detail]
    type.final = 'extension'
    type
  end

  def self.exception_complextype
    type = XMLSchema::ComplexType.new(XSD::QName.new(
	::SOAP::Mapping::RubyCustomTypeNamespace, 'SOAPException'))
    excn_name = XMLSchema::Element.new(XSD::QName.new(nil, 'excn_type_name'), XSD::XSDString::Type)
    cause = XMLSchema::Element.new(XSD::QName.new(nil, 'cause'), XSD::AnyTypeName)
    backtrace = XMLSchema::Element.new(XSD::QName.new(nil, 'backtrace'), ::SOAP::ValueArrayName)
    message = XMLSchema::Element.new(XSD::QName.new(nil, 'message'), XSD::XSDString::Type)
    type.all_elements = [excn_name, cause, backtrace, message]
    type
  end

  def soap_rpc_complextypes(binding)
    types = rpc_operation_complextypes(binding)
    types + self.class.soap_rpc_complextypes
  end

  def collect_faulttypes
    result = []
    collect_fault_messages.each do |name|
      faultparts = message(name).parts
      if faultparts.size != 1
	raise RuntimeError.new("expecting fault message to have only 1 part")
      end
      if result.index(faultparts[0].type).nil?
	result << faultparts[0].type
      end
    end
    result
  end

private

  def collect_fault_messages
    result = []
    porttypes.each do |porttype|
      porttype.operations.each do |operation|
	operation.fault.each do |fault|
	  if result.index(fault.message).nil?
	    result << fault.message
	  end
	end
      end
    end
    result
  end

  def rpc_operation_complextypes(binding)
    types = XSD::NamedElements.new
    binding.operations.each do |op_bind|
      if op_bind_rpc?(op_bind)
	operation = op_bind.find_operation
	if op_bind.input
	  type = XMLSchema::ComplexType.new(op_bind.soapoperation_name)
	  message = messages[operation.input.message]
	  type.sequence_elements = elements_from_message(message)
	  types << type
	end
	if op_bind.output
	  type = XMLSchema::ComplexType.new(operation.outputname)
	  message = messages[operation.output.message]
	  type.sequence_elements = elements_from_message(message)
	  types << type
	end
      end
    end
    types
  end

  def op_bind_rpc?(op_bind)
    op_bind.soapoperation_style == :rpc
  end

  def elements_from_message(message)
    message.parts.collect { |part|
      if part.element
        collect_elements[part.element]
      elsif part.name.nil? or part.type.nil?
	raise RuntimeError.new("part of a message must be an element or typed")
      else
        qname = XSD::QName.new(nil, part.name)
        XMLSchema::Element.new(qname, part.type)
      end
    }
  end
end


end
PK     3Z\#Ph  h    wsdl/soap/body.rbnu [        # WSDL4R - WSDL SOAP body definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module SOAP


class Body < Info
  attr_reader :parts
  attr_reader :use	# required
  attr_reader :encodingstyle
  attr_reader :namespace

  def initialize
    super
    @parts = nil
    @use = nil
    @encodingstyle = nil
    @namespace = nil
  end

  def parse_element(element)
    nil
  end

  def parse_attr(attr, value)
    case attr
    when PartsAttrName
      @parts = value.source
    when UseAttrName
      if ['literal', 'encoded'].include?(value.source)
        @use = value.source.intern
      else
        raise RuntimeError.new("unknown use of soap:body: #{value.source}")
      end
    when EncodingStyleAttrName
      @encodingstyle = value.source
    when NamespaceAttrName
      @namespace = value.source
    else
      nil
    end
  end
end


end
end
PK     3Z\^8	  	  #  wsdl/soap/classDefCreatorSupport.rbnu [        # WSDL4R - Creating class code support from WSDL.
# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'soap/mapping'
require 'soap/mapping/typeMap'
require 'xsd/codegen/gensupport'


module WSDL
module SOAP


module ClassDefCreatorSupport
  include XSD::CodeGen::GenSupport

  def create_class_name(qname)
    if klass = basetype_mapped_class(qname)
      ::SOAP::Mapping::DefaultRegistry.find_mapped_obj_class(klass).name
    else
      safeconstname(qname.name)
    end
  end

  def basetype_mapped_class(name)
    ::SOAP::TypeMap[name]
  end

  def dump_method_signature(operation)
    name = operation.name.name
    input = operation.input
    output = operation.output
    fault = operation.fault
    signature = "#{ name }#{ dump_inputparam(input) }"
    str = <<__EOD__
# SYNOPSIS
#   #{name}#{dump_inputparam(input)}
#
# ARGS
#{dump_inout_type(input).chomp}
#
# RETURNS
#{dump_inout_type(output).chomp}
#
__EOD__
    unless fault.empty?
      faultstr = (fault.collect { |f| dump_inout_type(f).chomp }).join(', ')
      str <<<<__EOD__
# RAISES
#   #{faultstr}
#
__EOD__
    end
    str
  end

  def dq(ele)
    ele.dump
  end

  def ndq(ele)
    ele.nil? ? 'nil' : dq(ele)
  end

  def sym(ele)
    ':' + ele
  end

  def dqname(qname)
    qname.dump
  end

private

  def dump_inout_type(param)
    if param
      message = param.find_message
      params = ""
      message.parts.each do |part|
        name = safevarname(part.name)
        if part.type
          typename = safeconstname(part.type.name)
          params << add_at("#   #{name}", "#{typename} - #{part.type}\n", 20)
        elsif part.element
          typename = safeconstname(part.element.name)
          params << add_at("#   #{name}", "#{typename} - #{part.element}\n", 20)
        end
      end
      unless params.empty?
        return params
      end
    end
    "#   N/A\n"
  end

  def dump_inputparam(input)
    message = input.find_message
    params = ""
    message.parts.each do |part|
      params << ", " unless params.empty?
      params << safevarname(part.name)
    end
    if params.empty?
      ""
    else
      "(#{ params })"
    end
  end

  def add_at(base, str, pos)
    if base.size >= pos
      base + ' ' + str
    else
      base + ' ' * (pos - base.size) + str
    end
  end
end


end
end
PK     4Z\#{(  (    wsdl/soap/fault.rbnu [        # WSDL4R - WSDL SOAP body definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module SOAP


class Fault < Info
  attr_reader :name	# required
  attr_reader :use	# required
  attr_reader :encodingstyle
  attr_reader :namespace

  def initialize
    super
    @name = nil
    @use = nil
    @encodingstyle = nil
    @namespace = nil
  end

  def targetnamespace
    parent.targetnamespace
  end

  def parse_element(element)
    nil
  end

  def parse_attr(attr, value)
    case attr
    when NameAttrName
      @name = XSD::QName.new(targetnamespace, value.source)
    when UseAttrName
      @use = value.source
    when EncodingStyleAttrName
      @encodingstyle = value.source
    when NamespaceAttrName
      @namespace = value.source
    else
      nil
    end
  end
end


end
end
PK     5Z\u?D    !  wsdl/soap/clientSkeltonCreator.rbnu [        # WSDL4R - Creating client skelton code from WSDL.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'wsdl/soap/classDefCreatorSupport'


module WSDL
module SOAP


class ClientSkeltonCreator
  include ClassDefCreatorSupport

  attr_reader :definitions

  def initialize(definitions)
    @definitions = definitions
  end

  def dump(service_name)
    result = ""
    @definitions.service(service_name).ports.each do |port|
      result << dump_porttype(port.porttype.name)
      result << "\n"
    end
    result
  end

private

  def dump_porttype(name)
    drv_name = create_class_name(name)

    result = ""
    result << <<__EOD__
endpoint_url = ARGV.shift
obj = #{ drv_name }.new(endpoint_url)

# run ruby with -d to see SOAP wiredumps.
obj.wiredump_dev = STDERR if $DEBUG

__EOD__
    @definitions.porttype(name).operations.each do |operation|
      result << dump_method_signature(operation)
      result << dump_input_init(operation.input) << "\n"
      result << dump_operation(operation) << "\n\n"
    end
    result
  end

  def dump_operation(operation)
    name = operation.name
    input = operation.input
    "puts obj.#{ safemethodname(name.name) }#{ dump_inputparam(input) }"
  end

  def dump_input_init(input)
    result = input.find_message.parts.collect { |part|
      safevarname(part.name)
    }.join(" = ")
    if result.empty?
      ""
    else
      result << " = nil"
    end
    result
  end
end


end
end
PK     6Z\Xd	  	    wsdl/soap/driverCreator.rbnu [        # WSDL4R - Creating driver code from WSDL.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'wsdl/soap/mappingRegistryCreator'
require 'wsdl/soap/methodDefCreator'
require 'wsdl/soap/classDefCreatorSupport'
require 'xsd/codegen'


module WSDL
module SOAP


class DriverCreator
  include ClassDefCreatorSupport

  attr_reader :definitions

  def initialize(definitions)
    @definitions = definitions
  end

  def dump(porttype = nil)
    if porttype.nil?
      result = ""
      @definitions.porttypes.each do |type|
	result << dump_porttype(type.name)
	result << "\n"
      end
    else
      result = dump_porttype(porttype)
    end
    result
  end

private

  def dump_porttype(name)
    class_name = create_class_name(name)
    methoddef, types = MethodDefCreator.new(@definitions).dump(name)
    mr_creator = MappingRegistryCreator.new(@definitions)
    binding = @definitions.bindings.find { |item| item.type == name }
    return '' unless binding.soapbinding        # not a SOAP binding
    address = @definitions.porttype(name).locations[0]

    c = XSD::CodeGen::ClassDef.new(class_name, "::SOAP::RPC::Driver")
    c.def_require("soap/rpc/driver")
    c.def_const("MappingRegistry", "::SOAP::Mapping::Registry.new")
    c.def_const("DefaultEndpointUrl", ndq(address))
    c.def_code(mr_creator.dump(types))
    c.def_code <<-EOD
Methods = [
#{methoddef.gsub(/^/, "  ")}
]
    EOD
    c.def_method("initialize", "endpoint_url = nil") do
      <<-EOD
        endpoint_url ||= DefaultEndpointUrl
        super(endpoint_url, nil)
        self.mapping_registry = MappingRegistry
        init_methods
      EOD
    end
    c.def_privatemethod("init_methods") do
      <<-EOD
        Methods.each do |definitions|
          opt = definitions.last
          if opt[:request_style] == :document
            add_document_operation(*definitions)
          else
            add_rpc_operation(*definitions)
            qname = definitions[0]
            name = definitions[2]
            if qname.name != name and qname.name.capitalize == name.capitalize
              ::SOAP::Mapping.define_singleton_method(self, qname.name) do |*arg|
                __send__(name, *arg)
              end
            end
          end
        end
      EOD
    end
    c.dump
  end
end


end
end
PK     7Z\6vq  q    wsdl/soap/wsdl2ruby.rbnu [        # WSDL4R - WSDL to ruby mapping library.
# Copyright (C) 2002-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'logger'
require 'xsd/qname'
require 'wsdl/importer'
require 'wsdl/soap/classDefCreator'
require 'wsdl/soap/servantSkeltonCreator'
require 'wsdl/soap/driverCreator'
require 'wsdl/soap/clientSkeltonCreator'
require 'wsdl/soap/standaloneServerStubCreator'
require 'wsdl/soap/cgiStubCreator'


module WSDL
module SOAP


class WSDL2Ruby
  attr_accessor :location
  attr_reader :opt
  attr_accessor :logger
  attr_accessor :basedir

  def run
    unless @location
      raise RuntimeError, "WSDL location not given"
    end
    @wsdl = import(@location)
    @name = @wsdl.name ? @wsdl.name.name : 'default'
    create_file
  end

private

  def initialize
    @location = nil
    @opt = {}
    @logger = Logger.new(STDERR)
    @basedir = nil
    @wsdl = nil
    @name = nil
  end

  def create_file
    create_classdef if @opt.key?('classdef')
    create_servant_skelton(@opt['servant_skelton']) if @opt.key?('servant_skelton')
    create_cgi_stub(@opt['cgi_stub']) if @opt.key?('cgi_stub')
    create_standalone_server_stub(@opt['standalone_server_stub']) if @opt.key?('standalone_server_stub')
    create_driver(@opt['driver']) if @opt.key?('driver')
    create_client_skelton(@opt['client_skelton']) if @opt.key?('client_skelton')
  end

  def create_classdef
    @logger.info { "Creating class definition." }
    @classdef_filename = @name + '.rb'
    check_file(@classdef_filename) or return
    write_file(@classdef_filename) do |f|
      f << WSDL::SOAP::ClassDefCreator.new(@wsdl).dump
    end
  end

  def create_client_skelton(servicename)
    @logger.info { "Creating client skelton." }
    servicename ||= @wsdl.services[0].name.name
    @client_skelton_filename = servicename + 'Client.rb'
    check_file(@client_skelton_filename) or return
    write_file(@client_skelton_filename) do |f|
      f << shbang << "\n"
      f << "require '#{@driver_filename}'\n\n" if @driver_filename
      f << WSDL::SOAP::ClientSkeltonCreator.new(@wsdl).dump(
	create_name(servicename))
    end
  end

  def create_servant_skelton(porttypename)
    @logger.info { "Creating servant skelton." }
    @servant_skelton_filename = (porttypename || @name + 'Servant') + '.rb'
    check_file(@servant_skelton_filename) or return
    write_file(@servant_skelton_filename) do |f|
      f << "require '#{@classdef_filename}'\n\n" if @classdef_filename
      f << WSDL::SOAP::ServantSkeltonCreator.new(@wsdl).dump(
	create_name(porttypename))
    end
  end

  def create_cgi_stub(servicename)
    @logger.info { "Creating CGI stub." }
    servicename ||= @wsdl.services[0].name.name
    @cgi_stubFilename = servicename + '.cgi'
    check_file(@cgi_stubFilename) or return
    write_file(@cgi_stubFilename) do |f|
      f << shbang << "\n"
      if @servant_skelton_filename
	f << "require '#{@servant_skelton_filename}'\n\n"
      end
      f << WSDL::SOAP::CGIStubCreator.new(@wsdl).dump(create_name(servicename))
    end
  end

  def create_standalone_server_stub(servicename)
    @logger.info { "Creating standalone stub." }
    servicename ||= @wsdl.services[0].name.name
    @standalone_server_stub_filename = servicename + '.rb'
    check_file(@standalone_server_stub_filename) or return
    write_file(@standalone_server_stub_filename) do |f|
      f << shbang << "\n"
      f << "require '#{@servant_skelton_filename}'\n\n" if @servant_skelton_filename
      f << WSDL::SOAP::StandaloneServerStubCreator.new(@wsdl).dump(
	create_name(servicename))
    end
  end

  def create_driver(porttypename)
    @logger.info { "Creating driver." }
    @driver_filename = (porttypename || @name) + 'Driver.rb'
    check_file(@driver_filename) or return
    write_file(@driver_filename) do |f|
      f << "require '#{@classdef_filename}'\n\n" if @classdef_filename
      f << WSDL::SOAP::DriverCreator.new(@wsdl).dump(
	create_name(porttypename))
    end
  end

  def write_file(filename)
    if @basedir
      filename = File.join(basedir, filename)
    end
    File.open(filename, "w") do |f|
      yield f
    end
  end

  def check_file(filename)
    if @basedir
      filename = File.join(basedir, filename)
    end
    if FileTest.exist?(filename)
      if @opt.key?('force')
	@logger.warn {
	  "File '#{filename}' exists but overrides it."
	}
	true
      else
	@logger.warn {
	  "File '#{filename}' exists.  #{$0} did not override it."
	}
	false
      end
    else
      @logger.info { "Creates file '#{filename}'." }
      true
    end
  end

  def shbang
    "#!/usr/bin/env ruby"
  end

  def create_name(name)
    name ? XSD::QName.new(@wsdl.targetnamespace, name) : nil
  end

  def import(location)
    WSDL::Importer.import(location)
  end
end


end
end
PK     7Z\X L      wsdl/soap/binding.rbnu [        # WSDL4R - WSDL SOAP binding definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module SOAP


class Binding < Info
  attr_reader :style
  attr_reader :transport

  def initialize
    super
    @style = nil
    @transport = nil
  end

  def parse_element(element)
    nil
  end

  def parse_attr(attr, value)
    case attr
    when StyleAttrName
      if ["document", "rpc"].include?(value.source)
	@style = value.source.intern
      else
	raise Parser::AttributeConstraintError.new(
          "Unexpected value #{ value }.")
      end
    when TransportAttrName
      @transport = value.source
    else
      nil
    end
  end
end


end
end
PK     8Z\q       wsdl/soap/header.rbnu [        # WSDL4R - WSDL SOAP body definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module SOAP


class Header < Info
  attr_reader :headerfault

  attr_reader :message	# required
  attr_reader :part	# required
  attr_reader :use	# required
  attr_reader :encodingstyle
  attr_reader :namespace

  def initialize
    super
    @message = nil
    @part = nil
    @use = nil
    @encodingstyle = nil
    @namespace = nil
    @headerfault = nil
  end

  def targetnamespace
    parent.targetnamespace
  end

  def find_message
    root.message(@message) or raise RuntimeError.new("#{@message} not found")
  end

  def find_part
    find_message.parts.each do |part|
      if part.name == @part
	return part
      end
    end
    raise RuntimeError.new("#{@part} not found")
  end

  def parse_element(element)
    case element
    when HeaderFaultName
      o = WSDL::SOAP::HeaderFault.new
      @headerfault = o
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when MessageAttrName
      if value.namespace.nil?
        value = XSD::QName.new(targetnamespace, value.source)
      end
      @message = value
    when PartAttrName
      @part = value.source
    when UseAttrName
      @use = value.source
    when EncodingStyleAttrName
      @encodingstyle = value.source
    when NamespaceAttrName
      @namespace = value.source
    else
      nil
    end
  end
end


end
end
PK     8Z\RG
  
    wsdl/soap/operation.rbnu [        # WSDL4R - WSDL SOAP operation definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL
module SOAP


class Operation < Info
  class OperationInfo
    attr_reader :style
    attr_reader :op_name
    attr_reader :optype_name
    attr_reader :headerparts
    attr_reader :bodyparts
    attr_reader :faultpart
    attr_reader :soapaction
    
    def initialize(style, op_name, optype_name, headerparts, bodyparts, faultpart, soapaction)
      @style = style
      @op_name = op_name
      @optype_name = optype_name
      @headerparts = headerparts
      @bodyparts = bodyparts
      @faultpart = faultpart
      @soapaction = soapaction
    end
  end

  attr_reader :soapaction
  attr_reader :style

  def initialize
    super
    @soapaction = nil
    @style = nil
  end

  def parse_element(element)
    nil
  end

  def parse_attr(attr, value)
    case attr
    when StyleAttrName
      if ["document", "rpc"].include?(value.source)
	@style = value.source.intern
      else
	raise Parser::AttributeConstraintError.new(
          "Unexpected value #{ value }.")
      end
    when SOAPActionAttrName
      @soapaction = value.source
    else
      nil
    end
  end

  def input_info
    name_info = parent.find_operation.input_info
    param_info(name_info, parent.input)
  end

  def output_info
    name_info = parent.find_operation.output_info
    param_info(name_info, parent.output)
  end

  def operation_style
    return @style if @style
    if parent_binding.soapbinding
      return parent_binding.soapbinding.style
    end
    nil
  end

private

  def parent_binding
    parent.parent
  end

  def param_info(name_info, param)
    op_name = name_info.op_name
    optype_name = name_info.optype_name

    soapheader = param.soapheader
    headerparts = soapheader.collect { |item| item.find_part }

    soapbody = param.soapbody
    if soapbody.encodingstyle and
	soapbody.encodingstyle != ::SOAP::EncodingNamespace
      raise NotImplementedError.new(
	"EncodingStyle '#{ soapbody.encodingstyle }' not supported.")
    end
    if soapbody.namespace
      op_name = XSD::QName.new(soapbody.namespace, op_name.name)
    end
    if soapbody.parts
      target = soapbody.parts.split(/\s+/)
      bodyparts = name_info.parts.find_all { |part|
	target.include?(part.name)
      }
    else
      bodyparts = name_info.parts
    end

    faultpart = nil
    OperationInfo.new(operation_style, op_name, optype_name, headerparts, bodyparts, faultpart, parent.soapaction)
  end
end


end
end
PK     9Z\8P    #  wsdl/soap/mappingRegistryCreator.rbnu [        # WSDL4R - Creating MappingRegistry code from WSDL.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'wsdl/soap/classDefCreatorSupport'


module WSDL
module SOAP


class MappingRegistryCreator
  include ClassDefCreatorSupport

  attr_reader :definitions

  def initialize(definitions)
    @definitions = definitions
    @complextypes = @definitions.collect_complextypes
    @types = nil
  end

  def dump(types)
    @types = types
    map_cache = []
    map = ""
    @types.each do |type|
      if map_cache.index(type).nil?
	map_cache << type
	if type.namespace != XSD::Namespace
	  if typemap = dump_typemap(type)
            map << typemap
          end
	end
      end
   end
    return map
  end

private

  def dump_typemap(type)
    if definedtype = @complextypes[type]
      case definedtype.compoundtype
      when :TYPE_STRUCT
        dump_struct_typemap(definedtype)
      when :TYPE_ARRAY
        dump_array_typemap(definedtype)
      when :TYPE_MAP, :TYPE_EMPTY
        nil
      else
        raise NotImplementedError.new("must not reach here")
      end
    end
  end

  def dump_struct_typemap(definedtype)
    ele = definedtype.name
    return <<__EOD__
MappingRegistry.set(
  #{create_class_name(ele)},
  ::SOAP::SOAPStruct,
  ::SOAP::Mapping::Registry::TypedStructFactory,
  { :type => #{dqname(ele)} }
)
__EOD__
  end

  def dump_array_typemap(definedtype)
    ele = definedtype.name
    arytype = definedtype.find_arytype || XSD::AnyTypeName
    type = XSD::QName.new(arytype.namespace, arytype.name.sub(/\[(?:,)*\]$/, ''))
    @types << type
    return <<__EOD__
MappingRegistry.set(
  #{create_class_name(ele)},
  ::SOAP::SOAPArray,
  ::SOAP::Mapping::Registry::TypedArrayFactory,
  { :type => #{dqname(type)} }
)
__EOD__
  end
end


end
end
PK     ;Z\S!  S!    wsdl/soap/classDefCreator.rbnu [        # WSDL4R - Creating class definition from WSDL
# Copyright (C) 2002, 2003, 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/data'
require 'wsdl/soap/classDefCreatorSupport'
require 'xsd/codegen'


module WSDL
module SOAP


class ClassDefCreator
  include ClassDefCreatorSupport

  def initialize(definitions)
    @elements = definitions.collect_elements
    @simpletypes = definitions.collect_simpletypes
    @complextypes = definitions.collect_complextypes
    @faulttypes = nil
    if definitions.respond_to?(:collect_faulttypes)
      @faulttypes = definitions.collect_faulttypes
    end
  end

  def dump(type = nil)
    result = "require 'xsd/qname'\n"
    if type
      result = dump_classdef(type.name, type)
    else
      str = dump_element
      unless str.empty?
        result << "\n" unless result.empty?
        result << str
      end
      str = dump_complextype
      unless str.empty?
        result << "\n" unless result.empty?
        result << str
      end
      str = dump_simpletype
      unless str.empty?
        result << "\n" unless result.empty?
        result << str
      end
    end
    result
  end

private

  def dump_element
    @elements.collect { |ele|
      if ele.local_complextype
        dump_classdef(ele.name, ele.local_complextype,
          ele.elementform == 'qualified')
      elsif ele.local_simpletype
        dump_simpletypedef(ele.name, ele.local_simpletype)
      else
        nil
      end
    }.compact.join("\n")
  end

  def dump_simpletype
    @simpletypes.collect { |type|
      dump_simpletypedef(type.name, type)
    }.compact.join("\n")
  end

  def dump_complextype
    @complextypes.collect { |type|
      case type.compoundtype
      when :TYPE_STRUCT, :TYPE_EMPTY
        dump_classdef(type.name, type)
      when :TYPE_ARRAY
        dump_arraydef(type)
      when :TYPE_SIMPLE
        dump_simpleclassdef(type)
      when :TYPE_MAP
        # mapped as a general Hash
        nil
      else
        raise RuntimeError.new(
          "unknown kind of complexContent: #{type.compoundtype}")
      end
    }.compact.join("\n")
  end

  def dump_simpletypedef(qname, simpletype)
    if !simpletype.restriction or simpletype.restriction.enumeration.empty?
      return nil
    end
    c = XSD::CodeGen::ModuleDef.new(create_class_name(qname))
    c.comment = "#{qname}"
    const = {}
    simpletype.restriction.enumeration.each do |value|
      constname = safeconstname(value)
      const[constname] ||= 0
      if (const[constname] += 1) > 1
        constname += "_#{const[constname]}"
      end
      c.def_const(constname, ndq(value))
    end
    c.dump
  end

  def dump_simpleclassdef(type_or_element)
    qname = type_or_element.name
    base = create_class_name(type_or_element.simplecontent.base)
    c = XSD::CodeGen::ClassDef.new(create_class_name(qname), base)
    c.comment = "#{qname}"
    c.dump
  end

  def dump_classdef(qname, typedef, qualified = false)
    if @faulttypes and @faulttypes.index(qname)
      c = XSD::CodeGen::ClassDef.new(create_class_name(qname),
        '::StandardError')
    else
      c = XSD::CodeGen::ClassDef.new(create_class_name(qname))
    end
    c.comment = "#{qname}"
    c.def_classvar('schema_type', ndq(qname.name))
    c.def_classvar('schema_ns', ndq(qname.namespace))
    c.def_classvar('schema_qualified', dq('true')) if qualified
    schema_element = []
    init_lines = ''
    params = []
    typedef.each_element do |element|
      if element.type == XSD::AnyTypeName
        type = nil
      elsif klass = element_basetype(element)
        type = klass.name
      elsif element.type
        type = create_class_name(element.type)
      else
        type = nil      # means anyType.
        # do we define a class for local complexType from it's name?
        #   type = create_class_name(element.name)
        # <element>
        #   <complexType>
        #     <seq...>
        #   </complexType>
        # </element>
      end
      name = name_element(element).name
      attrname = safemethodname?(name) ? name : safemethodname(name)
      varname = safevarname(name)
      c.def_attr(attrname, true, varname)
      init_lines << "@#{varname} = #{varname}\n"
      if element.map_as_array?
        params << "#{varname} = []"
        type << '[]' if type
      else
        params << "#{varname} = nil"
      end
      # nil means @@schema_ns + varname
      eleqname =
        (varname == name && element.name.namespace == qname.namespace) ?
        nil : element.name
      schema_element << [varname, eleqname, type]
    end
    unless typedef.attributes.empty?
      define_attribute(c, typedef.attributes)
      init_lines << "@__xmlattr = {}\n"
    end
    c.def_classvar('schema_element',
      '[' +
        schema_element.collect { |varname, name, type|
          '[' +
            (
              if name
                varname.dump + ', [' + ndq(type) + ', ' + dqname(name) + ']'
              else
                varname.dump + ', ' + ndq(type)
              end
            ) +
          ']'
        }.join(', ') +
      ']'
    )
    c.def_method('initialize', *params) do
      init_lines
    end
    c.dump
  end

  def element_basetype(ele)
    if klass = basetype_class(ele.type)
      klass
    elsif ele.local_simpletype
      basetype_class(ele.local_simpletype.base)
    else
      nil
    end
  end

  def attribute_basetype(attr)
    if klass = basetype_class(attr.type)
      klass
    elsif attr.local_simpletype
      basetype_class(attr.local_simpletype.base)
    else
      nil
    end
  end

  def basetype_class(type)
    return nil if type.nil?
    if simpletype = @simpletypes[type]
      basetype_mapped_class(simpletype.base)
    else
      basetype_mapped_class(type)
    end
  end

  def define_attribute(c, attributes)
    schema_attribute = []
    attributes.each do |attribute|
      name = name_attribute(attribute)
      if klass = attribute_basetype(attribute)
        type = klass.name
      else
        type = nil
      end
      methodname = safemethodname('xmlattr_' + name.name)
      c.def_method(methodname) do <<-__EOD__
          (@__xmlattr ||= {})[#{dqname(name)}]
        __EOD__
      end
      c.def_method(methodname + '=', 'value') do <<-__EOD__
          (@__xmlattr ||= {})[#{dqname(name)}] = value
        __EOD__
      end
      schema_attribute << [name, type]
    end
    c.def_classvar('schema_attribute',
      '{' +
        schema_attribute.collect { |name, type|
          dqname(name) + ' => ' + ndq(type)
        }.join(', ') +
      '}'
    )
  end

  def name_element(element)
    return element.name if element.name 
    return element.ref if element.ref
    raise RuntimeError.new("cannot define name of #{element}")
  end

  def name_attribute(attribute)
    return attribute.name if attribute.name 
    return attribute.ref if attribute.ref
    raise RuntimeError.new("cannot define name of #{attribute}")
  end

  DEFAULT_ITEM_NAME = XSD::QName.new(nil, 'item')

  def dump_arraydef(complextype)
    qname = complextype.name
    c = XSD::CodeGen::ClassDef.new(create_class_name(qname), '::Array')
    c.comment = "#{qname}"
    child_type = complextype.child_type
    c.def_classvar('schema_type', ndq(child_type.name))
    c.def_classvar('schema_ns', ndq(child_type.namespace))
    child_element = complextype.find_aryelement
    schema_element = []
    if child_type == XSD::AnyTypeName
      type = nil
    elsif child_element and (klass = element_basetype(child_element))
      type = klass.name
    elsif child_type
      type = create_class_name(child_type)
    else
      type = nil
    end
    if child_element
      if child_element.map_as_array?
        type << '[]' if type
      end
      child_element_name = child_element.name
    else
      child_element_name = DEFAULT_ITEM_NAME
    end
    schema_element << [child_element_name.name, child_element_name, type]
    c.def_classvar('schema_element',
      '[' +
        schema_element.collect { |varname, name, type|
          '[' +
            (
              if name
                varname.dump + ', [' + ndq(type) + ', ' + dqname(name) + ']'
              else
                varname.dump + ', ' + ndq(type)
              end
            ) +
          ']'
        }.join(', ') +
      ']'
    )
    c.dump
  end
end


end
end
PK     <Z\٢I"r  r    wsdl/soap/methodDefCreator.rbnu [        # WSDL4R - Creating driver code from WSDL.
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'
require 'wsdl/soap/classDefCreatorSupport'
require 'soap/rpc/element'


module WSDL
module SOAP


class MethodDefCreator
  include ClassDefCreatorSupport

  attr_reader :definitions

  def initialize(definitions)
    @definitions = definitions
    @simpletypes = @definitions.collect_simpletypes
    @complextypes = @definitions.collect_complextypes
    @elements = @definitions.collect_elements
    @types = []
  end

  def dump(porttype)
    @types.clear
    result = ""
    operations = @definitions.porttype(porttype).operations
    binding = @definitions.porttype_binding(porttype)
    operations.each do |operation|
      op_bind = binding.operations[operation.name]
      next unless op_bind # no binding is defined
      next unless op_bind.soapoperation # not a SOAP operation binding
      result << ",\n" unless result.empty?
      result << dump_method(operation, op_bind).chomp
    end
    return result, @types
  end

  def collect_rpcparameter(operation)
    result = operation.inputparts.collect { |part|
      collect_type(part.type)
      param_set(::SOAP::RPC::SOAPMethod::IN, part.name, rpcdefinedtype(part))
    }
    outparts = operation.outputparts
    if outparts.size > 0
      retval = outparts[0]
      collect_type(retval.type)
      result << param_set(::SOAP::RPC::SOAPMethod::RETVAL, retval.name,
        rpcdefinedtype(retval))
      cdr(outparts).each { |part|
	collect_type(part.type)
	result << param_set(::SOAP::RPC::SOAPMethod::OUT, part.name,
          rpcdefinedtype(part))
      }
    end
    result
  end

  def collect_documentparameter(operation)
    param = []
    operation.inputparts.each do |input|
      param << param_set(::SOAP::RPC::SOAPMethod::IN, input.name,
        documentdefinedtype(input), elementqualified(input))
    end
    operation.outputparts.each do |output|
      param << param_set(::SOAP::RPC::SOAPMethod::OUT, output.name,
        documentdefinedtype(output), elementqualified(output))
    end
    param
  end

private

  def dump_method(operation, binding)
    name = safemethodname(operation.name.name)
    name_as = operation.name.name
    style = binding.soapoperation_style
    inputuse = binding.input.soapbody_use
    outputuse = binding.output.soapbody_use
    namespace = binding.input.soapbody.namespace
    if style == :rpc
      qname = XSD::QName.new(namespace, name_as)
      paramstr = param2str(collect_rpcparameter(operation))
    else
      qname = nil
      paramstr = param2str(collect_documentparameter(operation))
    end
    if paramstr.empty?
      paramstr = '[]'
    else
      paramstr = "[ " << paramstr.split(/\r?\n/).join("\n    ") << " ]"
    end
    definitions = <<__EOD__
#{ndq(binding.soapaction)},
  #{dq(name)},
  #{paramstr},
  { :request_style =>  #{sym(style.id2name)}, :request_use =>  #{sym(inputuse.id2name)},
    :response_style => #{sym(style.id2name)}, :response_use => #{sym(outputuse.id2name)} }
__EOD__
    if style == :rpc
      return <<__EOD__
[ #{qname.dump},
  #{definitions}]
__EOD__
    else
      return <<__EOD__
[ #{definitions}]
__EOD__
    end
  end

  def rpcdefinedtype(part)
    if mapped = basetype_mapped_class(part.type)
      ['::' + mapped.name]
    elsif definedtype = @simpletypes[part.type]
      ['::' + basetype_mapped_class(definedtype.base).name]
    elsif definedtype = @elements[part.element]
      #['::SOAP::SOAPStruct', part.element.namespace, part.element.name]
      ['nil', part.element.namespace, part.element.name]
    elsif definedtype = @complextypes[part.type]
      case definedtype.compoundtype
      when :TYPE_STRUCT, :TYPE_EMPTY    # ToDo: empty should be treated as void.
        type = create_class_name(part.type)
	[type, part.type.namespace, part.type.name]
      when :TYPE_MAP
	[Hash.name, part.type.namespace, part.type.name]
      when :TYPE_ARRAY
	arytype = definedtype.find_arytype || XSD::AnyTypeName
	ns = arytype.namespace
	name = arytype.name.sub(/\[(?:,)*\]$/, '')
        type = create_class_name(XSD::QName.new(ns, name))
	[type + '[]', ns, name]
      else
	raise NotImplementedError.new("must not reach here")
      end
    else
      raise RuntimeError.new("part: #{part.name} cannot be resolved")
    end
  end

  def documentdefinedtype(part)
    if mapped = basetype_mapped_class(part.type)
      ['::' + mapped.name, nil, part.name]
    elsif definedtype = @simpletypes[part.type]
      ['::' + basetype_mapped_class(definedtype.base).name, nil, part.name]
    elsif definedtype = @elements[part.element]
      ['::SOAP::SOAPElement', part.element.namespace, part.element.name]
    elsif definedtype = @complextypes[part.type]
      ['::SOAP::SOAPElement', part.type.namespace, part.type.name]
    else
      raise RuntimeError.new("part: #{part.name} cannot be resolved")
    end
  end

  def elementqualified(part)
    if mapped = basetype_mapped_class(part.type)
      false
    elsif definedtype = @simpletypes[part.type]
      false
    elsif definedtype = @elements[part.element]
      definedtype.elementform == 'qualified'
    elsif definedtype = @complextypes[part.type]
      false
    else
      raise RuntimeError.new("part: #{part.name} cannot be resolved")
    end
  end

  def param_set(io_type, name, type, ele = nil)
    [io_type, name, type, ele]
  end

  def collect_type(type)
    # ignore inline type definition.
    return if type.nil?
    return if @types.include?(type)
    @types << type
    return unless @complextypes[type]
    @complextypes[type].each_element do |element|
      collect_type(element.type)
    end
  end

  def param2str(params)
    params.collect { |param|
      io, name, type, ele = param
      unless ele.nil?
        "[#{dq(io)}, #{dq(name)}, #{type2str(type)}, #{ele2str(ele)}]"
      else
        "[#{dq(io)}, #{dq(name)}, #{type2str(type)}]"
      end
    }.join(",\n")
  end

  def type2str(type)
    if type.size == 1
      "[#{dq(type[0])}]" 
    else
      "[#{dq(type[0])}, #{ndq(type[1])}, #{dq(type[2])}]" 
    end
  end

  def ele2str(ele)
    qualified = ele
    if qualified
      "true"
    else
      "false"
    end
  end

  def cdr(ary)
    result = ary.dup
    result.shift
    result
  end
end


end
end
PK     =Z\&      wsdl/soap/element.rbnu [        # WSDL4R - XMLSchema element definition for WSDL.
# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/xmlSchema/element'


module WSDL
module XMLSchema


class Element < Info
  def map_as_array?
    maxoccurs != '1'
  end

  def attributes
    @local_complextype.attributes
  end
end


end
end
PK     AZ\^Df  f    wsdl/port.rbnu [        # WSDL4R - WSDL port definition.
# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/info'


module WSDL


class Port < Info
  attr_reader :name		# required
  attr_reader :binding		# required
  attr_reader :soap_address

  def initialize
    super
    @name = nil
    @binding = nil
    @soap_address = nil
  end

  def targetnamespace
    parent.targetnamespace
  end

  def porttype
    root.porttype(find_binding.type)
  end

  def find_binding
    root.binding(@binding) or raise RuntimeError.new("#{@binding} not found")
  end

  def inputoperation_map
    result = {}
    find_binding.operations.each do |op_bind|
      op_info = op_bind.soapoperation.input_info
      result[op_info.op_name] = op_info
    end
    result
  end

  def outputoperation_map
    result = {}
    find_binding.operations.each do |op_bind|
      op_info = op_bind.soapoperation.output_info
      result[op_info.op_name] = op_info
    end
    result
  end

  def parse_element(element)
    case element
    when SOAPAddressName
      o = WSDL::SOAP::Address.new
      @soap_address = o
      o
    when DocumentationName
      o = Documentation.new
      o
    else
      nil
    end
  end

  def parse_attr(attr, value)
    case attr
    when NameAttrName
      @name = XSD::QName.new(targetnamespace, value.source)
    when BindingAttrName
      @binding = value
    else
      nil
    end
  end
end


end
PK     CZ\܃t30  30    rational.rbnu [        #
#   rational.rb -
#       $Release Version: 0.5 $
#       $Revision: 1.7 $
#       $Date: 1999/08/24 12:49:28 $
#       by Keiju ISHITSUKA(SHL Japan Inc.)
#
# Documentation by Kevin Jackson and Gavin Sinclair.
# 
# When you <tt>require 'rational'</tt>, all interactions between numbers
# potentially return a rational result.  For example:
#
#   1.quo(2)              # -> 0.5
#   require 'rational'
#   1.quo(2)              # -> Rational(1,2)
# 
# See Rational for full documentation.
#


#
# Creates a Rational number (i.e. a fraction).  +a+ and +b+ should be Integers:
# 
#   Rational(1,3)           # -> 1/3
#
# Note: trying to construct a Rational with floating point or real values
# produces errors:
#
#   Rational(1.1, 2.3)      # -> NoMethodError
#
def Rational(a, b = 1)
  if a.kind_of?(Rational) && b == 1
    a
  else
    Rational.reduce(a, b)
  end
end

#
# Rational implements a rational class for numbers.
#
# <em>A rational number is a number that can be expressed as a fraction p/q
# where p and q are integers and q != 0.  A rational number p/q is said to have
# numerator p and denominator q.  Numbers that are not rational are called
# irrational numbers.</em> (http://mathworld.wolfram.com/RationalNumber.html)
#
# To create a Rational Number:
#   Rational(a,b)             # -> a/b
#   Rational.new!(a,b)        # -> a/b
#
# Examples:
#   Rational(5,6)             # -> 5/6
#   Rational(5)               # -> 5/1
# 
# Rational numbers are reduced to their lowest terms:
#   Rational(6,10)            # -> 3/5
#
# But not if you use the unusual method "new!":
#   Rational.new!(6,10)       # -> 6/10
#
# Division by zero is obviously not allowed:
#   Rational(3,0)             # -> ZeroDivisionError
#
class Rational < Numeric
  @RCS_ID='-$Id: rational.rb,v 1.7 1999/08/24 12:49:28 keiju Exp keiju $-'

  #
  # Reduces the given numerator and denominator to their lowest terms.  Use
  # Rational() instead.
  #
  def Rational.reduce(num, den = 1)
    raise ZeroDivisionError, "denominator is zero" if den == 0

    if den < 0
      num = -num
      den = -den
    end
    gcd = num.gcd(den)
    num = num.div(gcd)
    den = den.div(gcd)
    if den == 1 && defined?(Unify)
      num
    else
      new!(num, den)
    end
  end

  #
  # Implements the constructor.  This method does not reduce to lowest terms or
  # check for division by zero.  Therefore #Rational() should be preferred in
  # normal use.
  #
  def Rational.new!(num, den = 1)
    new(num, den)
  end

  private_class_method :new

  #
  # This method is actually private.
  #
  def initialize(num, den)
    if den < 0
      num = -num
      den = -den
    end
    if num.kind_of?(Integer) and den.kind_of?(Integer)
      @numerator = num
      @denominator = den
    else
      @numerator = num.to_i
      @denominator = den.to_i
    end
  end

  #
  # Returns the addition of this value and +a+.
  #
  # Examples:
  #   r = Rational(3,4)      # -> Rational(3,4)
  #   r + 1                  # -> Rational(7,4)
  #   r + 0.5                # -> 1.25
  #
  def + (a)
    if a.kind_of?(Rational)
      num = @numerator * a.denominator
      num_a = a.numerator * @denominator
      Rational(num + num_a, @denominator * a.denominator)
    elsif a.kind_of?(Integer)
      self + Rational.new!(a, 1)
    elsif a.kind_of?(Float)
      Float(self) + a
    else
      x, y = a.coerce(self)
      x + y
    end
  end

  #
  # Returns the difference of this value and +a+.
  # subtracted.
  #
  # Examples:
  #   r = Rational(3,4)    # -> Rational(3,4)
  #   r - 1                # -> Rational(-1,4)
  #   r - 0.5              # -> 0.25
  #
  def - (a)
    if a.kind_of?(Rational)
      num = @numerator * a.denominator
      num_a = a.numerator * @denominator
      Rational(num - num_a, @denominator*a.denominator)
    elsif a.kind_of?(Integer)
      self - Rational.new!(a, 1)
    elsif a.kind_of?(Float)
      Float(self) - a
    else
      x, y = a.coerce(self)
      x - y
    end
  end

  #
  # Returns the product of this value and +a+.
  #
  # Examples:
  #   r = Rational(3,4)    # -> Rational(3,4)
  #   r * 2                # -> Rational(3,2)
  #   r * 4                # -> Rational(3,1)
  #   r * 0.5              # -> 0.375
  #   r * Rational(1,2)    # -> Rational(3,8)
  #
  def * (a)
    if a.kind_of?(Rational)
      num = @numerator * a.numerator
      den = @denominator * a.denominator
      Rational(num, den)
    elsif a.kind_of?(Integer)
      self * Rational.new!(a, 1)
    elsif a.kind_of?(Float)
      Float(self) * a
    else
      x, y = a.coerce(self)
      x * y
    end
  end

  #
  # Returns the quotient of this value and +a+.
  #   r = Rational(3,4)    # -> Rational(3,4)
  #   r / 2                # -> Rational(3,8)
  #   r / 2.0              # -> 0.375
  #   r / Rational(1,2)    # -> Rational(3,2)
  #
  def / (a)
    if a.kind_of?(Rational)
      num = @numerator * a.denominator
      den = @denominator * a.numerator
      Rational(num, den)
    elsif a.kind_of?(Integer)
      raise ZeroDivisionError, "division by zero" if a == 0
      self / Rational.new!(a, 1)
    elsif a.kind_of?(Float)
      Float(self) / a
    else
      x, y = a.coerce(self)
      x / y
    end
  end

  #
  # Returns this value raised to the given power.
  #
  # Examples:
  #   r = Rational(3,4)    # -> Rational(3,4)
  #   r ** 2               # -> Rational(9,16)
  #   r ** 2.0             # -> 0.5625
  #   r ** Rational(1,2)   # -> 0.866025403784439
  #
  def ** (other)
    if other.kind_of?(Rational)
      Float(self) ** other
    elsif other.kind_of?(Integer)
      if other > 0
	num = @numerator ** other
	den = @denominator ** other
      elsif other < 0
	num = @denominator ** -other
	den = @numerator ** -other
      elsif other == 0
	num = 1
	den = 1
      end
      Rational.new!(num, den)
    elsif other.kind_of?(Float)
      Float(self) ** other
    else
      x, y = other.coerce(self)
      x ** y
    end
  end

  def div(other)
    (self / other).floor
  end

  #
  # Returns the remainder when this value is divided by +other+.
  #
  # Examples:
  #   r = Rational(7,4)    # -> Rational(7,4)
  #   r % Rational(1,2)    # -> Rational(1,4)
  #   r % 1                # -> Rational(3,4)
  #   r % Rational(1,7)    # -> Rational(1,28)
  #   r % 0.26             # -> 0.19
  #
  def % (other)
    value = (self / other).floor
    return self - other * value
  end

  #
  # Returns the quotient _and_ remainder.
  #
  # Examples:
  #   r = Rational(7,4)        # -> Rational(7,4)
  #   r.divmod Rational(1,2)   # -> [3, Rational(1,4)]
  #
  def divmod(other)
    value = (self / other).floor
    return value, self - other * value
  end

  #
  # Returns the absolute value.
  #
  def abs
    if @numerator > 0
      self
    else
      Rational.new!(-@numerator, @denominator)
    end
  end

  #
  # Returns +true+ iff this value is numerically equal to +other+.
  #
  # But beware:
  #   Rational(1,2) == Rational(4,8)          # -> true
  #   Rational(1,2) == Rational.new!(4,8)     # -> false
  #
  # Don't use Rational.new!
  #
  def == (other)
    if other.kind_of?(Rational)
      @numerator == other.numerator and @denominator == other.denominator
    elsif other.kind_of?(Integer)
      self == Rational.new!(other, 1)
    elsif other.kind_of?(Float)
      Float(self) == other
    else
      other == self
    end
  end

  #
  # Standard comparison operator.
  #
  def <=> (other)
    if other.kind_of?(Rational)
      num = @numerator * other.denominator
      num_a = other.numerator * @denominator
      v = num - num_a
      if v > 0
	return 1
      elsif v < 0
	return  -1
      else
	return 0
      end
    elsif other.kind_of?(Integer)
      return self <=> Rational.new!(other, 1)
    elsif other.kind_of?(Float)
      return Float(self) <=> other
    elsif defined? other.coerce
      x, y = other.coerce(self)
      return x <=> y
    else
      return nil
    end
  end

  def coerce(other)
    if other.kind_of?(Float)
      return other, self.to_f
    elsif other.kind_of?(Integer)
      return Rational.new!(other, 1), self
    else
      super
    end
  end

  #
  # Converts the rational to an Integer.  Not the _nearest_ integer, the
  # truncated integer.  Study the following example carefully:
  #   Rational(+7,4).to_i             # -> 1
  #   Rational(-7,4).to_i             # -> -1
  #   (-1.75).to_i                    # -> -1
  #
  # In other words:
  #   Rational(-7,4) == -1.75                 # -> true
  #   Rational(-7,4).to_i == (-1.75).to_i     # -> true
  #


  def floor()
    @numerator.div(@denominator)
  end

  def ceil()
    -((-@numerator).div(@denominator))
  end

  def truncate()
    if @numerator < 0
      return -((-@numerator).div(@denominator))
    end
    @numerator.div(@denominator)
  end

  alias_method :to_i, :truncate

  def round()
    if @numerator < 0
      num = -@numerator
      num = num * 2 + @denominator
      den = @denominator * 2
      -(num.div(den))
    else
      num = @numerator * 2 + @denominator
      den = @denominator * 2
      num.div(den)
    end
  end

  #
  # Converts the rational to a Float.
  #
  def to_f
    @numerator.fdiv(@denominator)
  end

  #
  # Returns a string representation of the rational number.
  #
  # Example:
  #   Rational(3,4).to_s          #  "3/4"
  #   Rational(8).to_s            #  "8"
  #
  def to_s
    if @denominator == 1
      @numerator.to_s
    else
      @numerator.to_s+"/"+@denominator.to_s
    end
  end

  #
  # Returns +self+.
  #
  def to_r
    self
  end

  #
  # Returns a reconstructable string representation:
  #
  #   Rational(5,8).inspect     # -> "Rational(5, 8)"
  #
  def inspect
    sprintf("Rational(%s, %s)", @numerator.inspect, @denominator.inspect)
  end

  #
  # Returns a hash code for the object.
  #
  def hash
    @numerator.hash ^ @denominator.hash
  end

  attr :numerator
  attr :denominator

  private :initialize
end

class Integer
  #
  # In an integer, the value _is_ the numerator of its rational equivalent.
  # Therefore, this method returns +self+.
  #
  def numerator
    self
  end

  #
  # In an integer, the denominator is 1.  Therefore, this method returns 1.
  #
  def denominator
    1
  end

  #
  # Returns a Rational representation of this integer.
  #
  def to_r
    Rational(self, 1)
  end

  #
  # Returns the <em>greatest common denominator</em> of the two numbers (+self+
  # and +n+).
  #
  # Examples:
  #   72.gcd 168           # -> 24
  #   19.gcd 36            # -> 1
  #
  # The result is positive, no matter the sign of the arguments.
  #
  def gcd(other)
    min = self.abs
    max = other.abs
    while min > 0
      tmp = min
      min = max % min
      max = tmp
    end
    max
  end

  #
  # Returns the <em>lowest common multiple</em> (LCM) of the two arguments
  # (+self+ and +other+).
  #
  # Examples:
  #   6.lcm 7        # -> 42
  #   6.lcm 9        # -> 18
  #
  def lcm(other)
    if self.zero? or other.zero?
      0
    else
      (self.div(self.gcd(other)) * other).abs
    end
  end

  #
  # Returns the GCD _and_ the LCM (see #gcd and #lcm) of the two arguments
  # (+self+ and +other+).  This is more efficient than calculating them
  # separately.
  #
  # Example:
  #   6.gcdlcm 9     # -> [3, 18]
  #
  def gcdlcm(other)
    gcd = self.gcd(other)
    if self.zero? or other.zero?
      [gcd, 0]
    else
      [gcd, (self.div(gcd) * other).abs]
    end
  end
end

class Fixnum
  remove_method :quo

  # If Rational is defined, returns a Rational number instead of a Float.
  def quo(other)
    Rational.new!(self, 1) / other
  end
  alias rdiv quo

  # Returns a Rational number if the result is in fact rational (i.e. +other+ < 0).
  def rpower (other)
    if other >= 0
      self.power!(other)
    else
      Rational.new!(self, 1)**other
    end
  end

end

class Bignum
  remove_method :quo

  # If Rational is defined, returns a Rational number instead of a Float.
  def quo(other)
    Rational.new!(self, 1) / other
  end
  alias rdiv quo

  # Returns a Rational number if the result is in fact rational (i.e. +other+ < 0).
  def rpower (other)
    if other >= 0
      self.power!(other)
    else
      Rational.new!(self, 1)**other
    end
  end

end

unless defined? 1.power!
  class Fixnum
    alias power! **
    alias ** rpower
  end
  class Bignum
    alias power! **
    alias ** rpower
  end
end
PK     DZ\pgVq  q    drb/observer.rbnu [        require 'observer'

module DRb
  module DRbObservable
    include Observable

    def notify_observers(*arg)
      if defined? @observer_state and @observer_state
	if defined? @observer_peers
	  for i in @observer_peers.dup
	    begin
	      i.update(*arg)
	    rescue
	      delete_observer(i)
	    end
	  end
	end
	@observer_state = false
      end
    end
  end
end
PK     EZ\M}	  	    drb/unix.rbnu [        require 'socket'
require 'drb/drb'
require 'tmpdir'

raise(LoadError, "UNIXServer is required") unless defined?(UNIXServer)

module DRb

  class DRbUNIXSocket < DRbTCPSocket
    def self.parse_uri(uri)
      if /^drbunix:(.*?)(\?(.*))?$/ =~ uri 
	filename = $1
	option = $3
	[filename, option]
      else
	raise(DRbBadScheme, uri) unless uri =~ /^drbunix:/
	raise(DRbBadURI, 'can\'t parse uri:' + uri)
      end
    end

    def self.open(uri, config)
      filename, option = parse_uri(uri)
      filename.untaint
      soc = UNIXSocket.open(filename)
      self.new(uri, soc, config)
    end

    def self.open_server(uri, config)
      filename, option = parse_uri(uri)
      if filename.size == 0
	soc = temp_server
        filename = soc.path
	uri = 'drbunix:' + soc.path
      else
	soc = UNIXServer.open(filename)
      end
      owner = config[:UNIXFileOwner]
      group = config[:UNIXFileGroup]
      if owner || group
        require 'etc'
        owner = Etc.getpwnam( owner ).uid  if owner
        group = Etc.getgrnam( group ).gid  if group
        File.chown owner, group, filename
      end
      mode = config[:UNIXFileMode]
      File.chmod(mode, filename) if mode

      self.new(uri, soc, config, true)
    end

    def self.uri_option(uri, config)
      filename, option = parse_uri(uri)
      return "drbunix:#{filename}", option
    end

    def initialize(uri, soc, config={}, server_mode = false)
      super(uri, soc, config)
      set_sockopt(@socket)
      @server_mode = server_mode
      @acl = nil
    end
    
    # import from tempfile.rb
    Max_try = 10
    private
    def self.temp_server
      tmpdir = Dir::tmpdir
      n = 0
      while true
	begin
	  tmpname = sprintf('%s/druby%d.%d', tmpdir, $$, n)
	  lock = tmpname + '.lock'
	  unless File.exist?(tmpname) or File.exist?(lock)
	    Dir.mkdir(lock)
	    break
	  end
	rescue
	  raise "cannot generate tempfile `%s'" % tmpname if n >= Max_try
	  #sleep(1)
	end
	n += 1
      end
      soc = UNIXServer.new(tmpname)
      Dir.rmdir(lock)
      soc
    end

    public
    def close
      return unless @socket
      path = @socket.path if @server_mode
      @socket.close
      File.unlink(path) if @server_mode
      @socket = nil
    end

    def accept
      s = @socket.accept
      self.class.new(nil, s, @config)
    end

    def set_sockopt(soc)
      soc.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::FD_CLOEXEC
    end
  end

  DRbProtocol.add_protocol(DRbUNIXSocket)
end
PK     FZ\>2g  g    drb/extservm.rbnu [        =begin
 external service manager
 	Copyright (c) 2000 Masatoshi SEKI 
=end

require 'drb/drb'
require 'thread'
require 'monitor'

module DRb
  class ExtServManager
    include DRbUndumped
    include MonitorMixin

    @@command = {}

    def self.command
      @@command
    end

    def self.command=(cmd)
      @@command = cmd
    end
      
    def initialize
      super()
      @cond = new_cond
      @servers = {}
      @waiting = []
      @queue = Queue.new
      @thread = invoke_thread
      @uri = nil
    end
    attr_accessor :uri

    def service(name)
      synchronize do
        while true
          server = @servers[name]
          return server if server && server.alive?
          invoke_service(name)
          @cond.wait
        end
      end
    end

    def regist(name, ro)
      synchronize do
        @servers[name] = ro
        @cond.signal
      end
      self
    end
    
    def unregist(name)
      synchronize do
	@servers.delete(name)
      end
    end

    private
    def invoke_thread
      Thread.new do
	while true
	  name = @queue.pop
	  invoke_service_command(name, @@command[name])
	end
      end
    end

    def invoke_service(name)
      @queue.push(name)
    end

    def invoke_service_command(name, command)
      raise "invalid command. name: #{name}" unless command
      synchronize do
	return if @servers.include?(name)
	@servers[name] = false
      end
      uri = @uri || DRb.uri
      if RUBY_PLATFORM =~ /mswin32/ && /NT/ =~ ENV["OS"]
        system(%Q'cmd /c start "ruby" /b #{command} #{uri} #{name}')
      else
	system("#{command} #{uri} #{name} &")
      end
    end
  end
end
PK     FZ\$УS
  S
  
  drb/acl.rbnu [        # acl-2.0 - simple Access Control List
#
# Copyright (c) 2000,2002,2003 Masatoshi SEKI
#
# acl.rb is copyrighted free software by Masatoshi SEKI.
# You can redistribute it and/or modify it under the same terms as Ruby.

require 'ipaddr'

class ACL
  VERSION=["2.0.0"]
  class ACLEntry
    def initialize(str)
      if str == '*' or str == 'all'
	@pat = [:all]
      elsif str.include?('*')
        @pat = [:name, dot_pat(str)]
      else
	begin
	  @pat = [:ip, IPAddr.new(str)]
	rescue ArgumentError
	  @pat = [:name, dot_pat(str)]
	end
      end
    end

    private
    def dot_pat_str(str)
      list = str.split('.').collect { |s|
	(s == '*') ? '.+' : s
      }
      list.join("\\.")
    end

    private
    def dot_pat(str)
      exp = "^" + dot_pat_str(str) + "$"
      Regexp.new(exp)
    end

    public
    def match(addr)
      case @pat[0]
      when :all
	true
      when :ip
	begin
	  ipaddr = IPAddr.new(addr[3])
	  ipaddr = ipaddr.ipv4_mapped if @pat[1].ipv6? && ipaddr.ipv4?
	rescue ArgumentError
	  return false
	end
	(@pat[1].include?(ipaddr)) ? true : false
      when :name
	(@pat[1] =~ addr[2]) ? true : false
      else
	false
      end
    end
  end

  class ACLList
    def initialize
      @list = []
    end

    public
    def match(addr)
      @list.each do |e|
	return true if e.match(addr)
      end
      false
    end

    public
    def add(str)
      @list.push(ACLEntry.new(str))
    end
  end

  DENY_ALLOW = 0
  ALLOW_DENY = 1

  def initialize(list=nil, order = DENY_ALLOW)
    @order = order
    @deny = ACLList.new
    @allow = ACLList.new
    install_list(list) if list
  end

  public
  def allow_socket?(soc)
    allow_addr?(soc.peeraddr)
  end

  public
  def allow_addr?(addr)
    case @order
    when DENY_ALLOW
      return true if @allow.match(addr)
      return false if @deny.match(addr)
      return true
    when ALLOW_DENY
      return false if @deny.match(addr)
      return true if @allow.match(addr)
      return false
    else
      false
    end
  end

  public
  def install_list(list)
    i = 0
    while i < list.size
      permission, domain = list.slice(i,2)
      case permission.downcase
      when 'allow'
	@allow.add(domain)
      when 'deny'
	@deny.add(domain)
      else
	raise "Invalid ACL entry #{list.to_s}"
      end
      i += 2
    end
  end
end

if __FILE__ == $0
  # example
  list = %w(deny all
	    allow 192.168.1.1
            allow ::ffff:192.168.1.2
            allow 192.168.1.3
            )

  addr = ["AF_INET", 10, "lc630", "192.168.1.3"]

  acl = ACL.new
  p acl.allow_addr?(addr)

  acl = ACL.new(list, ACL::DENY_ALLOW)
  p acl.allow_addr?(addr)
end

PK     GZ\"      drb/timeridconv.rbnu [        require 'drb/drb'
require 'monitor'

module DRb
  class TimerIdConv < DRbIdConv
    class TimerHolder2
      include MonitorMixin

      class InvalidIndexError < RuntimeError; end

      def initialize(timeout=600)
	super()
	@sentinel = Object.new
	@gc = {}
	@curr = {}
	@renew = {}
	@timeout = timeout
	@keeper = keeper
      end

      def add(obj)
	synchronize do 
	  key = obj.__id__
	  @curr[key] = obj
	  return key
	end
      end

      def fetch(key, dv=@sentinel)
	synchronize do 
	  obj = peek(key)
	  if obj == @sentinel
	    return dv unless dv == @sentinel
	    raise InvalidIndexError
	  end
	  @renew[key] = obj # KeepIt
	  return obj
	end
      end

      def include?(key)
	synchronize do 
	  obj = peek(key)
	  return false if obj == @sentinel
	  true
	end
      end

      def peek(key)
	synchronize do 
	  return @curr.fetch(key, @renew.fetch(key, @gc.fetch(key, @sentinel)))
	end
      end

      private
      def alternate
	synchronize do
	  @gc = @curr       # GCed
	  @curr = @renew
	  @renew = {}
	end
      end

      def keeper
	Thread.new do
	  loop do
	    size = alternate
	    sleep(@timeout)
	  end
	end
      end
    end

    def initialize(timeout=600)
      @holder = TimerHolder2.new(timeout)
    end

    def to_obj(ref)
      return super if ref.nil?
      @holder.fetch(ref)
    rescue TimerHolder2::InvalidIndexError
      raise "invalid reference"
    end

    def to_id(obj)
      return @holder.add(obj)
    end
  end
end

# DRb.install_id_conv(TimerIdConv.new)
PK     GZ\vg'F      drb/invokemethod.rbnu [        # for ruby-1.8.0

module DRb
  class DRbServer
    module InvokeMethod18Mixin
      def block_yield(x)
	if x.size == 1 && x[0].class == Array
	  x[0] = DRbArray.new(x[0])
	end
        block_value = @block.call(*x)
      end
      
      def perform_with_block
        @obj.__send__(@msg_id, *@argv) do |*x|
          jump_error = nil
          begin
            block_value = block_yield(x)
          rescue LocalJumpError
            jump_error = $!
          end
          if jump_error
            case jump_error.reason
            when :retry
              retry
            when :break
              break(jump_error.exit_value)
            else
              raise jump_error
            end
          end
          block_value
        end
      end
    end
  end
end
PK     HZ\5s    
  drb/ssl.rbnu [        require 'socket'
require 'openssl'
require 'drb/drb'
require 'singleton'

module DRb

  class DRbSSLSocket < DRbTCPSocket

    class SSLConfig

      DEFAULT = {
	:SSLCertificate       => nil,
	:SSLPrivateKey        => nil,
	:SSLClientCA          => nil,
	:SSLCACertificatePath => nil,
	:SSLCACertificateFile => nil,
	:SSLVerifyMode        => ::OpenSSL::SSL::VERIFY_NONE, 
	:SSLVerifyDepth       => nil,
	:SSLVerifyCallback    => nil,   # custom verification
        :SSLCertificateStore  => nil,
	# Must specify if you use auto generated certificate.
	:SSLCertName          => nil,   # e.g. [["CN","fqdn.example.com"]]
	:SSLCertComment       => "Generated by Ruby/OpenSSL"
      }

      def initialize(config)
	@config  = config
        @cert    = config[:SSLCertificate]
        @pkey    = config[:SSLPrivateKey]
        @ssl_ctx = nil
      end

      def [](key); 
	@config[key] || DEFAULT[key]
      end

      def connect(tcp)
	ssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
	ssl.sync = true
	ssl.connect
	ssl
      end
      
      def accept(tcp)
	ssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
	ssl.sync = true
	ssl.accept
	ssl
      end
      
      def setup_certificate
        if @cert && @pkey
          return
        end

	rsa = OpenSSL::PKey::RSA.new(512){|p, n|
	  next unless self[:verbose]
	  case p
	  when 0; $stderr.putc "."  # BN_generate_prime
	  when 1; $stderr.putc "+"  # BN_generate_prime
	  when 2; $stderr.putc "*"  # searching good prime,
	                            # n = #of try,
                          	    # but also data from BN_generate_prime
	  when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
                         	    # but also data from BN_generate_prime
	  else;   $stderr.putc "*"  # BN_generate_prime
	  end
	}

	cert = OpenSSL::X509::Certificate.new
	cert.version = 3
	cert.serial = 0
	name = OpenSSL::X509::Name.new(self[:SSLCertName])
	cert.subject = name
	cert.issuer = name
	cert.not_before = Time.now
	cert.not_after = Time.now + (365*24*60*60)
	cert.public_key = rsa.public_key
	
	ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
	cert.extensions = [
	  ef.create_extension("basicConstraints","CA:FALSE"),
	  ef.create_extension("subjectKeyIdentifier", "hash") ]
	ef.issuer_certificate = cert
	cert.add_extension(ef.create_extension("authorityKeyIdentifier",
					       "keyid:always,issuer:always"))
	if comment = self[:SSLCertComment]
	  cert.add_extension(ef.create_extension("nsComment", comment))
	end
	cert.sign(rsa, OpenSSL::Digest::SHA1.new)
	
	@cert = cert
        @pkey = rsa
      end

      def setup_ssl_context
        ctx = ::OpenSSL::SSL::SSLContext.new
        ctx.cert            = @cert
        ctx.key             = @pkey
	ctx.client_ca       = self[:SSLClientCA]
	ctx.ca_path         = self[:SSLCACertificatePath]
	ctx.ca_file         = self[:SSLCACertificateFile]
	ctx.verify_mode     = self[:SSLVerifyMode]
	ctx.verify_depth    = self[:SSLVerifyDepth]
	ctx.verify_callback = self[:SSLVerifyCallback]
        ctx.cert_store      = self[:SSLCertificateStore]
        @ssl_ctx = ctx
      end
    end

    def self.parse_uri(uri)
      if uri =~ /^drbssl:\/\/(.*?):(\d+)(\?(.*))?$/
	host = $1
	port = $2.to_i
	option = $4
	[host, port, option]
      else
	raise(DRbBadScheme, uri) unless uri =~ /^drbssl:/
	raise(DRbBadURI, 'can\'t parse uri:' + uri)
      end
    end

    def self.open(uri, config)
      host, port, option = parse_uri(uri)
      host.untaint
      port.untaint
      soc = TCPSocket.open(host, port)
      ssl_conf = SSLConfig::new(config)
      ssl_conf.setup_ssl_context
      ssl = ssl_conf.connect(soc)
      self.new(uri, ssl, ssl_conf, true)
    end

    def self.open_server(uri, config)
      uri = 'drbssl://:0' unless uri
      host, port, opt = parse_uri(uri)
      if host.size == 0
        host = getservername
        soc = open_server_inaddr_any(host, port)
      else
	soc = TCPServer.open(host, port)
      end
      port = soc.addr[1] if port == 0
      @uri = "drbssl://#{host}:#{port}"
      
      ssl_conf = SSLConfig.new(config)
      ssl_conf.setup_certificate
      ssl_conf.setup_ssl_context
      self.new(@uri, soc, ssl_conf, false)
    end

    def self.uri_option(uri, config)
      host, port, option = parse_uri(uri)
      return "drbssl://#{host}:#{port}", option
    end

    def initialize(uri, soc, config, is_established)
      @ssl = is_established ? soc : nil
      super(uri, soc.to_io, config)
    end
    
    def stream; @ssl; end

    def close
      if @ssl
	@ssl.close
	@ssl = nil
      end
      super
    end
      
    def accept
      begin
      while true
	soc = @socket.accept
	break if (@acl ? @acl.allow_socket?(soc) : true) 
	soc.close
      end
      ssl = @config.accept(soc)
      self.class.new(uri, ssl, @config, true)
      rescue OpenSSL::SSL::SSLError
	warn("#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})") if @config[:verbose]
	retry
      end
    end
  end
  
  DRbProtocol.add_protocol(DRbSSLSocket)
end
PK     HZ\WJ    
  drb/drb.rbnu [        #
# = drb/drb.rb
#
# Distributed Ruby: _dRuby_ version 2.0.4
#
# Copyright (c) 1999-2003 Masatoshi SEKI.  You can redistribute it and/or
# modify it under the same terms as Ruby.
#
# Author:: Masatoshi SEKI
#
# Documentation:: William Webber (william@williamwebber.com)
#
# == Overview
#
# dRuby is a distributed object system for Ruby.  It allows an object in one
# Ruby process to invoke methods on an object in another Ruby process on the
# same or a different machine.
#
# The Ruby standard library contains the core classes of the dRuby package.
# However, the full package also includes access control lists and the
# Rinda tuple-space distributed task management system, as well as a 
# large number of samples.  The full dRuby package can be downloaded from
# the dRuby home page (see *References*).
#
# For an introduction and examples of usage see the documentation to the
# DRb module.
#
# == References
#
# [http://www2a.biglobe.ne.jp/~seki/ruby/druby.html]
#    The dRuby home page, in Japanese.  Contains the full dRuby package
#    and links to other Japanese-language sources.
#
# [http://www2a.biglobe.ne.jp/~seki/ruby/druby.en.html]
#    The English version of the dRuby home page.
#
# [http://www.chadfowler.com/ruby/drb.html]
#    A quick tutorial introduction to using dRuby by Chad Fowler.
#
# [http://www.linux-mag.com/2002-09/ruby_05.html]
#   A tutorial introduction to dRuby in Linux Magazine by Dave Thomas.
#   Includes a discussion of Rinda.
#
# [http://www.eng.cse.dmu.ac.uk/~hgs/ruby/dRuby/]
#   Links to English-language Ruby material collected by Hugh Sasse.
#
# [http://www.rubycentral.com/book/ospace.html]
#   The chapter from *Programming* *Ruby* by Dave Thomas and Andy Hunt
#   which discusses dRuby.
#
# [http://www.clio.ne.jp/home/web-i31s/Flotuard/Ruby/PRC2K_seki/dRuby.en.html]
#   Translation of presentation on Ruby by Masatoshi Seki.

require 'socket'
require 'thread'
require 'fcntl'
require 'drb/eq'

#
# == Overview
#
# dRuby is a distributed object system for Ruby.  It is written in
# pure Ruby and uses its own protocol.  No add-in services are needed
# beyond those provided by the Ruby runtime, such as TCP sockets.  It
# does not rely on or interoperate with other distributed object
# systems such as CORBA, RMI, or .NET.
#
# dRuby allows methods to be called in one Ruby process upon a Ruby
# object located in another Ruby process, even on another machine.
# References to objects can be passed between processes.  Method
# arguments and return values are dumped and loaded in marshalled
# format.  All of this is done transparently to both the caller of the
# remote method and the object that it is called upon.
#
# An object in a remote process is locally represented by a
# DRb::DRbObject instance.  This acts as a sort of proxy for the
# remote object.  Methods called upon this DRbObject instance are
# forwarded to its remote object.  This is arranged dynamically at run
# time.  There are no statically declared interfaces for remote
# objects, such as CORBA's IDL.
#
# dRuby calls made into a process are handled by a DRb::DRbServer
# instance within that process.  This reconstitutes the method call,
# invokes it upon the specified local object, and returns the value to
# the remote caller.  Any object can receive calls over dRuby.  There
# is no need to implement a special interface, or mixin special
# functionality.  Nor, in the general case, does an object need to
# explicitly register itself with a DRbServer in order to receive
# dRuby calls.
#
# One process wishing to make dRuby calls upon another process must
# somehow obtain an initial reference to an object in the remote
# process by some means other than as the return value of a remote
# method call, as there is initially no remote object reference it can
# invoke a method upon.  This is done by attaching to the server by
# URI.  Each DRbServer binds itself to a URI such as
# 'druby://example.com:8787'.  A DRbServer can have an object attached
# to it that acts as the server's *front* *object*.  A DRbObject can
# be explicitly created from the server's URI.  This DRbObject's
# remote object will be the server's front object.  This front object
# can then return references to other Ruby objects in the DRbServer's
# process.
#
# Method calls made over dRuby behave largely the same as normal Ruby
# method calls made within a process.  Method calls with blocks are
# supported, as are raising exceptions.  In addition to a method's
# standard errors, a dRuby call may also raise one of the
# dRuby-specific errors, all of which are subclasses of DRb::DRbError.
#
# Any type of object can be passed as an argument to a dRuby call or
# returned as its return value.  By default, such objects are dumped
# or marshalled at the local end, then loaded or unmarshalled at the
# remote end.  The remote end therefore receives a copy of the local
# object, not a distributed reference to it; methods invoked upon this
# copy are executed entirely in the remote process, not passed on to
# the local original.  This has semantics similar to pass-by-value.
#
# However, if an object cannot be marshalled, a dRuby reference to it
# is passed or returned instead.  This will turn up at the remote end
# as a DRbObject instance.  All methods invoked upon this remote proxy
# are forwarded to the local object, as described in the discussion of
# DRbObjects.  This has semantics similar to the normal Ruby
# pass-by-reference.
# 
# The easiest way to signal that we want an otherwise marshallable
# object to be passed or returned as a DRbObject reference, rather
# than marshalled and sent as a copy, is to include the
# DRb::DRbUndumped mixin module.
#
# dRuby supports calling remote methods with blocks.  As blocks (or
# rather the Proc objects that represent them) are not marshallable,
# the block executes in the local, not the remote, context.  Each
# value yielded to the block is passed from the remote object to the
# local block, then the value returned by each block invocation is
# passed back to the remote execution context to be collected, before
# the collected values are finally returned to the local context as
# the return value of the method invocation.
# 
# == Examples of usage
#
# For more dRuby samples, see the +samples+ directory in the full
# dRuby distribution.
#
# === dRuby in client/server mode
#
# This illustrates setting up a simple client-server drb
# system.  Run the server and client code in different terminals,
# starting the server code first.
#
# ==== Server code
#    
#   require 'drb/drb'
#     
#   # The URI for the server to connect to
#   URI="druby://localhost:8787" 
#     
#   class TimeServer
#     
#     def get_current_time
#       return Time.now
#     end
#     
#   end
#     
#   # The object that handles requests on the server
#   FRONT_OBJECT=TimeServer.new
#
#   $SAFE = 1   # disable eval() and friends
#   
#   DRb.start_service(URI, FRONT_OBJECT)
#   # Wait for the drb server thread to finish before exiting.
#   DRb.thread.join
#
# ==== Client code
#     
#   require 'drb/drb'
#   
#   # The URI to connect to
#   SERVER_URI="druby://localhost:8787"
#
#   # Start a local DRbServer to handle callbacks.
#   #
#   # Not necessary for this small example, but will be required
#   # as soon as we pass a non-marshallable object as an argument
#   # to a dRuby call.
#   DRb.start_service
#   
#   timeserver = DRbObject.new_with_uri(SERVER_URI)
#   puts timeserver.get_current_time 
#
# === Remote objects under dRuby
#
# This example illustrates returning a reference to an object
# from a dRuby call.  The Logger instances live in the server
# process.  References to them are returned to the client process,
# where methods can be invoked upon them.  These methods are 
# executed in the server process.
#
# ==== Server code
#   
#   require 'drb/drb'
#   
#   URI="druby://localhost:8787"
#   
#   class Logger
#
#       # Make dRuby send Logger instances as dRuby references,
#       # not copies.
#       include DRb::DRbUndumped
#   
#       def initialize(n, fname)
#           @name = n
#           @filename = fname
#       end
#   
#       def log(message)
#           File.open(@filename, "a") do |f|
#               f.puts("#{Time.now}: #{@name}: #{message}")
#           end
#       end
#   
#   end
#   
#   # We have a central object for creating and retrieving loggers.
#   # This retains a local reference to all loggers created.  This
#   # is so an existing logger can be looked up by name, but also
#   # to prevent loggers from being garbage collected.  A dRuby
#   # reference to an object is not sufficient to prevent it being
#   # garbage collected!
#   class LoggerFactory
#   
#       def initialize(bdir)
#           @basedir = bdir
#           @loggers = {}
#       end
#   
#       def get_logger(name)
#           if !@loggers.has_key? name
#               # make the filename safe, then declare it to be so
#               fname = name.gsub(/[.\/]/, "_").untaint
#               @loggers[name] = Logger.new(name, @basedir + "/" + fname)
#           end
#           return @loggers[name]
#       end
#   
#   end
#   
#   FRONT_OBJECT=LoggerFactory.new("/tmp/dlog")
#
#   $SAFE = 1   # disable eval() and friends
#   
#   DRb.start_service(URI, FRONT_OBJECT)
#   DRb.thread.join
#
# ==== Client code
#
#   require 'drb/drb'
#   
#   SERVER_URI="druby://localhost:8787"
#
#   DRb.start_service
#   
#   log_service=DRbObject.new_with_uri(SERVER_URI)
#   
#   ["loga", "logb", "logc"].each do |logname|
#   
#       logger=log_service.get_logger(logname)
#   
#       logger.log("Hello, world!")
#       logger.log("Goodbye, world!")
#       logger.log("=== EOT ===")
#   
#   end
#
# == Security
#
# As with all network services, security needs to be considered when
# using dRuby.  By allowing external access to a Ruby object, you are
# not only allowing outside clients to call the methods you have
# defined for that object, but by default to execute arbitrary Ruby
# code on your server.  Consider the following:
#
#    # !!! UNSAFE CODE !!!
#    ro = DRbObject::new_with_uri("druby://your.server.com:8989")
#    class << ro
#      undef :instance_eval  # force call to be passed to remote object
#    end
#    ro.instance_eval("`rm -rf *`")
#
# The dangers posed by instance_eval and friends are such that a
# DRbServer should generally be run with $SAFE set to at least 
# level 1.  This will disable eval() and related calls on strings 
# passed across the wire.  The sample usage code given above follows 
# this practice.
#
# A DRbServer can be configured with an access control list to
# selectively allow or deny access from specified IP addresses.  The
# main druby distribution provides the ACL class for this purpose.  In
# general, this mechanism should only be used alongside, rather than
# as a replacement for, a good firewall.
#
# == dRuby internals
#
# dRuby is implemented using three main components: a remote method
# call marshaller/unmarshaller; a transport protocol; and an
# ID-to-object mapper.  The latter two can be directly, and the first
# indirectly, replaced, in order to provide different behaviour and
# capabilities.
#
# Marshalling and unmarshalling of remote method calls is performed by
# a DRb::DRbMessage instance.  This uses the Marshal module to dump
# the method call before sending it over the transport layer, then
# reconstitute it at the other end.  There is normally no need to
# replace this component, and no direct way is provided to do so.
# However, it is possible to implement an alternative marshalling
# scheme as part of an implementation of the transport layer.
#
# The transport layer is responsible for opening client and server
# network connections and forwarding dRuby request across them.
# Normally, it uses DRb::DRbMessage internally to manage marshalling
# and unmarshalling.  The transport layer is managed by
# DRb::DRbProtocol.  Multiple protocols can be installed in
# DRbProtocol at the one time; selection between them is determined by
# the scheme of a dRuby URI.  The default transport protocol is
# selected by the scheme 'druby:', and implemented by
# DRb::DRbTCPSocket.  This uses plain TCP/IP sockets for
# communication.  An alternative protocol, using UNIX domain sockets,
# is implemented by DRb::DRbUNIXSocket in the file drb/unix.rb, and
# selected by the scheme 'drbunix:'.  A sample implementation over
# HTTP can be found in the samples accompanying the main dRuby
# distribution.
#
# The ID-to-object mapping component maps dRuby object ids to the
# objects they refer to, and vice versa.  The implementation to use
# can be specified as part of a DRb::DRbServer's configuration.  The
# default implementation is provided by DRb::DRbIdConv.  It uses an
# object's ObjectSpace id as its dRuby id.  This means that the dRuby
# reference to that object only remains meaningful for the lifetime of
# the object's process and the lifetime of the object within that
# process.  A modified implementation is provided by DRb::TimerIdConv
# in the file drb/timeridconv.rb.  This implementation retains a local
# reference to all objects exported over dRuby for a configurable
# period of time (defaulting to ten minutes), to prevent them being
# garbage-collected within this time.  Another sample implementation
# is provided in sample/name.rb in the main dRuby distribution.  This
# allows objects to specify their own id or "name".  A dRuby reference
# can be made persistent across processes by having each process
# register an object using the same dRuby name.
#
module DRb

  # Superclass of all errors raised in the DRb module.
  class DRbError < RuntimeError; end

  # Error raised when an error occurs on the underlying communication
  # protocol.
  class DRbConnError < DRbError; end

  # Class responsible for converting between an object and its id.
  #
  # This, the default implementation, uses an object's local ObjectSpace
  # __id__ as its id.  This means that an object's identification over
  # drb remains valid only while that object instance remains alive 
  # within the server runtime.
  #
  # For alternative mechanisms, see DRb::TimerIdConv in rdb/timeridconv.rb
  # and DRbNameIdConv in sample/name.rb in the full drb distribution.
  class DRbIdConv

    # Convert an object reference id to an object.
    #
    # This implementation looks up the reference id in the local object
    # space and returns the object it refers to.
    def to_obj(ref)
      ObjectSpace._id2ref(ref)
    end
    
    # Convert an object into a reference id.
    #
    # This implementation returns the object's __id__ in the local
    # object space.
    def to_id(obj)
      obj.nil? ? nil : obj.__id__
    end
  end

  # Mixin module making an object undumpable or unmarshallable.
  #
  # If an object which includes this module is returned by method
  # called over drb, then the object remains in the server space
  # and a reference to the object is returned, rather than the
  # object being marshalled and moved into the client space.
  module DRbUndumped 
    def _dump(dummy)  # :nodoc:
      raise TypeError, 'can\'t dump'
    end
  end

  # Error raised by the DRb module when an attempt is made to refer to
  # the context's current drb server but the context does not have one.
  # See #current_server.
  class DRbServerNotFound < DRbError; end

  # Error raised by the DRbProtocol module when it cannot find any
  # protocol implementation support the scheme specified in a URI.
  class DRbBadURI < DRbError; end

  # Error raised by a dRuby protocol when it doesn't support the
  # scheme specified in a URI.  See DRb::DRbProtocol.
  class DRbBadScheme < DRbError; end

  # An exception wrapping a DRb::DRbUnknown object
  class DRbUnknownError < DRbError

    # Create a new DRbUnknownError for the DRb::DRbUnknown object +unknown+
    def initialize(unknown)
      @unknown = unknown
      super(unknown.name)
    end

    # Get the wrapped DRb::DRbUnknown object.
    attr_reader :unknown

    def self._load(s)  # :nodoc:
      Marshal::load(s)
    end
    
    def _dump(lv) # :nodoc:
      Marshal::dump(@unknown)
    end
  end

  # An exception wrapping an error object
  class DRbRemoteError < DRbError
    def initialize(error)
      @reason = error.class.to_s
      super("#{error.message} (#{error.class})")
      set_backtrace(error.backtrace)
    end

    # the class of the error, as a string.
    attr_reader :reason
  end

  # Class wrapping a marshalled object whose type is unknown locally.
  #
  # If an object is returned by a method invoked over drb, but the
  # class of the object is unknown in the client namespace, or
  # the object is a constant unknown in the client namespace, then
  # the still-marshalled object is returned wrapped in a DRbUnknown instance.
  #
  # If this object is passed as an argument to a method invoked over
  # drb, then the wrapped object is passed instead.
  #
  # The class or constant name of the object can be read from the
  # +name+ attribute.  The marshalled object is held in the +buf+
  # attribute.
  class DRbUnknown
    
    # Create a new DRbUnknown object.
    #
    # +buf+ is a string containing a marshalled object that could not
    # be unmarshalled.  +err+ is the error message that was raised 
    # when the unmarshalling failed.  It is used to determine the
    # name of the unmarshalled object.
    def initialize(err, buf)
      case err.to_s
      when /uninitialized constant (\S+)/
	@name = $1
      when /undefined class\/module (\S+)/
	@name = $1
      else
	@name = nil
      end
      @buf = buf
    end

    # The name of the unknown thing.
    #
    # Class name for unknown objects; variable name for unknown
    # constants.
    attr_reader :name

    # Buffer contained the marshalled, unknown object.
    attr_reader :buf

    def self._load(s) # :nodoc:
      begin
	Marshal::load(s)
      rescue NameError, ArgumentError
	DRbUnknown.new($!, s)
      end
    end

    def _dump(lv) # :nodoc:
      @buf
    end

    # Attempt to load the wrapped marshalled object again.
    #
    # If the class of the object is now known locally, the object
    # will be unmarshalled and returned.  Otherwise, a new 
    # but identical DRbUnknown object will be returned.
    def reload
      self.class._load(@buf)
    end

    # Create a DRbUnknownError exception containing this object.
    def exception
      DRbUnknownError.new(self)
    end
  end

  class DRbArray
    def initialize(ary)
      @ary = ary.collect { |obj| 
	if obj.kind_of? DRbUndumped
	  DRbObject.new(obj)
	else
	  begin
	    Marshal.dump(obj)
	    obj
	  rescue
	    DRbObject.new(obj)
	  end
	end
      }
    end

    def self._load(s)
      Marshal::load(s)
    end

    def _dump(lv)
      Marshal.dump(@ary)
    end
  end

  # Handler for sending and receiving drb messages.
  #
  # This takes care of the low-level marshalling and unmarshalling
  # of drb requests and responses sent over the wire between server
  # and client.  This relieves the implementor of a new drb
  # protocol layer with having to deal with these details.
  #
  # The user does not have to directly deal with this object in
  # normal use.
  class DRbMessage
    def initialize(config) # :nodoc:
      @load_limit = config[:load_limit]
      @argc_limit = config[:argc_limit]
    end

    def dump(obj, error=false)  # :nodoc:
      obj = make_proxy(obj, error) if obj.kind_of? DRbUndumped
      begin
	str = Marshal::dump(obj)
      rescue
	str = Marshal::dump(make_proxy(obj, error))
      end
      [str.size].pack('N') + str
    end

    def load(soc)  # :nodoc:
      begin
        sz = soc.read(4)	# sizeof (N)
      rescue
        raise(DRbConnError, $!.message, $!.backtrace)
      end
      raise(DRbConnError, 'connection closed') if sz.nil?
      raise(DRbConnError, 'premature header') if sz.size < 4
      sz = sz.unpack('N')[0]
      raise(DRbConnError, "too large packet #{sz}") if @load_limit < sz
      begin
        str = soc.read(sz)
      rescue
        raise(DRbConnError, $!.message, $!.backtrace)
      end
      raise(DRbConnError, 'connection closed') if str.nil?
      raise(DRbConnError, 'premature marshal format(can\'t read)') if str.size < sz
      DRb.mutex.synchronize do
        begin
          save = Thread.current[:drb_untaint]
          Thread.current[:drb_untaint] = []
          Marshal::load(str)
        rescue NameError, ArgumentError
          DRbUnknown.new($!, str)
        ensure
          Thread.current[:drb_untaint].each do |x|
            x.untaint
          end
          Thread.current[:drb_untaint] = save
        end
      end
    end

    def send_request(stream, ref, msg_id, arg, b) # :nodoc:
      ary = []
      ary.push(dump(ref.__drbref))
      ary.push(dump(msg_id.id2name))
      ary.push(dump(arg.length))
      arg.each do |e|
	ary.push(dump(e))
      end
      ary.push(dump(b))
      stream.write(ary.join(''))
    rescue
      raise(DRbConnError, $!.message, $!.backtrace)
    end
    
    def recv_request(stream) # :nodoc:
      ref = load(stream)
      ro = DRb.to_obj(ref)
      msg = load(stream)
      argc = load(stream)
      raise ArgumentError, 'too many arguments' if @argc_limit < argc
      argv = Array.new(argc, nil)
      argc.times do |n|
	argv[n] = load(stream)
      end
      block = load(stream)
      return ro, msg, argv, block
    end

    def send_reply(stream, succ, result)  # :nodoc:
      stream.write(dump(succ) + dump(result, !succ))
    rescue
      raise(DRbConnError, $!.message, $!.backtrace)
    end

    def recv_reply(stream)  # :nodoc:
      succ = load(stream)
      result = load(stream)
      [succ, result]
    end

    private
    def make_proxy(obj, error=false)
      if error
        DRbRemoteError.new(obj)
      else
        DRbObject.new(obj)
      end
    end
  end

  # Module managing the underlying network protocol(s) used by drb.
  #
  # By default, drb uses the DRbTCPSocket protocol.  Other protocols
  # can be defined.  A protocol must define the following class methods:
  #
  #   [open(uri, config)] Open a client connection to the server at +uri+,
  #                       using configuration +config+.  Return a protocol
  #                       instance for this connection.
  #   [open_server(uri, config)] Open a server listening at +uri+,
  #                              using configuration +config+.  Return a
  #                              protocol instance for this listener.
  #   [uri_option(uri, config)] Take a URI, possibly containing an option
  #                             component (e.g. a trailing '?param=val'), 
  #                             and return a [uri, option] tuple.
  #
  # All of these methods should raise a DRbBadScheme error if the URI 
  # does not identify the protocol they support (e.g. "druby:" for
  # the standard Ruby protocol).  This is how the DRbProtocol module,
  # given a URI, determines which protocol implementation serves that
  # protocol.
  #
  # The protocol instance returned by #open_server must have the
  # following methods:
  #
  # [accept] Accept a new connection to the server.  Returns a protocol
  #          instance capable of communicating with the client.
  # [close] Close the server connection.
  # [uri] Get the URI for this server.
  #
  # The protocol instance returned by #open must have the following methods:
  #
  # [send_request (ref, msg_id, arg, b)] 
  #      Send a request to +ref+ with the given message id and arguments.
  #      This is most easily implemented by calling DRbMessage.send_request,
  #      providing a stream that sits on top of the current protocol.
  # [recv_reply]
  #      Receive a reply from the server and return it as a [success-boolean,
  #      reply-value] pair.  This is most easily implemented by calling
  #      DRb.recv_reply, providing a stream that sits on top of the 
  #      current protocol.
  # [alive?]
  #      Is this connection still alive?
  # [close]
  #      Close this connection.
  #
  # The protocol instance returned by #open_server().accept() must have
  # the following methods:
  #
  # [recv_request]
  #     Receive a request from the client and return a [object, message,
  #     args, block] tuple.  This is most easily implemented by calling
  #     DRbMessage.recv_request, providing a stream that sits on top of
  #     the current protocol.
  # [send_reply(succ, result)]
  #     Send a reply to the client.  This is most easily implemented
  #     by calling DRbMessage.send_reply, providing a stream that sits
  #     on top of the current protocol.
  # [close]
  #     Close this connection.
  #
  # A new protocol is registered with the DRbProtocol module using
  # the add_protocol method.
  #
  # For examples of other protocols, see DRbUNIXSocket in drb/unix.rb,
  # and HTTP0 in sample/http0.rb and sample/http0serv.rb in the full
  # drb distribution.
  module DRbProtocol

    # Add a new protocol to the DRbProtocol module.
    def add_protocol(prot)
      @protocol.push(prot)
    end
    module_function :add_protocol

    # Open a client connection to +uri+ with the configuration +config+.
    #
    # The DRbProtocol module asks each registered protocol in turn to
    # try to open the URI.  Each protocol signals that it does not handle that
    # URI by raising a DRbBadScheme error.  If no protocol recognises the
    # URI, then a DRbBadURI error is raised.  If a protocol accepts the
    # URI, but an error occurs in opening it, a DRbConnError is raised.
    def open(uri, config, first=true) 
      @protocol.each do |prot|
	begin
	  return prot.open(uri, config)
	rescue DRbBadScheme
	rescue DRbConnError
	  raise($!)
	rescue
	  raise(DRbConnError, "#{uri} - #{$!.inspect}")
	end
      end
      if first && (config[:auto_load] != false)
	auto_load(uri, config)
	return open(uri, config, false)
      end
      raise DRbBadURI, 'can\'t parse uri:' + uri
    end
    module_function :open

    # Open a server listening for connections at +uri+ with 
    # configuration +config+.
    #
    # The DRbProtocol module asks each registered protocol in turn to
    # try to open a server at the URI.  Each protocol signals that it does 
    # not handle that URI by raising a DRbBadScheme error.  If no protocol 
    # recognises the URI, then a DRbBadURI error is raised.  If a protocol 
    # accepts the URI, but an error occurs in opening it, the underlying 
    # error is passed on to the caller.
    def open_server(uri, config, first=true)
      @protocol.each do |prot|
	begin
	  return prot.open_server(uri, config)
	rescue DRbBadScheme
	end
      end
      if first && (config[:auto_load] != false)
	auto_load(uri, config)
	return open_server(uri, config, false)
      end
      raise DRbBadURI, 'can\'t parse uri:' + uri
    end
    module_function :open_server

    # Parse +uri+ into a [uri, option] pair.
    #
    # The DRbProtocol module asks each registered protocol in turn to
    # try to parse the URI.  Each protocol signals that it does not handle that
    # URI by raising a DRbBadScheme error.  If no protocol recognises the
    # URI, then a DRbBadURI error is raised.  
    def uri_option(uri, config, first=true)
      @protocol.each do |prot|
	begin
	  uri, opt = prot.uri_option(uri, config)
	  # opt = nil if opt == ''
	  return uri, opt
	rescue DRbBadScheme
	end
      end
      if first && (config[:auto_load] != false)
	auto_load(uri, config)
        return uri_option(uri, config, false)
      end
      raise DRbBadURI, 'can\'t parse uri:' + uri
    end
    module_function :uri_option

    def auto_load(uri, config)  # :nodoc:
      if uri =~ /^drb([a-z0-9]+):/
	require("drb/#{$1}") rescue nil
      end
    end
    module_function :auto_load
  end

  # The default drb protocol.
  #
  # Communicates over a TCP socket.
  class DRbTCPSocket
    private
    def self.parse_uri(uri)
      if uri =~ /^druby:\/\/(.*?):(\d+)(\?(.*))?$/
	host = $1
	port = $2.to_i
	option = $4
	[host, port, option]
      else
	raise(DRbBadScheme, uri) unless uri =~ /^druby:/
	raise(DRbBadURI, 'can\'t parse uri:' + uri)
      end
    end

    public

    # Open a client connection to +uri+ using configuration +config+.
    def self.open(uri, config)
      host, port, option = parse_uri(uri)
      host.untaint
      port.untaint
      soc = TCPSocket.open(host, port)
      self.new(uri, soc, config)
    end

    def self.getservername
      host = Socket::gethostname
      begin
        Socket::gethostbyname(host)[0]
      rescue
        'localhost'
      end
    end

    def self.open_server_inaddr_any(host, port)
      infos = Socket::getaddrinfo(host, nil, 
                                  Socket::AF_UNSPEC,
                                  Socket::SOCK_STREAM, 
                                  0,
                                  Socket::AI_PASSIVE)
      families = Hash[*infos.collect { |af, *_| af }.uniq.zip([]).flatten]
      return TCPServer.open('0.0.0.0', port) if families.has_key?('AF_INET')
      return TCPServer.open('::', port) if families.has_key?('AF_INET6')
      return TCPServer.open(port)
    end

    # Open a server listening for connections at +uri+ using 
    # configuration +config+.
    def self.open_server(uri, config)
      uri = 'druby://:0' unless uri
      host, port, opt = parse_uri(uri)
      config = {:tcp_original_host => host}.update(config)
      if host.size == 0
        host = getservername
        soc = open_server_inaddr_any(host, port)
      else
	soc = TCPServer.open(host, port)
      end
      port = soc.addr[1] if port == 0
      config[:tcp_port] = port
      uri = "druby://#{host}:#{port}"
      self.new(uri, soc, config)
    end

    # Parse +uri+ into a [uri, option] pair.
    def self.uri_option(uri, config)
      host, port, option = parse_uri(uri)
      return "druby://#{host}:#{port}", option
    end

    # Create a new DRbTCPSocket instance.
    #
    # +uri+ is the URI we are connected to.
    # +soc+ is the tcp socket we are bound to.  +config+ is our
    # configuration.
    def initialize(uri, soc, config={})
      @uri = uri
      @socket = soc
      @config = config
      @acl = config[:tcp_acl]
      @msg = DRbMessage.new(config)
      set_sockopt(@socket)
    end

    # Get the URI that we are connected to.
    attr_reader :uri

    # Get the address of our TCP peer (the other end of the socket
    # we are bound to.
    def peeraddr
      @socket.peeraddr
    end
    
    # Get the socket.
    def stream; @socket; end

    # On the client side, send a request to the server.
    def send_request(ref, msg_id, arg, b)
      @msg.send_request(stream, ref, msg_id, arg, b)
    end
    
    # On the server side, receive a request from the client.
    def recv_request
      @msg.recv_request(stream)
    end

    # On the server side, send a reply to the client.
    def send_reply(succ, result)
      @msg.send_reply(stream, succ, result)
    end

    # On the client side, receive a reply from the server.
    def recv_reply
      @msg.recv_reply(stream)
    end

    public

    # Close the connection.
    #
    # If this is an instance returned by #open_server, then this stops
    # listening for new connections altogether.  If this is an instance
    # returned by #open or by #accept, then it closes this particular
    # client-server session.
    def close
      if @socket
	@socket.close
	@socket = nil
      end
    end
    
    # On the server side, for an instance returned by #open_server, 
    # accept a client connection and return a new instance to handle
    # the server's side of this client-server session.
    def accept
      while true
	s = @socket.accept
	break if (@acl ? @acl.allow_socket?(s) : true) 
	s.close
      end
      if @config[:tcp_original_host].to_s.size == 0
        uri = "druby://#{s.addr[3]}:#{@config[:tcp_port]}"
      else
        uri = @uri
      end
      self.class.new(uri, s, @config)
    end

    # Check to see if this connection is alive.
    def alive?
      return false unless @socket
      if IO.select([@socket], nil, nil, 0)
	close
	return false
      end
      true
    end

    def set_sockopt(soc) # :nodoc:
      soc.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
      soc.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::FD_CLOEXEC
    end
  end

  module DRbProtocol
    @protocol = [DRbTCPSocket] # default
  end

  class DRbURIOption  # :nodoc:  I don't understand the purpose of this class...
    def initialize(option)
      @option = option.to_s
    end
    attr :option
    def to_s; @option; end
    
    def ==(other)
      return false unless DRbURIOption === other
      @option == other.option
    end
    
    def hash
      @option.hash
    end
    
    alias eql? ==
  end

  # Object wrapping a reference to a remote drb object.
  #
  # Method calls on this object are relayed to the remote
  # object that this object is a stub for.
  class DRbObject

    # Unmarshall a marshalled DRbObject.
    #
    # If the referenced object is located within the local server, then
    # the object itself is returned.  Otherwise, a new DRbObject is
    # created to act as a stub for the remote referenced object.
    def self._load(s)
      uri, ref = Marshal.load(s)
      
      if DRb.here?(uri)
	obj = DRb.to_obj(ref)
        if ((! obj.tainted?) && Thread.current[:drb_untaint])
          Thread.current[:drb_untaint].push(obj)
        end
        return obj
      end

      self.new_with(uri, ref)
    end

    def self.new_with(uri, ref)
      it = self.allocate
      it.instance_variable_set('@uri', uri)
      it.instance_variable_set('@ref', ref)
      it
    end

    # Create a new DRbObject from a URI alone.
    def self.new_with_uri(uri)
      self.new(nil, uri)
    end

    # Marshall this object.
    #
    # The URI and ref of the object are marshalled.
    def _dump(lv)
      Marshal.dump([@uri, @ref])
    end

    # Create a new remote object stub.
    #
    # +obj+ is the (local) object we want to create a stub for.  Normally
    # this is +nil+.  +uri+ is the URI of the remote object that this
    # will be a stub for.
    def initialize(obj, uri=nil)
      @uri = nil
      @ref = nil
      if obj.nil?
	return if uri.nil?
	@uri, option = DRbProtocol.uri_option(uri, DRb.config)
	@ref = DRbURIOption.new(option) unless option.nil?
      else
	@uri = uri ? uri : (DRb.uri rescue nil)
	@ref = obj ? DRb.to_id(obj) : nil
      end
    end

    # Get the URI of the remote object.
    def __drburi 
      @uri
    end

    # Get the reference of the object, if local.
    def __drbref
      @ref
    end

    undef :to_s
    undef :to_a if respond_to?(:to_a)

    def respond_to?(msg_id, priv=false)
      case msg_id
      when :_dump
        true
      when :marshal_dump
        false
      else
        method_missing(:respond_to?, msg_id, priv)
      end
    end

    # Routes method calls to the referenced object.
    def method_missing(msg_id, *a, &b)
      if DRb.here?(@uri)
	obj = DRb.to_obj(@ref)
	DRb.current_server.check_insecure_method(obj, msg_id)
	return obj.__send__(msg_id, *a, &b) 
      end

      succ, result = self.class.with_friend(@uri) do
        DRbConn.open(@uri) do |conn|
          conn.send_message(self, msg_id, a, b)
        end
      end

      if succ
        return result
      elsif DRbUnknown === result
        raise result
      else
        bt = self.class.prepare_backtrace(@uri, result)
	result.set_backtrace(bt + caller)
        raise result
      end
    end

    def self.with_friend(uri)
      friend = DRb.fetch_server(uri)
      return yield() unless friend
      
      save = Thread.current['DRb']
      Thread.current['DRb'] = { 'server' => friend }
      return yield
    ensure
      Thread.current['DRb'] = save if friend
    end

    def self.prepare_backtrace(uri, result)
      prefix = "(#{uri}) "
      bt = []
      result.backtrace.each do |x|
        break if /`__send__'$/ =~ x 
        if /^\(druby:\/\// =~ x
          bt.push(x)
        else
          bt.push(prefix + x)
        end
      end
      bt
    end

    def pretty_print(q)   # :nodoc:
      q.pp_object(self)
    end

    def pretty_print_cycle(q)   # :nodoc:
      q.object_address_group(self) {
        q.breakable
        q.text '...'
      }
    end
  end

  # Class handling the connection between a DRbObject and the
  # server the real object lives on.
  #
  # This class maintains a pool of connections, to reduce the
  # overhead of starting and closing down connections for each
  # method call.
  #
  # This class is used internally by DRbObject.  The user does
  # not normally need to deal with it directly.
  class DRbConn
    POOL_SIZE = 16  # :nodoc:
    @mutex = Mutex.new
    @pool = []

    def self.open(remote_uri)  # :nodoc:
      begin
	conn = nil

	@mutex.synchronize do
	  #FIXME
	  new_pool = []
	  @pool.each do |c|
	    if conn.nil? and c.uri == remote_uri
	      conn = c if c.alive?
	    else
	      new_pool.push c
	    end
	  end
	  @pool = new_pool
	end

	conn = self.new(remote_uri) unless conn
	succ, result = yield(conn)
	return succ, result

      ensure
	if conn
	  if succ
	    @mutex.synchronize do
	      @pool.unshift(conn)
	      @pool.pop.close while @pool.size > POOL_SIZE
	    end
	  else
	    conn.close
	  end
	end
      end
    end

    def initialize(remote_uri)  # :nodoc:
      @uri = remote_uri
      @protocol = DRbProtocol.open(remote_uri, DRb.config)
    end
    attr_reader :uri  # :nodoc:

    def send_message(ref, msg_id, arg, block)  # :nodoc:
      @protocol.send_request(ref, msg_id, arg, block)
      @protocol.recv_reply
    end

    def close  # :nodoc:
      @protocol.close
      @protocol = nil
    end

    def alive?  # :nodoc:
      return false unless @protocol
      @protocol.alive?
    end
  end

  # Class representing a drb server instance.
  #
  # A DRbServer must be running in the local process before any incoming
  # dRuby calls can be accepted, or any local objects can be passed as
  # dRuby references to remote processes, even if those local objects are
  # never actually called remotely. You do not need to start a DRbServer
  # in the local process if you are only making outgoing dRuby calls
  # passing marshalled parameters.
  #
  # Unless multiple servers are being used, the local DRbServer is normally
  # started by calling DRb.start_service.
  class DRbServer
    @@acl = nil
    @@idconv = DRbIdConv.new
    @@secondary_server = nil
    @@argc_limit = 256
    @@load_limit = 256 * 102400
    @@verbose = false
    @@safe_level = 0

    # Set the default value for the :argc_limit option.
    #
    # See #new().  The initial default value is 256.
    def self.default_argc_limit(argc)
      @@argc_limit = argc
    end

    # Set the default value for the :load_limit option.
    #
    # See #new().  The initial default value is 25 MB.
    def self.default_load_limit(sz)
      @@load_limit = sz
    end

    # Set the default value for the :acl option.
    #
    # See #new().  The initial default value is nil.
    def self.default_acl(acl)
      @@acl = acl
    end

    # Set the default value for the :id_conv option.
    #
    # See #new().  The initial default value is a DRbIdConv instance.
    def self.default_id_conv(idconv)
      @@idconv = idconv
    end

    def self.default_safe_level(level)
      @@safe_level = level
    end

    # Set the default value of the :verbose option.
    #
    # See #new().  The initial default value is false.
    def self.verbose=(on)
      @@verbose = on
    end
    
    # Get the default value of the :verbose option.
    def self.verbose
      @@verbose
    end

    def self.make_config(hash={})  # :nodoc:
      default_config = { 
	:idconv => @@idconv,
	:verbose => @@verbose,
	:tcp_acl => @@acl,
	:load_limit => @@load_limit,
	:argc_limit => @@argc_limit,
        :safe_level => @@safe_level
      }
      default_config.update(hash)
    end

    # Create a new DRbServer instance.
    #
    # +uri+ is the URI to bind to.  This is normally of the form
    # 'druby://<hostname>:<port>' where <hostname> is a hostname of
    # the local machine.  If nil, then the system's default hostname
    # will be bound to, on a port selected by the system; these value
    # can be retrieved from the +uri+ attribute.  'druby:' specifies
    # the default dRuby transport protocol: another protocol, such
    # as 'drbunix:', can be specified instead.
    #
    # +front+ is the front object for the server, that is, the object
    # to which remote method calls on the server will be passed.  If
    # nil, then the server will not accept remote method calls.
    #
    # If +config_or_acl+ is a hash, it is the configuration to
    # use for this server.  The following options are recognised:
    #
    # :idconv :: an id-to-object conversion object.  This defaults
    #            to an instance of the class DRb::DRbIdConv.
    # :verbose :: if true, all unsuccessful remote calls on objects
    #             in the server will be logged to $stdout. false
    #             by default.
    # :tcp_acl :: the access control list for this server.  See
    #             the ACL class from the main dRuby distribution.
    # :load_limit :: the maximum message size in bytes accepted by
    #                the server.  Defaults to 25 MB (26214400).
    # :argc_limit :: the maximum number of arguments to a remote
    #                method accepted by the server.  Defaults to
    #                256.
    #
    # The default values of these options can be modified on
    # a class-wide basis by the class methods #default_argc_limit,
    # #default_load_limit, #default_acl, #default_id_conv,
    # and #verbose=
    #
    # If +config_or_acl+ is not a hash, but is not nil, it is
    # assumed to be the access control list for this server.
    # See the :tcp_acl option for more details.
    #
    # If no other server is currently set as the primary server,
    # this will become the primary server.
    #
    # The server will immediately start running in its own thread.
    def initialize(uri=nil, front=nil, config_or_acl=nil)
      if Hash === config_or_acl
	config = config_or_acl.dup
      else
	acl = config_or_acl || @@acl
	config = {
	  :tcp_acl => acl
	}
      end

      @config = self.class.make_config(config)

      @protocol = DRbProtocol.open_server(uri, @config)
      @uri = @protocol.uri

      @front = front
      @idconv = @config[:idconv]
      @safe_level = @config[:safe_level]

      @grp = ThreadGroup.new
      @thread = run

      DRb.regist_server(self)
    end

    # The URI of this DRbServer.
    attr_reader :uri

    # The main thread of this DRbServer.
    #
    # This is the thread that listens for and accepts connections
    # from clients, not that handles each client's request-response
    # session.
    attr_reader :thread

    # The front object of the DRbServer.
    # 
    # This object receives remote method calls made on the server's
    # URI alone, with an object id.
    attr_reader :front

    # The configuration of this DRbServer
    attr_reader :config

    attr_reader :safe_level

    # Set whether to operate in verbose mode.
    #
    # In verbose mode, failed calls are logged to stdout.
    def verbose=(v); @config[:verbose]=v; end

    # Get whether the server is in verbose mode.
    #
    # In verbose mode, failed calls are logged to stdout.
    def verbose; @config[:verbose]; end

    # Is this server alive?
    def alive?
      @thread.alive?
    end

    # Stop this server.
    def stop_service
      DRb.remove_server(self)
      if  Thread.current['DRb'] && Thread.current['DRb']['server'] == self
        Thread.current['DRb']['stop_service'] = true
      else
        @thread.kill
      end
    end

    # Convert a dRuby reference to the local object it refers to.
    def to_obj(ref)
      return front if ref.nil?
      return front[ref.to_s] if DRbURIOption === ref
      @idconv.to_obj(ref)
    end

    # Convert a local object to a dRuby reference.
    def to_id(obj)
      return nil if obj.__id__ == front.__id__
      @idconv.to_id(obj)
    end

    private
    def kill_sub_thread
      Thread.new do
	grp = ThreadGroup.new
	grp.add(Thread.current)
	list = @grp.list
	while list.size > 0
	  list.each do |th|
	    th.kill if th.alive?
	  end
	  list = @grp.list
	end
      end
    end

    def run
      Thread.start do
	begin
	  while true
	    main_loop
	  end
	ensure
	  @protocol.close if @protocol
	  kill_sub_thread
	end
      end
    end

    # List of insecure methods.
    #
    # These methods are not callable via dRuby.
    INSECURE_METHOD = [
      :__send__
    ]

    # Has a method been included in the list of insecure methods?
    def insecure_method?(msg_id)
      INSECURE_METHOD.include?(msg_id)
    end

    # Coerce an object to a string, providing our own representation if
    # to_s is not defined for the object.
    def any_to_s(obj)
      obj.to_s + ":#{obj.class}"
    rescue
      sprintf("#<%s:0x%lx>", obj.class, obj.__id__)      
    end

    # Check that a method is callable via dRuby.
    #
    # +obj+ is the object we want to invoke the method on. +msg_id+ is the
    # method name, as a Symbol.
    #
    # If the method is an insecure method (see #insecure_method?) a 
    # SecurityError is thrown.  If the method is private or undefined,
    # a NameError is thrown.
    def check_insecure_method(obj, msg_id)
      return true if Proc === obj && msg_id == :__drb_yield
      raise(ArgumentError, "#{any_to_s(msg_id)} is not a symbol") unless Symbol == msg_id.class
      raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(msg_id)
      
      if obj.private_methods.include?(msg_id.to_s)
	desc = any_to_s(obj)
        raise NoMethodError, "private method `#{msg_id}' called for #{desc}"
      elsif obj.protected_methods.include?(msg_id.to_s)
	desc = any_to_s(obj)
        raise NoMethodError, "protected method `#{msg_id}' called for #{desc}"
      else
        true
      end
    end
    public :check_insecure_method
    
    class InvokeMethod  # :nodoc:
      def initialize(drb_server, client)
	@drb_server = drb_server
        @safe_level = drb_server.safe_level
	@client = client
      end

      def perform
	@result = nil
	@succ = false
	setup_message

        if $SAFE < @safe_level
          info = Thread.current['DRb']
          if @block
            @result = Thread.new {
              Thread.current['DRb'] = info
              $SAFE = @safe_level
              perform_with_block
            }.value
          else
            @result = Thread.new { 
              Thread.current['DRb'] = info
              $SAFE = @safe_level
              perform_without_block
            }.value
          end
        else
          if @block
            @result = perform_with_block
          else
            @result = perform_without_block
          end
        end
	@succ = true
	if @msg_id == :to_ary && @result.class == Array
	  @result = DRbArray.new(@result) 
	end
	return @succ, @result
      rescue StandardError, ScriptError, Interrupt
	@result = $!
	return @succ, @result
      end

      private
      def init_with_client
	obj, msg, argv, block = @client.recv_request
        @obj = obj
        @msg_id = msg.intern
        @argv = argv
        @block = block
      end
      
      def check_insecure_method
        @drb_server.check_insecure_method(@obj, @msg_id)
      end

      def setup_message
	init_with_client
	check_insecure_method
      end
      
      def perform_without_block
	if Proc === @obj && @msg_id == :__drb_yield
          if @argv.size == 1
	    ary = @argv
	  else
	    ary = [@argv]
	  end
	  ary.collect(&@obj)[0]
	else
	  @obj.__send__(@msg_id, *@argv)
	end
      end

    end

    if RUBY_VERSION >= '1.8'
      require 'drb/invokemethod'
      class InvokeMethod
        include InvokeMethod18Mixin
      end
    else
      require 'drb/invokemethod16'
      class InvokeMethod
        include InvokeMethod16Mixin
      end
    end

    # The main loop performed by a DRbServer's internal thread.
    #
    # Accepts a connection from a client, and starts up its own
    # thread to handle it.  This thread loops, receiving requests
    # from the client, invoking them on a local object, and
    # returning responses, until the client closes the connection
    # or a local method call fails.
    def main_loop
      Thread.start(@protocol.accept) do |client|
	@grp.add Thread.current
	Thread.current['DRb'] = { 'client' => client ,
	                          'server' => self }
	loop do
	  begin
	    succ = false
	    invoke_method = InvokeMethod.new(self, client)
	    succ, result = invoke_method.perform
	    if !succ && verbose
	      p result
	      result.backtrace.each do |x|
		puts x
	      end
	    end
	    client.send_reply(succ, result) rescue nil
	  ensure
            client.close unless succ
            if Thread.current['DRb']['stop_service']
              Thread.new { stop_service }
            end
            break unless succ
	  end
	end
      end
    end
  end

  @primary_server = nil

  # Start a dRuby server locally.
  #
  # The new dRuby server will become the primary server, even
  # if another server is currently the primary server.
  #
  # +uri+ is the URI for the server to bind to.  If nil,
  # the server will bind to random port on the default local host
  # name and use the default dRuby protocol.
  #
  # +front+ is the server's front object.  This may be nil.
  #
  # +config+ is the configuration for the new server.  This may
  # be nil.
  #
  # See DRbServer::new.
  def start_service(uri=nil, front=nil, config=nil)
    @primary_server = DRbServer.new(uri, front, config)
  end
  module_function :start_service

  # The primary local dRuby server.
  #
  # This is the server created by the #start_service call.  
  attr_accessor :primary_server
  module_function :primary_server=, :primary_server

  # Get the 'current' server.
  #
  # In the context of execution taking place within the main
  # thread of a dRuby server (typically, as a result of a remote
  # call on the server or one of its objects), the current
  # server is that server.  Otherwise, the current server is
  # the primary server.
  #
  # If the above rule fails to find a server, a DRbServerNotFound
  # error is raised.
  def current_server
    drb = Thread.current['DRb'] 
    server = (drb && drb['server']) ? drb['server'] : @primary_server 
    raise DRbServerNotFound unless server
    return server
  end
  module_function :current_server

  # Stop the local dRuby server.
  #
  # This operates on the primary server.  If there is no primary
  # server currently running, it is a noop.
  def stop_service
    @primary_server.stop_service if @primary_server
    @primary_server = nil
  end
  module_function :stop_service

  # Get the URI defining the local dRuby space.
  #
  # This is the URI of the current server.  See #current_server.
  def uri
    drb = Thread.current['DRb']
    client = (drb && drb['client'])
    if client
      uri = client.uri
      return uri if uri
    end
    current_server.uri
  end
  module_function :uri

  # Is +uri+ the URI for the current local server?
  def here?(uri)
    (current_server.uri rescue nil) == uri
  end
  module_function :here?

  # Get the configuration of the current server.
  #
  # If there is no current server, this returns the default configuration.
  # See #current_server and DRbServer::make_config.
  def config
    current_server.config
  rescue
    DRbServer.make_config
  end
  module_function :config
  
  # Get the front object of the current server.
  #
  # This raises a DRbServerNotFound error if there is no current server.
  # See #current_server.
  def front
    current_server.front
  end
  module_function :front

  # Convert a reference into an object using the current server.
  #
  # This raises a DRbServerNotFound error if there is no current server.
  # See #current_server.
  def to_obj(ref)
    current_server.to_obj(ref)
  end

  # Get a reference id for an object using the current server.
  #
  # This raises a DRbServerNotFound error if there is no current server.
  # See #current_server.
  def to_id(obj)
    current_server.to_id(obj)
  end
  module_function :to_id
  module_function :to_obj

  # Get the thread of the primary server.
  #
  # This returns nil if there is no primary server.  See #primary_server.
  def thread
    @primary_server ? @primary_server.thread : nil
  end
  module_function :thread

  # Set the default id conv object.
  #
  # See DRbServer#default_id_conv.
  def install_id_conv(idconv)
    DRbServer.default_id_conv(idconv)
  end
  module_function :install_id_conv

  # Set the default acl.
  #
  # See DRb::DRbServer.default_acl.
  def install_acl(acl)
    DRbServer.default_acl(acl)
  end
  module_function :install_acl

  @mutex = Mutex.new
  def mutex
    @mutex
  end
  module_function :mutex

  @server = {}
  def regist_server(server)
    @server[server.uri] = server
    mutex.synchronize do
      @primary_server = server unless @primary_server
    end
  end
  module_function :regist_server

  def remove_server(server)
    @server.delete(server.uri)
  end
  module_function :remove_server
  
  def fetch_server(uri)
    @server[uri]
  end
  module_function :fetch_server
end

DRbObject = DRb::DRbObject
DRbUndumped = DRb::DRbUndumped
DRbIdConv = DRb::DRbIdConv
PK     IZ\܉̕      	  drb/eq.rbnu [        require 'drb/drb'

module DRb
  class DRbObject
    def ==(other)
      return false unless DRbObject === other
     (@ref == other.__drbref) && (@uri == other.__drburi)
    end

    def hash
      [@uri, @ref].hash
    end

    alias eql? ==
  end
end
PK     IZ\j    	  drb/gw.rbnu [        require 'drb/drb'
require 'monitor'

module DRb
  class GWIdConv < DRbIdConv
    def to_obj(ref)
      if Array === ref && ref[0] == :DRbObject
        return DRbObject.new_with(ref[1], ref[2])
      end
      super(ref)
    end
  end

  class GW
    include MonitorMixin
    def initialize
      super()
      @hash = {}
    end

    def [](key)
      synchronize do
        @hash[key]
      end
    end

    def []=(key, v)
      synchronize do
        @hash[key] = v
      end
    end
  end

  class DRbObject
    def self._load(s)
      uri, ref = Marshal.load(s)
      if DRb.uri == uri
        return ref ? DRb.to_obj(ref) : DRb.front
      end

      self.new_with(DRb.uri, [:DRbObject, uri, ref])
    end

    def _dump(lv)
      if DRb.uri == @uri
        if Array === @ref && @ref[0] == :DRbObject
          Marshal.dump([@ref[1], @ref[2]])
        else
          Marshal.dump([@uri, @ref]) # ??
        end
      else
        Marshal.dump([DRb.uri, [:DRbObject, @uri, @ref]])
      end
    end
  end
end

=begin
DRb.install_id_conv(DRb::GWIdConv.new)

front = DRb::GW.new

s1 = DRb::DRbServer.new('drbunix:/tmp/gw_b_a', front)
s2 = DRb::DRbServer.new('drbunix:/tmp/gw_b_c', front)

s1.thread.join
s2.thread.join
=end

=begin
# foo.rb

require 'drb/drb'

class Foo
  include DRbUndumped
  def initialize(name, peer=nil)
    @name = name
    @peer = peer
  end

  def ping(obj)
    puts "#{@name}: ping: #{obj.inspect}"
    @peer.ping(self) if @peer
  end
end
=end

=begin
# gw_a.rb
require 'drb/unix'
require 'foo'

obj = Foo.new('a')
DRb.start_service("drbunix:/tmp/gw_a", obj)

robj = DRbObject.new_with_uri('drbunix:/tmp/gw_b_a')
robj[:a] = obj

DRb.thread.join
=end

=begin
# gw_c.rb
require 'drb/unix'
require 'foo'

foo = Foo.new('c', nil)

DRb.start_service("drbunix:/tmp/gw_c", nil)

robj = DRbObject.new_with_uri("drbunix:/tmp/gw_b_c")

puts "c->b"
a = robj[:a]
sleep 2

a.ping(foo)

DRb.thread.join
=end

PK     IZ\+6{9  9    drb/extserv.rbnu [        =begin
 external service
 	Copyright (c) 2000,2002 Masatoshi SEKI 
=end

require 'drb/drb'

module DRb
  class ExtServ
    include DRbUndumped

    def initialize(there, name, server=nil)
      @server = server || DRb::primary_server
      @name = name
      ro = DRbObject.new(nil, there)
      @invoker = ro.regist(name, DRbObject.new(self, @server.uri))
    end
    attr_reader :server

    def front
      DRbObject.new(nil, @server.uri)
    end

    def stop_service
      @invoker.unregist(@name)
      server = @server
      @server = nil
      server.stop_service
      true
    end

    def alive?
      @server ? @server.alive? : false
    end
  end
end

if __FILE__ == $0
  class Foo
    include DRbUndumped

    def initialize(str)
      @str = str
    end

    def hello(it)
      "#{it}: #{self}"
    end

    def to_s
      @str
    end
  end

  cmd = ARGV.shift
  case cmd
  when 'itest1', 'itest2'
    front = Foo.new(cmd)
    manager = DRb::DRbServer.new(nil, front)
    es = DRb::ExtServ.new(ARGV.shift, ARGV.shift, manager)
    es.server.thread.join
  end
end

PK     JZ\P EE  E    cgi/session.rbnu [        #
# cgi/session.rb - session support for cgi scripts
#
# Copyright (C) 2001  Yukihiro "Matz" Matsumoto
# Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
# Copyright (C) 2000  Information-technology Promotion Agency, Japan
#
# Author: Yukihiro "Matz" Matsumoto
#
# Documentation: William Webber (william@williamwebber.com)
#
# == Overview
#
# This file provides the +CGI::Session+ class, which provides session
# support for CGI scripts.  A session is a sequence of HTTP requests
# and responses linked together and associated with a single client.  
# Information associated with the session is stored
# on the server between requests.  A session id is passed between client
# and server with every request and response, transparently
# to the user.  This adds state information to the otherwise stateless
# HTTP request/response protocol.
#
# See the documentation to the +CGI::Session+ class for more details
# and examples of usage.  See cgi.rb for the +CGI+ class itself.

require 'cgi'
require 'tmpdir'

class CGI

  # Class representing an HTTP session.  See documentation for the file 
  # cgi/session.rb for an introduction to HTTP sessions.
  #
  # == Lifecycle
  #
  # A CGI::Session instance is created from a CGI object.  By default,
  # this CGI::Session instance will start a new session if none currently
  # exists, or continue the current session for this client if one does
  # exist.  The +new_session+ option can be used to either always or
  # never create a new session.  See #new() for more details.
  #
  # #delete() deletes a session from session storage.  It
  # does not however remove the session id from the client.  If the client
  # makes another request with the same id, the effect will be to start
  # a new session with the old session's id.
  #
  # == Setting and retrieving session data.
  #
  # The Session class associates data with a session as key-value pairs.
  # This data can be set and retrieved by indexing the Session instance 
  # using '[]', much the same as hashes (although other hash methods
  # are not supported).
  #
  # When session processing has been completed for a request, the
  # session should be closed using the close() method.  This will
  # store the session's state to persistent storage.  If you want
  # to store the session's state to persistent storage without
  # finishing session processing for this request, call the update()
  # method.
  #
  # == Storing session state
  #
  # The caller can specify what form of storage to use for the session's 
  # data with the +database_manager+ option to CGI::Session::new.  The
  # following storage classes are provided as part of the standard library:
  #
  # CGI::Session::FileStore:: stores data as plain text in a flat file.  Only 
  #                           works with String data.  This is the default 
  #                           storage type.
  # CGI::Session::MemoryStore:: stores data in an in-memory hash.  The data 
  #                             only persists for as long as the current ruby 
  #                             interpreter instance does.
  # CGI::Session::PStore:: stores data in Marshalled format.  Provided by
  #                        cgi/session/pstore.rb.  Supports data of any type, 
  #                        and provides file-locking and transaction support.
  #
  # Custom storage types can also be created by defining a class with 
  # the following methods:
  #
  #    new(session, options)
  #    restore  # returns hash of session data.
  #    update
  #    close
  #    delete
  #
  # Changing storage type mid-session does not work.  Note in particular
  # that by default the FileStore and PStore session data files have the
  # same name.  If your application switches from one to the other without
  # making sure that filenames will be different
  # and clients still have old sessions lying around in cookies, then
  # things will break nastily!
  #
  # == Maintaining the session id.
  #
  # Most session state is maintained on the server.  However, a session
  # id must be passed backwards and forwards between client and server
  # to maintain a reference to this session state.
  #
  # The simplest way to do this is via cookies.  The CGI::Session class
  # provides transparent support for session id communication via cookies
  # if the client has cookies enabled.
  # 
  # If the client has cookies disabled, the session id must be included
  # as a parameter of all requests sent by the client to the server.  The
  # CGI::Session class in conjunction with the CGI class will transparently
  # add the session id as a hidden input field to all forms generated
  # using the CGI#form() HTML generation method.  No built-in support is
  # provided for other mechanisms, such as URL re-writing.  The caller is
  # responsible for extracting the session id from the session_id 
  # attribute and manually encoding it in URLs and adding it as a hidden
  # input to HTML forms created by other mechanisms.  Also, session expiry
  # is not automatically handled.
  #
  # == Examples of use
  #
  # === Setting the user's name
  #
  #   require 'cgi'
  #   require 'cgi/session'
  #   require 'cgi/session/pstore'     # provides CGI::Session::PStore
  #
  #   cgi = CGI.new("html4")
  #
  #   session = CGI::Session.new(cgi,
  #       'database_manager' => CGI::Session::PStore,  # use PStore
  #       'session_key' => '_rb_sess_id',              # custom session key
  #       'session_expires' => Time.now + 30 * 60,     # 30 minute timeout 
  #       'prefix' => 'pstore_sid_')                   # PStore option
  #   if cgi.has_key?('user_name') and cgi['user_name'] != ''
  #       # coerce to String: cgi[] returns the 
  #       # string-like CGI::QueryExtension::Value
  #       session['user_name'] = cgi['user_name'].to_s
  #   elsif !session['user_name']
  #       session['user_name'] = "guest"
  #   end
  #   session.close
  #
  # === Creating a new session safely
  #
  #   require 'cgi'
  #   require 'cgi/session'
  #
  #   cgi = CGI.new("html4")
  #
  #   # We make sure to delete an old session if one exists,
  #   # not just to free resources, but to prevent the session 
  #   # from being maliciously hijacked later on.
  #   begin
  #       session = CGI::Session.new(cgi, 'new_session' => false)      
  #       session.delete                 
  #   rescue ArgumentError  # if no old session
  #   end
  #   session = CGI::Session.new(cgi, 'new_session' => true)
  #   session.close
  #
  class Session

    class NoSession < RuntimeError #:nodoc:
    end

    # The id of this session.
    attr_reader :session_id, :new_session

    def Session::callback(dbman)  #:nodoc:
      Proc.new{
	dbman[0].close unless dbman.empty?
      }
    end

    # Create a new session id.
    #
    # The session id is an MD5 hash based upon the time,
    # a random number, and a constant string.  This routine
    # is used internally for automatically generated
    # session ids. 
    def create_new_id
      require 'securerandom'
      begin
        session_id = SecureRandom.hex(16)
      rescue NotImplementedError
        require 'digest/md5'
        md5 = Digest::MD5::new
        now = Time::now
        md5.update(now.to_s)
        md5.update(String(now.usec))
        md5.update(String(rand(0)))
        md5.update(String($$))
        md5.update('foobar')
        session_id = md5.hexdigest
      end
      session_id
    end
    private :create_new_id

    # Create a new CGI::Session object for +request+.
    #
    # +request+ is an instance of the +CGI+ class (see cgi.rb).
    # +option+ is a hash of options for initialising this
    # CGI::Session instance.  The following options are
    # recognised:
    #
    # session_key:: the parameter name used for the session id.
    #               Defaults to '_session_id'.
    # session_id:: the session id to use.  If not provided, then
    #              it is retrieved from the +session_key+ parameter
    #              of the request, or automatically generated for
    #              a new session.
    # new_session:: if true, force creation of a new session.  If not set, 
    #               a new session is only created if none currently
    #               exists.  If false, a new session is never created,
    #               and if none currently exists and the +session_id+
    #               option is not set, an ArgumentError is raised.
    # database_manager:: the name of the class providing storage facilities
    #                    for session state persistence.  Built-in support
    #                    is provided for +FileStore+ (the default),
    #                    +MemoryStore+, and +PStore+ (from
    #                    cgi/session/pstore.rb).  See the documentation for
    #                    these classes for more details.
    #
    # The following options are also recognised, but only apply if the
    # session id is stored in a cookie.
    #
    # session_expires:: the time the current session expires, as a 
    #                   +Time+ object.  If not set, the session will terminate
    #                   when the user's browser is closed.
    # session_domain:: the hostname domain for which this session is valid.
    #                  If not set, defaults to the hostname of the server.
    # session_secure:: if +true+, this session will only work over HTTPS.
    # session_path:: the path for which this session applies.  Defaults
    #                to the directory of the CGI script.
    #
    # +option+ is also passed on to the session storage class initializer; see
    # the documentation for each session storage class for the options
    # they support.
    #                  
    # The retrieved or created session is automatically added to +request+
    # as a cookie, and also to its +output_hidden+ table, which is used
    # to add hidden input elements to forms.  
    #
    # *WARNING* the +output_hidden+
    # fields are surrounded by a <fieldset> tag in HTML 4 generation, which
    # is _not_ invisible on many browsers; you may wish to disable the
    # use of fieldsets with code similar to the following
    # (see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/37805)
    #
    #   cgi = CGI.new("html4")
    #   class << cgi
    #       undef_method :fieldset
    #   end
    #
    def initialize(request, option={})
      @new_session = false
      session_key = option['session_key'] || '_session_id'
      session_id = option['session_id']
      unless session_id
	if option['new_session']
	  session_id = create_new_id
      @new_session = true
	end
      end
      unless session_id
	if request.key?(session_key)
	  session_id = request[session_key]
	  session_id = session_id.read if session_id.respond_to?(:read)
	end
	unless session_id
	  session_id, = request.cookies[session_key]
	end
	unless session_id
	  unless option.fetch('new_session', true)
	    raise ArgumentError, "session_key `%s' should be supplied"%session_key
	  end
	  session_id = create_new_id
      @new_session = true
	end
      end
      @session_id = session_id
      dbman = option['database_manager'] || FileStore
      begin
        @dbman = dbman::new(self, option)
      rescue NoSession
        unless option.fetch('new_session', true)
          raise ArgumentError, "invalid session_id `%s'"%session_id
        end
        session_id = @session_id = create_new_id unless session_id
      @new_session = true
        retry
      end
      request.instance_eval do
	@output_hidden = {session_key => session_id} unless option['no_hidden']
	@output_cookies =  [
          Cookie::new("name" => session_key,
		      "value" => session_id,
		      "expires" => option['session_expires'],
		      "domain" => option['session_domain'],
		      "secure" => option['session_secure'],
		      "path" => if option['session_path'] then
				  option['session_path']
		                elsif ENV["SCRIPT_NAME"] then
				  File::dirname(ENV["SCRIPT_NAME"])
				else
				  ""
				end)
        ] unless option['no_cookies']
      end
      @dbprot = [@dbman]
      ObjectSpace::define_finalizer(self, Session::callback(@dbprot))
    end

    # Retrieve the session data for key +key+.
    def [](key)
      @data ||= @dbman.restore
      @data[key]
    end

    # Set the session date for key +key+.
    def []=(key, val)
      @write_lock ||= true
      @data ||= @dbman.restore
      @data[key] = val
    end

    # Store session data on the server.  For some session storage types,
    # this is a no-op.
    def update  
      @dbman.update
    end

    # Store session data on the server and close the session storage.  
    # For some session storage types, this is a no-op.
    def close
      @dbman.close
      @dbprot.clear
    end

    # Delete the session from storage.  Also closes the storage.
    #
    # Note that the session's data is _not_ automatically deleted
    # upon the session expiring.
    def delete
      @dbman.delete
      @dbprot.clear
    end

    # File-based session storage class.
    #
    # Implements session storage as a flat file of 'key=value' values.
    # This storage type only works directly with String values; the
    # user is responsible for converting other types to Strings when
    # storing and from Strings when retrieving.
    class FileStore
      # Create a new FileStore instance.
      #
      # This constructor is used internally by CGI::Session.  The
      # user does not generally need to call it directly.
      #
      # +session+ is the session for which this instance is being
      # created.  The session id must only contain alphanumeric
      # characters; automatically generated session ids observe
      # this requirement.
      # 
      # +option+ is a hash of options for the initializer.  The
      # following options are recognised:
      #
      # tmpdir:: the directory to use for storing the FileStore
      #          file.  Defaults to Dir::tmpdir (generally "/tmp"
      #          on Unix systems).
      # prefix:: the prefix to add to the session id when generating
      #          the filename for this session's FileStore file.
      #          Defaults to the empty string.
      # suffix:: the prefix to add to the session id when generating
      #          the filename for this session's FileStore file.
      #          Defaults to the empty string.
      #
      # This session's FileStore file will be created if it does
      # not exist, or opened if it does.
      def initialize(session, option={})
	dir = option['tmpdir'] || Dir::tmpdir
	prefix = option['prefix'] || ''
	suffix = option['suffix'] || ''
	id = session.session_id
        require 'digest/md5'
        md5 = Digest::MD5.hexdigest(id)[0,16]
	@path = dir+"/"+prefix+md5+suffix
	if File::exist? @path
	  @hash = nil
	else
          unless session.new_session
            raise CGI::Session::NoSession, "uninitialized session"
          end
	  @hash = {}
	end
      end

      # Restore session state from the session's FileStore file.
      #
      # Returns the session state as a hash.
      def restore
	unless @hash
	  @hash = {}
          begin
            lockf = File.open(@path+".lock", "r")
            lockf.flock File::LOCK_SH
	    f = File.open(@path, 'r')
	    for line in f
	      line.chomp!
	      k, v = line.split('=',2)
	      @hash[CGI::unescape(k)] = CGI::unescape(v)
	    end
          ensure
	    f.close unless f.nil?
            lockf.close if lockf
          end
	end
	@hash
      end

      # Save session state to the session's FileStore file.
      def update
	return unless @hash
        begin
          lockf = File.open(@path+".lock", File::CREAT|File::RDWR, 0600)
	  lockf.flock File::LOCK_EX
          f = File.open(@path+".new", File::CREAT|File::TRUNC|File::WRONLY, 0600)
   	  for k,v in @hash
	    f.printf "%s=%s\n", CGI::escape(k), CGI::escape(String(v))
	  end
          f.close
          File.rename @path+".new", @path
        ensure
          f.close if f and !f.closed?
          lockf.close if lockf
        end
      end

      # Update and close the session's FileStore file.
      def close
	update
      end

      # Close and delete the session's FileStore file.
      def delete
        File::unlink @path+".lock" rescue nil
        File::unlink @path+".new" rescue nil
        File::unlink @path
      rescue Errno::ENOENT
      end
    end

    # In-memory session storage class.
    #
    # Implements session storage as a global in-memory hash.  Session
    # data will only persist for as long as the ruby interpreter 
    # instance does.
    class MemoryStore
      GLOBAL_HASH_TABLE = {} #:nodoc:

      # Create a new MemoryStore instance.
      #
      # +session+ is the session this instance is associated with.
      # +option+ is a list of initialisation options.  None are
      # currently recognised.
      def initialize(session, option=nil)
	@session_id = session.session_id
        unless GLOBAL_HASH_TABLE.key?(@session_id)
          unless session.new_session
            raise CGI::Session::NoSession, "uninitialized session"
          end
          GLOBAL_HASH_TABLE[@session_id] = {}
        end
      end

      # Restore session state.
      #
      # Returns session data as a hash.
      def restore
	GLOBAL_HASH_TABLE[@session_id]
      end

      # Update session state.
      #
      # A no-op.
      def update
	# don't need to update; hash is shared
      end

      # Close session storage.
      #
      # A no-op.
      def close
	# don't need to close
      end

      # Delete the session state.
      def delete
	GLOBAL_HASH_TABLE.delete(@session_id)
      end
    end
  end
end
PK     KZ\T#p4  4    cgi/session/pstore.rbnu [        #
# cgi/session/pstore.rb - persistent storage of marshalled session data
#
# Documentation: William Webber (william@williamwebber.com)
# 
# == Overview
#
# This file provides the CGI::Session::PStore class, which builds
# persistent of session data on top of the pstore library.  See
# cgi/session.rb for more details on session storage managers.

require 'cgi/session'
require 'pstore'

class CGI
  class Session
    # PStore-based session storage class.
    #
    # This builds upon the top-level PStore class provided by the
    # library file pstore.rb.  Session data is marshalled and stored
    # in a file.  File locking and transaction services are provided.
    class PStore
      # Create a new CGI::Session::PStore instance
      #
      # This constructor is used internally by CGI::Session.  The
      # user does not generally need to call it directly.
      #
      # +session+ is the session for which this instance is being
      # created.  The session id must only contain alphanumeric
      # characters; automatically generated session ids observe
      # this requirement.
      # 
      # +option+ is a hash of options for the initializer.  The
      # following options are recognised:
      #
      # tmpdir:: the directory to use for storing the PStore
      #          file.  Defaults to Dir::tmpdir (generally "/tmp"
      #          on Unix systems).
      # prefix:: the prefix to add to the session id when generating
      #          the filename for this session's PStore file.
      #          Defaults to the empty string.
      #
      # This session's PStore file will be created if it does
      # not exist, or opened if it does.
      def initialize(session, option={})
	dir = option['tmpdir'] || Dir::tmpdir
	prefix = option['prefix'] || ''
	id = session.session_id
        require 'digest/md5'
        md5 = Digest::MD5.hexdigest(id)[0,16]
	path = dir+"/"+prefix+md5
	path.untaint
	if File::exist?(path)
	  @hash = nil
	else
          unless session.new_session
            raise CGI::Session::NoSession, "uninitialized session"
          end
	  @hash = {}
	end
	@p = ::PStore.new(path)
	@p.transaction do |p|
	  File.chmod(0600, p.path)
	end
      end

      # Restore session state from the session's PStore file.
      #
      # Returns the session state as a hash.
      def restore
	unless @hash
	  @p.transaction do
           @hash = @p['hash'] || {}
	  end
	end
	@hash
      end

      # Save session state to the session's PStore file.
      def update 
	@p.transaction do
	    @p['hash'] = @hash
	end
      end

      # Update and close the session's PStore file.
      def close
	update
      end

      # Close and delete the session's PStore file.
      def delete
	path = @p.path
	File::unlink path
      end

    end
  end
end

if $0 == __FILE__
  # :enddoc:
  STDIN.reopen("/dev/null")
  cgi = CGI.new
  session = CGI::Session.new(cgi, 'database_manager' => CGI::Session::PStore)
  session['key'] = {'k' => 'v'}
  puts session['key'].class
  fail unless Hash === session['key']
  puts session['key'].inspect
  fail unless session['key'].inspect == '{"k"=>"v"}'
end
PK     KZ\Ј      bigdecimal/newton.rbnu [        #
# newton.rb 
#
# Solves the nonlinear algebraic equation system f = 0 by Newton's method.
# This program is not dependent on BigDecimal.
#
# To call:
#    n = nlsolve(f,x)
#  where n is the number of iterations required,
#        x is the initial value vector
#        f is an Object which is used to compute the values of the equations to be solved.
# It must provide the following methods:
#
# f.values(x):: returns the values of all functions at x
#
# f.zero:: returns 0.0
# f.one:: returns 1.0
# f.two:: returns 1.0
# f.ten:: returns 10.0
#
# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.
#
# On exit, x is the solution vector.
#
require "bigdecimal/ludcmp"
require "bigdecimal/jacobian"

module Newton
  include LUSolve
  include Jacobian
  
  def norm(fv,zero=0.0)
    s = zero
    n = fv.size
    for i in 0...n do
      s += fv[i]*fv[i]
    end
    s
  end

  def nlsolve(f,x)
    nRetry = 0
    n = x.size

    f0 = f.values(x)
    zero = f.zero
    one  = f.one
    two  = f.two
    p5 = one/two
    d  = norm(f0,zero)
    minfact = f.ten*f.ten*f.ten
    minfact = one/minfact
    e = f.eps
    while d >= e do
      nRetry += 1
      # Not yet converged. => Compute Jacobian matrix
      dfdx = jacobian(f,f0,x)
      # Solve dfdx*dx = -f0 to estimate dx
      dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero)
      fact = two
      xs = x.dup
      begin
        fact *= p5
        if fact < minfact then
          raise "Failed to reduce function values."
        end
        for i in 0...n do
          x[i] = xs[i] - dx[i]*fact
        end
        f0 = f.values(x)
        dn = norm(f0,zero)
      end while(dn>=d)
      d = dn
    end
    nRetry
  end
end
PK     LZ\!      bigdecimal/util.rbnu [        #
# BigDecimal utility library.
#
# To use these functions, require 'bigdecimal/util'
#
# The following methods are provided to convert other types to BigDecimals:
#
#   String#to_d -> BigDecimal
#   Float#to_d -> BigDecimal
#   Rational#to_d -> BigDecimal
#
# The following method is provided to convert BigDecimals to other types:
#
#   BigDecimal#to_r -> Rational
#
# ----------------------------------------------------------------------
#
class Float < Numeric
  def to_d
    BigDecimal(self.to_s)
  end
end

class String
  def to_d
    BigDecimal(self)
  end
end

class BigDecimal < Numeric
  # Converts a BigDecimal to a String of the form "nnnnnn.mmm".
  # This method is deprecated; use BigDecimal#to_s("F") instead.
  def to_digits
     if self.nan? || self.infinite? || self.zero?
        self.to_s
     else
       i       = self.to_i.to_s
       s,f,y,z = self.frac.split
       i + "." + ("0"*(-z)) + f
     end
  end

  # Converts a BigDecimal to a Rational.
  def to_r 
     sign,digits,base,power = self.split
     numerator = sign*digits.to_i
     denomi_power = power - digits.size # base is always 10
     if denomi_power < 0
        Rational(numerator,base ** (-denomi_power))
     else
        Rational(numerator * (base ** denomi_power),1)
     end
  end
end

class Rational < Numeric
  # Converts a Rational to a BigDecimal
  def to_d(nFig=0)
     num = self.numerator.to_s
     if nFig<=0
        nFig = BigDecimal.double_fig*2+1
     end
     BigDecimal.new(num).div(self.denominator,nFig)
  end
end
PK     LZ\:O  O    bigdecimal/ludcmp.rbnu [        #
# Solves a*x = b for x, using LU decomposition.
#
module LUSolve
  # Performs LU decomposition of the n by n matrix a.
  def ludecomp(a,n,zero=0,one=1)
    prec = BigDecimal.limit(nil)
    ps     = []
    scales = []
    for i in 0...n do  # pick up largest(abs. val.) element in each row.
      ps <<= i
      nrmrow  = zero
      ixn = i*n
      for j in 0...n do
         biggst = a[ixn+j].abs
         nrmrow = biggst if biggst>nrmrow
      end
      if nrmrow>zero then
         scales <<= one.div(nrmrow,prec)
      else 
         raise "Singular matrix"
      end
    end
    n1          = n - 1
    for k in 0...n1 do # Gaussian elimination with partial pivoting.
      biggst  = zero;
      for i in k...n do
         size = a[ps[i]*n+k].abs*scales[ps[i]]
         if size>biggst then
            biggst = size
            pividx  = i
         end
      end
      raise "Singular matrix" if biggst<=zero
      if pividx!=k then
        j = ps[k]
        ps[k] = ps[pividx]
        ps[pividx] = j
      end
      pivot   = a[ps[k]*n+k]
      for i in (k+1)...n do
        psin = ps[i]*n
        a[psin+k] = mult = a[psin+k].div(pivot,prec)
        if mult!=zero then
           pskn = ps[k]*n
           for j in (k+1)...n do
             a[psin+j] -= mult.mult(a[pskn+j],prec)
           end
        end
      end
    end
    raise "Singular matrix" if a[ps[n1]*n+n1] == zero
    ps
  end

  # Solves a*x = b for x, using LU decomposition.
  #
  # a is a matrix, b is a constant vector, x is the solution vector.
  #
  # ps is the pivot, a vector which indicates the permutation of rows performed
  # during LU decomposition.
  def lusolve(a,b,ps,zero=0.0)
    prec = BigDecimal.limit(nil)
    n = ps.size
    x = []
    for i in 0...n do
      dot = zero
      psin = ps[i]*n
      for j in 0...i do
        dot = a[psin+j].mult(x[j],prec) + dot
      end
      x <<= b[ps[i]] - dot
    end
    (n-1).downto(0) do |i|
       dot = zero
       psin = ps[i]*n
       for j in (i+1)...n do
         dot = a[psin+j].mult(x[j],prec) + dot
       end
       x[i]  = (x[i]-dot).div(a[psin+i],prec)
    end
    x
  end
end
PK     NZ\       bigdecimal/math.rbnu [        #
#--
# Contents:
#   sqrt(x, prec)
#   sin (x, prec)
#   cos (x, prec)
#   atan(x, prec)  Note: |x|<1, x=0.9999 may not converge.
#   exp (x, prec)
#   log (x, prec)
#   PI  (prec)
#   E   (prec) == exp(1.0,prec)
#
# where:
#   x    ... BigDecimal number to be computed.
#            |x| must be small enough to get convergence.
#   prec ... Number of digits to be obtained.
#++
#
# Provides mathematical functions.
#
# Example:
#
#   require "bigdecimal"
#   require "bigdecimal/math"
#
#   include BigMath
#
#   a = BigDecimal((PI(100)/2).to_s)
#   puts sin(a,100) # -> 0.10000000000000000000......E1
#
module BigMath

  # Computes the square root of x to the specified number of digits of 
  # precision.
  #
  # BigDecimal.new('2').sqrt(16).to_s 
  #  -> "0.14142135623730950488016887242096975E1"
  #
  def sqrt(x,prec)
    x.sqrt(prec)
  end

  # Computes the sine of x to the specified number of digits of precision.
  #
  # If x is infinite or NaN, returns NaN.
  def sin(x, prec)
    raise ArgumentError, "Zero or negative precision for sin" if prec <= 0
    return BigDecimal("NaN") if x.infinite? || x.nan?
    n    = prec + BigDecimal.double_fig
    one  = BigDecimal("1")
    two  = BigDecimal("2")
    x1   = x
    x2   = x.mult(x,n)
    sign = 1
    y    = x
    d    = y
    i    = one
    z    = one
    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
      m = BigDecimal.double_fig if m < BigDecimal.double_fig
      sign = -sign
      x1  = x2.mult(x1,n)
      i  += two
      z  *= (i-one) * i
      d   = sign * x1.div(z,m)
      y  += d
    end
    y
  end

  # Computes the cosine of x to the specified number of digits of precision.
  #
  # If x is infinite or NaN, returns NaN.
  def cos(x, prec)
    raise ArgumentError, "Zero or negative precision for cos" if prec <= 0
    return BigDecimal("NaN") if x.infinite? || x.nan?
    n    = prec + BigDecimal.double_fig
    one  = BigDecimal("1")
    two  = BigDecimal("2")
    x1 = one
    x2 = x.mult(x,n)
    sign = 1
    y = one
    d = y
    i = BigDecimal("0")
    z = one
    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
      m = BigDecimal.double_fig if m < BigDecimal.double_fig
      sign = -sign
      x1  = x2.mult(x1,n)
      i  += two
      z  *= (i-one) * i
      d   = sign * x1.div(z,m)
      y  += d
    end
    y
  end

  # Computes the arctangent of x to the specified number of digits of precision.
  #
  # If x is infinite or NaN, returns NaN.
  # Raises an argument error if x > 1.
  def atan(x, prec)
    raise ArgumentError, "Zero or negative precision for atan" if prec <= 0
    return BigDecimal("NaN") if x.infinite? || x.nan?
    raise ArgumentError, "x.abs must be less than 1.0" if x.abs>=1
    n    = prec + BigDecimal.double_fig
    y = x
    d = y
    t = x
    r = BigDecimal("3")
    x2 = x.mult(x,n)
    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
      m = BigDecimal.double_fig if m < BigDecimal.double_fig
      t = -t.mult(x2,n)
      d = t.div(r,m)
      y += d
      r += 2
    end
    y
  end

  # Computes the value of e (the base of natural logarithms) raised to the 
  # power of x, to the specified number of digits of precision.
  #
  # If x is infinite or NaN, returns NaN.
  #
  # BigMath::exp(BigDecimal.new('1'), 10).to_s
  # -> "0.271828182845904523536028752390026306410273E1"
  def exp(x, prec)
    raise ArgumentError, "Zero or negative precision for exp" if prec <= 0
    return BigDecimal("NaN") if x.infinite? || x.nan?
    n    = prec + BigDecimal.double_fig
    one  = BigDecimal("1")
    x1 = one
    y  = one
    d  = y
    z  = one
    i  = 0
    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
      m = BigDecimal.double_fig if m < BigDecimal.double_fig
      x1  = x1.mult(x,n)
      i += 1
      z *= i
      d  = x1.div(z,m)
      y += d
    end
    y
  end

  # Computes the natural logarithm of x to the specified number of digits 
  # of precision.
  #
  # Returns x if x is infinite or NaN.
  #
  def log(x, prec)
    raise ArgumentError, "Zero or negative argument for log" if x <= 0 || prec <= 0
    return x if x.infinite? || x.nan?
    one = BigDecimal("1")
    two = BigDecimal("2")
    n  = prec + BigDecimal.double_fig
    x  = (x - one).div(x + one,n)
    x2 = x.mult(x,n)
    y  = x
    d  = y
    i = one
    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
      m = BigDecimal.double_fig if m < BigDecimal.double_fig
      x  = x2.mult(x,n)
      i += two
      d  = x.div(i,m)
      y += d
    end
    y*two
  end

  # Computes the value of pi to the specified number of digits of precision.
  def PI(prec)
    raise ArgumentError, "Zero or negative argument for PI" if prec <= 0
    n      = prec + BigDecimal.double_fig
    zero   = BigDecimal("0")
    one    = BigDecimal("1")
    two    = BigDecimal("2")

    m25    = BigDecimal("-0.04")
    m57121 = BigDecimal("-57121")

    pi     = zero

    d = one
    k = one
    w = one
    t = BigDecimal("-80")
    while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
      m = BigDecimal.double_fig if m < BigDecimal.double_fig
      t   = t*m25
      d   = t.div(k,m)
      k   = k+two
      pi  = pi + d
    end

    d = one
    k = one
    w = one
    t = BigDecimal("956")
    while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
      m = BigDecimal.double_fig if m < BigDecimal.double_fig
      t   = t.div(m57121,n)
      d   = t.div(k,m)
      pi  = pi + d
      k   = k+two
    end
    pi
  end

  # Computes e (the base of natural logarithms) to the specified number of
  # digits of precision.
  def E(prec)
    raise ArgumentError, "Zero or negative precision for E" if prec <= 0
    n    = prec + BigDecimal.double_fig
    one  = BigDecimal("1")
    y  = one
    d  = y
    z  = one
    i  = 0
    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
      m = BigDecimal.double_fig if m < BigDecimal.double_fig
      i += 1
      z *= i
      d  = one.div(z,m)
      y += d
    end
    y
  end
end
PK     OZ\ y      bigdecimal/jacobian.rbnu [        #
# require 'bigdecimal/jacobian'
#
# Provides methods to compute the Jacobian matrix of a set of equations at a
# point x. In the methods below:
#
# f is an Object which is used to compute the Jacobian matrix of the equations.
# It must provide the following methods:
#
# f.values(x):: returns the values of all functions at x
#
# f.zero:: returns 0.0
# f.one:: returns 1.0
# f.two:: returns 1.0
# f.ten:: returns 10.0
#
# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.
#
# x is the point at which to compute the Jacobian.
#
# fx is f.values(x).
#
module Jacobian
  #--
  def isEqual(a,b,zero=0.0,e=1.0e-8)
    aa = a.abs
    bb = b.abs
    if aa == zero &&  bb == zero then
          true
    else
          if ((a-b)/(aa+bb)).abs < e then
             true
          else
             false
          end
    end
  end
  #++

  # Computes the derivative of f[i] at x[i].
  # fx is the value of f at x.
  def dfdxi(f,fx,x,i)
    nRetry = 0
    n = x.size
    xSave = x[i]
    ok = 0
    ratio = f.ten*f.ten*f.ten
    dx = x[i].abs/ratio
    dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps)
    dx = f.one/f.ten     if isEqual(dx,f.zero,f.zero,f.eps)
    until ok>0 do
      s = f.zero
      deriv = []
      if(nRetry>100) then
         raize "Singular Jacobian matrix. No change at x[" + i.to_s + "]"
      end
      dx = dx*f.two
      x[i] += dx
      fxNew = f.values(x)
      for j in 0...n do
        if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then
           ok += 1
           deriv <<= (fxNew[j]-fx[j])/dx
        else
           deriv <<= f.zero
        end
      end
      x[i] = xSave
    end
    deriv
  end

  # Computes the Jacobian of f at x. fx is the value of f at x.
  def jacobian(f,fx,x)
    n = x.size
    dfdx = Array::new(n*n)
    for i in 0...n do
      df = dfdxi(f,fx,x,i)
      for j in 0...n do
         dfdx[j*n+i] = df[j]
      end
    end
    dfdx
  end
end
PK     QZ\Iُ ُ   net/imap.rbnu [        #
# = net/imap.rb
#
# Copyright (C) 2000  Shugo Maeda <shugo@ruby-lang.org>
#
# This library is distributed under the terms of the Ruby license.
# You can freely distribute/modify this library.
#
# Documentation: Shugo Maeda, with RDoc conversion and overview by William
# Webber.
#
# See Net::IMAP for documentation. 
#


require "socket"
require "monitor"
require "digest/md5"
begin
  require "openssl"
rescue LoadError
end

module Net

  #
  # Net::IMAP implements Internet Message Access Protocol (IMAP) client
  # functionality.  The protocol is described in [IMAP].
  #
  # == IMAP Overview
  #
  # An IMAP client connects to a server, and then authenticates
  # itself using either #authenticate() or #login().  Having
  # authenticated itself, there is a range of commands
  # available to it.  Most work with mailboxes, which may be
  # arranged in an hierarchical namespace, and each of which
  # contains zero or more messages.  How this is implemented on
  # the server is implementation-dependent; on a UNIX server, it
  # will frequently be implemented as a files in mailbox format
  # within a hierarchy of directories.
  #
  # To work on the messages within a mailbox, the client must
  # first select that mailbox, using either #select() or (for
  # read-only access) #examine().  Once the client has successfully
  # selected a mailbox, they enter _selected_ state, and that
  # mailbox becomes the _current_ mailbox, on which mail-item
  # related commands implicitly operate.  
  #
  # Messages have two sorts of identifiers: message sequence
  # numbers, and UIDs.  
  #
  # Message sequence numbers number messages within a mail box 
  # from 1 up to the number of items in the mail box.  If new
  # message arrives during a session, it receives a sequence
  # number equal to the new size of the mail box.  If messages
  # are expunged from the mailbox, remaining messages have their
  # sequence numbers "shuffled down" to fill the gaps.
  #
  # UIDs, on the other hand, are permanently guaranteed not to
  # identify another message within the same mailbox, even if 
  # the existing message is deleted.  UIDs are required to
  # be assigned in ascending (but not necessarily sequential)
  # order within a mailbox; this means that if a non-IMAP client
  # rearranges the order of mailitems within a mailbox, the
  # UIDs have to be reassigned.  An IMAP client cannot thus
  # rearrange message orders.
  #
  # == Examples of Usage
  #
  # === List sender and subject of all recent messages in the default mailbox
  #
  #   imap = Net::IMAP.new('mail.example.com')
  #   imap.authenticate('LOGIN', 'joe_user', 'joes_password')
  #   imap.examine('INBOX')
  #   imap.search(["RECENT"]).each do |message_id|
  #     envelope = imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"]
  #     puts "#{envelope.from[0].name}: \t#{envelope.subject}"
  #   end
  #
  # === Move all messages from April 2003 from "Mail/sent-mail" to "Mail/sent-apr03"
  #
  #   imap = Net::IMAP.new('mail.example.com')
  #   imap.authenticate('LOGIN', 'joe_user', 'joes_password')
  #   imap.select('Mail/sent-mail')
  #   if not imap.list('Mail/', 'sent-apr03')
  #     imap.create('Mail/sent-apr03')
  #   end
  #   imap.search(["BEFORE", "30-Apr-2003", "SINCE", "1-Apr-2003"]).each do |message_id|
  #     imap.copy(message_id, "Mail/sent-apr03")
  #     imap.store(message_id, "+FLAGS", [:Deleted])
  #   end
  #   imap.expunge
  # 
  # == Thread Safety
  #
  # Net::IMAP supports concurrent threads. For example,
  # 
  #   imap = Net::IMAP.new("imap.foo.net", "imap2")
  #   imap.authenticate("cram-md5", "bar", "password")
  #   imap.select("inbox")
  #   fetch_thread = Thread.start { imap.fetch(1..-1, "UID") }
  #   search_result = imap.search(["BODY", "hello"])
  #   fetch_result = fetch_thread.value
  #   imap.disconnect
  # 
  # This script invokes the FETCH command and the SEARCH command concurrently.
  #
  # == Errors
  #
  # An IMAP server can send three different types of responses to indicate
  # failure:
  #
  # NO:: the attempted command could not be successfully completed.  For
  #      instance, the username/password used for logging in are incorrect;
  #      the selected mailbox does not exists; etc.  
  #
  # BAD:: the request from the client does not follow the server's 
  #       understanding of the IMAP protocol.  This includes attempting
  #       commands from the wrong client state; for instance, attempting
  #       to perform a SEARCH command without having SELECTed a current
  #       mailbox.  It can also signal an internal server
  #       failure (such as a disk crash) has occurred.
  #
  # BYE:: the server is saying goodbye.  This can be part of a normal
  #       logout sequence, and can be used as part of a login sequence
  #       to indicate that the server is (for some reason) unwilling
  #       to accept our connection.  As a response to any other command,
  #       it indicates either that the server is shutting down, or that
  #       the server is timing out the client connection due to inactivity.
  #
  # These three error response are represented by the errors
  # Net::IMAP::NoResponseError, Net::IMAP::BadResponseError, and
  # Net::IMAP::ByeResponseError, all of which are subclasses of
  # Net::IMAP::ResponseError.  Essentially, all methods that involve
  # sending a request to the server can generate one of these errors.
  # Only the most pertinent instances have been documented below.
  #
  # Because the IMAP class uses Sockets for communication, its methods
  # are also susceptible to the various errors that can occur when
  # working with sockets.  These are generally represented as
  # Errno errors.  For instance, any method that involves sending a
  # request to the server and/or receiving a response from it could
  # raise an Errno::EPIPE error if the network connection unexpectedly
  # goes down.  See the socket(7), ip(7), tcp(7), socket(2), connect(2),
  # and associated man pages.
  #
  # Finally, a Net::IMAP::DataFormatError is thrown if low-level data
  # is found to be in an incorrect format (for instance, when converting
  # between UTF-8 and UTF-16), and Net::IMAP::ResponseParseError is 
  # thrown if a server response is non-parseable. 
  #
  #
  # == References
  #
  # [[IMAP]]
  #    M. Crispin, "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1",
  #    RFC 2060, December 1996.  (Note: since obsoleted by RFC 3501)
  #
  # [[LANGUAGE-TAGS]]
  #    Alvestrand, H., "Tags for the Identification of
  #    Languages", RFC 1766, March 1995.
  #
  # [[MD5]]
  #    Myers, J., and M. Rose, "The Content-MD5 Header Field", RFC
  #    1864, October 1995.
  #
  # [[MIME-IMB]]
  #    Freed, N., and N. Borenstein, "MIME (Multipurpose Internet
  #    Mail Extensions) Part One: Format of Internet Message Bodies", RFC
  #    2045, November 1996.
  #
  # [[RFC-822]]
  #    Crocker, D., "Standard for the Format of ARPA Internet Text
  #    Messages", STD 11, RFC 822, University of Delaware, August 1982.
  #
  # [[RFC-2087]]
  #    Myers, J., "IMAP4 QUOTA extension", RFC 2087, January 1997.
  #
  # [[RFC-2086]]
  #    Myers, J., "IMAP4 ACL extension", RFC 2086, January 1997.
  #
  # [[RFC-2195]]
  #    Klensin, J., Catoe, R., and Krumviede, P., "IMAP/POP AUTHorize Extension
  #    for Simple Challenge/Response", RFC 2195, September 1997.
  #
  # [[SORT-THREAD-EXT]]
  #    Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - SORT and THREAD
  #    Extensions", draft-ietf-imapext-sort, May 2003.
  #
  # [[OSSL]]
  #    http://www.openssl.org
  #
  # [[RSSL]]
  #    http://savannah.gnu.org/projects/rubypki
  #
  # [[UTF7]]
  #    Goldsmith, D. and Davis, M., "UTF-7: A Mail-Safe Transformation Format of
  #    Unicode", RFC 2152, May 1997.
  #
  class IMAP
    include MonitorMixin
    if defined?(OpenSSL)
      include OpenSSL
      include SSL
    end

    #  Returns an initial greeting response from the server.
    attr_reader :greeting

    # Returns recorded untagged responses.  For example:
    #
    #   imap.select("inbox")
    #   p imap.responses["EXISTS"][-1]
    #   #=> 2
    #   p imap.responses["UIDVALIDITY"][-1]
    #   #=> 968263756
    attr_reader :responses

    # Returns all response handlers.
    attr_reader :response_handlers

    # The thread to receive exceptions.
    attr_accessor :client_thread

    # Flag indicating a message has been seen
    SEEN = :Seen

    # Flag indicating a message has been answered
    ANSWERED = :Answered

    # Flag indicating a message has been flagged for special or urgent
    # attention
    FLAGGED = :Flagged

    # Flag indicating a message has been marked for deletion.  This
    # will occur when the mailbox is closed or expunged.
    DELETED = :Deleted

    # Flag indicating a message is only a draft or work-in-progress version.
    DRAFT = :Draft

    # Flag indicating that the message is "recent", meaning that this
    # session is the first session in which the client has been notified
    # of this message.
    RECENT = :Recent

    # Flag indicating that a mailbox context name cannot contain
    # children.
    NOINFERIORS = :Noinferiors

    # Flag indicating that a mailbox is not selected.
    NOSELECT = :Noselect

    # Flag indicating that a mailbox has been marked "interesting" by
    # the server; this commonly indicates that the mailbox contains
    # new messages.
    MARKED = :Marked

    # Flag indicating that the mailbox does not contains new messages.
    UNMARKED = :Unmarked

    # Returns the debug mode.
    def self.debug
      return @@debug
    end

    # Sets the debug mode.
    def self.debug=(val)
      return @@debug = val
    end

    # Adds an authenticator for Net::IMAP#authenticate.  +auth_type+
    # is the type of authentication this authenticator supports
    # (for instance, "LOGIN").  The +authenticator+ is an object
    # which defines a process() method to handle authentication with
    # the server.  See Net::IMAP::LoginAuthenticator and 
    # Net::IMAP::CramMD5Authenticator for examples.
    #
    # If +auth_type+ refers to an existing authenticator, it will be
    # replaced by the new one.
    def self.add_authenticator(auth_type, authenticator)
      @@authenticators[auth_type] = authenticator
    end

    # Disconnects from the server.
    def disconnect
      begin
        # try to call SSL::SSLSocket#io.
        @sock.io.shutdown
      rescue NoMethodError
        # @sock is not an SSL::SSLSocket.
        @sock.shutdown
      end
      @receiver_thread.join
      @sock.close
    end

    # Returns true if disconnected from the server.
    def disconnected?
      return @sock.closed?
    end

    # Sends a CAPABILITY command, and returns an array of
    # capabilities that the server supports.  Each capability
    # is a string.  See [IMAP] for a list of possible
    # capabilities.
    #
    # Note that the Net::IMAP class does not modify its
    # behaviour according to the capabilities of the server;
    # it is up to the user of the class to ensure that 
    # a certain capability is supported by a server before
    # using it.
    def capability
      synchronize do
        send_command("CAPABILITY")
        return @responses.delete("CAPABILITY")[-1]
      end
    end

    # Sends a NOOP command to the server. It does nothing.
    def noop
      send_command("NOOP")
    end

    # Sends a LOGOUT command to inform the server that the client is
    # done with the connection.
    def logout
      send_command("LOGOUT")
    end

    # Sends an AUTHENTICATE command to authenticate the client.
    # The +auth_type+ parameter is a string that represents
    # the authentication mechanism to be used. Currently Net::IMAP
    # supports authentication mechanisms:
    #
    #   LOGIN:: login using cleartext user and password. 
    #   CRAM-MD5:: login with cleartext user and encrypted password
    #              (see [RFC-2195] for a full description).  This
    #              mechanism requires that the server have the user's
    #              password stored in clear-text password.
    #
    # For both these mechanisms, there should be two +args+: username
    # and (cleartext) password.  A server may not support one or other
    # of these mechanisms; check #capability() for a capability of
    # the form "AUTH=LOGIN" or "AUTH=CRAM-MD5".
    #
    # Authentication is done using the appropriate authenticator object:
    # see @@authenticators for more information on plugging in your own
    # authenticator.
    #
    # For example:
    #
    #    imap.authenticate('LOGIN', user, password)
    #
    # A Net::IMAP::NoResponseError is raised if authentication fails.
    def authenticate(auth_type, *args)
      auth_type = auth_type.upcase
      unless @@authenticators.has_key?(auth_type)
        raise ArgumentError,
          format('unknown auth type - "%s"', auth_type)
      end
      authenticator = @@authenticators[auth_type].new(*args)
      send_command("AUTHENTICATE", auth_type) do |resp|
        if resp.instance_of?(ContinuationRequest)
          data = authenticator.process(resp.data.text.unpack("m")[0])
          s = [data].pack("m").gsub(/\n/, "")
          send_string_data(s)
          put_string(CRLF)
        end
      end
    end

    # Sends a LOGIN command to identify the client and carries
    # the plaintext +password+ authenticating this +user+.  Note
    # that, unlike calling #authenticate() with an +auth_type+
    # of "LOGIN", #login() does *not* use the login authenticator.
    #
    # A Net::IMAP::NoResponseError is raised if authentication fails.
    def login(user, password)
      send_command("LOGIN", user, password)
    end

    # Sends a SELECT command to select a +mailbox+ so that messages
    # in the +mailbox+ can be accessed. 
    #
    # After you have selected a mailbox, you may retrieve the
    # number of items in that mailbox from @responses["EXISTS"][-1],
    # and the number of recent messages from @responses["RECENT"][-1].
    # Note that these values can change if new messages arrive
    # during a session; see #add_response_handler() for a way of
    # detecting this event.
    #
    # A Net::IMAP::NoResponseError is raised if the mailbox does not
    # exist or is for some reason non-selectable.
    def select(mailbox)
      synchronize do
        @responses.clear
        send_command("SELECT", mailbox)
      end
    end

    # Sends a EXAMINE command to select a +mailbox+ so that messages
    # in the +mailbox+ can be accessed.  Behaves the same as #select(),
    # except that the selected +mailbox+ is identified as read-only.
    #
    # A Net::IMAP::NoResponseError is raised if the mailbox does not
    # exist or is for some reason non-examinable.
    def examine(mailbox)
      synchronize do
        @responses.clear
        send_command("EXAMINE", mailbox)
      end
    end

    # Sends a CREATE command to create a new +mailbox+.
    #
    # A Net::IMAP::NoResponseError is raised if a mailbox with that name
    # cannot be created.
    def create(mailbox)
      send_command("CREATE", mailbox)
    end

    # Sends a DELETE command to remove the +mailbox+.
    #
    # A Net::IMAP::NoResponseError is raised if a mailbox with that name
    # cannot be deleted, either because it does not exist or because the
    # client does not have permission to delete it.
    def delete(mailbox)
      send_command("DELETE", mailbox)
    end

    # Sends a RENAME command to change the name of the +mailbox+ to
    # +newname+.
    #
    # A Net::IMAP::NoResponseError is raised if a mailbox with the 
    # name +mailbox+ cannot be renamed to +newname+ for whatever
    # reason; for instance, because +mailbox+ does not exist, or
    # because there is already a mailbox with the name +newname+.
    def rename(mailbox, newname)
      send_command("RENAME", mailbox, newname)
    end

    # Sends a SUBSCRIBE command to add the specified +mailbox+ name to
    # the server's set of "active" or "subscribed" mailboxes as returned
    # by #lsub().
    #
    # A Net::IMAP::NoResponseError is raised if +mailbox+ cannot be
    # subscribed to, for instance because it does not exist.
    def subscribe(mailbox)
      send_command("SUBSCRIBE", mailbox)
    end

    # Sends a UNSUBSCRIBE command to remove the specified +mailbox+ name
    # from the server's set of "active" or "subscribed" mailboxes.
    #
    # A Net::IMAP::NoResponseError is raised if +mailbox+ cannot be
    # unsubscribed from, for instance because the client is not currently
    # subscribed to it.
    def unsubscribe(mailbox)
      send_command("UNSUBSCRIBE", mailbox)
    end

    # Sends a LIST command, and returns a subset of names from
    # the complete set of all names available to the client.
    # +refname+ provides a context (for instance, a base directory
    # in a directory-based mailbox hierarchy).  +mailbox+ specifies
    # a mailbox or (via wildcards) mailboxes under that context.
    # Two wildcards may be used in +mailbox+: '*', which matches
    # all characters *including* the hierarchy delimiter (for instance,
    # '/' on a UNIX-hosted directory-based mailbox hierarchy); and '%',
    # which matches all characters *except* the hierarchy delimiter.
    #
    # If +refname+ is empty, +mailbox+ is used directly to determine
    # which mailboxes to match.  If +mailbox+ is empty, the root
    # name of +refname+ and the hierarchy delimiter are returned.
    #
    # The return value is an array of +Net::IMAP::MailboxList+. For example:
    #
    #   imap.create("foo/bar")
    #   imap.create("foo/baz")
    #   p imap.list("", "foo/%")
    #   #=> [#<Net::IMAP::MailboxList attr=[:Noselect], delim="/", name="foo/">, \\ 
    #        #<Net::IMAP::MailboxList attr=[:Noinferiors, :Marked], delim="/", name="foo/bar">, \\ 
    #        #<Net::IMAP::MailboxList attr=[:Noinferiors], delim="/", name="foo/baz">]
    def list(refname, mailbox)
      synchronize do
        send_command("LIST", refname, mailbox)
        return @responses.delete("LIST")
      end
    end

    # Sends the GETQUOTAROOT command along with specified +mailbox+.
    # This command is generally available to both admin and user.
    # If mailbox exists, returns an array containing objects of
    # Net::IMAP::MailboxQuotaRoot and Net::IMAP::MailboxQuota.
    def getquotaroot(mailbox)
      synchronize do
        send_command("GETQUOTAROOT", mailbox)
        result = []
        result.concat(@responses.delete("QUOTAROOT"))
        result.concat(@responses.delete("QUOTA"))
        return result
      end
    end

    # Sends the GETQUOTA command along with specified +mailbox+.
    # If this mailbox exists, then an array containing a
    # Net::IMAP::MailboxQuota object is returned.  This
    # command generally is only available to server admin.
    def getquota(mailbox)
      synchronize do
        send_command("GETQUOTA", mailbox)
        return @responses.delete("QUOTA")
      end
    end

    # Sends a SETQUOTA command along with the specified +mailbox+ and
    # +quota+.  If +quota+ is nil, then quota will be unset for that
    # mailbox.  Typically one needs to be logged in as server admin
    # for this to work.  The IMAP quota commands are described in
    # [RFC-2087].
    def setquota(mailbox, quota)
      if quota.nil?
        data = '()'
      else
        data = '(STORAGE ' + quota.to_s + ')'
      end
      send_command("SETQUOTA", mailbox, RawData.new(data))
    end

    # Sends the SETACL command along with +mailbox+, +user+ and the
    # +rights+ that user is to have on that mailbox.  If +rights+ is nil,
    # then that user will be stripped of any rights to that mailbox.
    # The IMAP ACL commands are described in [RFC-2086].
    def setacl(mailbox, user, rights)
      if rights.nil? 
        send_command("SETACL", mailbox, user, "")
      else
        send_command("SETACL", mailbox, user, rights)
      end
    end

    # Send the GETACL command along with specified +mailbox+.
    # If this mailbox exists, an array containing objects of
    # Net::IMAP::MailboxACLItem will be returned.
    def getacl(mailbox)
      synchronize do
        send_command("GETACL", mailbox)
        return @responses.delete("ACL")[-1]
      end
    end

    # Sends a LSUB command, and returns a subset of names from the set
    # of names that the user has declared as being "active" or
    # "subscribed".  +refname+ and +mailbox+ are interpreted as 
    # for #list().
    # The return value is an array of +Net::IMAP::MailboxList+.
    def lsub(refname, mailbox)
      synchronize do
        send_command("LSUB", refname, mailbox)
        return @responses.delete("LSUB")
      end
    end

    # Sends a STATUS command, and returns the status of the indicated
    # +mailbox+. +attr+ is a list of one or more attributes that
    # we are request the status of.  Supported attributes include:
    #
    #   MESSAGES:: the number of messages in the mailbox.
    #   RECENT:: the number of recent messages in the mailbox.
    #   UNSEEN:: the number of unseen messages in the mailbox.
    #
    # The return value is a hash of attributes. For example:
    #
    #   p imap.status("inbox", ["MESSAGES", "RECENT"])
    #   #=> {"RECENT"=>0, "MESSAGES"=>44}
    #
    # A Net::IMAP::NoResponseError is raised if status values 
    # for +mailbox+ cannot be returned, for instance because it
    # does not exist.
    def status(mailbox, attr)
      synchronize do
        send_command("STATUS", mailbox, attr)
        return @responses.delete("STATUS")[-1].attr
      end
    end

    # Sends a APPEND command to append the +message+ to the end of
    # the +mailbox+. The optional +flags+ argument is an array of 
    # flags to initially passing to the new message.  The optional
    # +date_time+ argument specifies the creation time to assign to the 
    # new message; it defaults to the current time.
    # For example:
    #
    #   imap.append("inbox", <<EOF.gsub(/\n/, "\r\n"), [:Seen], Time.now)
    #   Subject: hello
    #   From: shugo@ruby-lang.org
    #   To: shugo@ruby-lang.org
    #   
    #   hello world
    #   EOF
    #
    # A Net::IMAP::NoResponseError is raised if the mailbox does
    # not exist (it is not created automatically), or if the flags,
    # date_time, or message arguments contain errors.
    def append(mailbox, message, flags = nil, date_time = nil)
      args = []
      if flags
        args.push(flags)
      end
      args.push(date_time) if date_time
      args.push(Literal.new(message))
      send_command("APPEND", mailbox, *args)
    end

    # Sends a CHECK command to request a checkpoint of the currently
    # selected mailbox.  This performs implementation-specific
    # housekeeping, for instance, reconciling the mailbox's 
    # in-memory and on-disk state.
    def check
      send_command("CHECK")
    end

    # Sends a CLOSE command to close the currently selected mailbox.
    # The CLOSE command permanently removes from the mailbox all
    # messages that have the \Deleted flag set.
    def close
      send_command("CLOSE")
    end

    # Sends a EXPUNGE command to permanently remove from the currently
    # selected mailbox all messages that have the \Deleted flag set.
    def expunge
      synchronize do
        send_command("EXPUNGE")
        return @responses.delete("EXPUNGE")
      end
    end

    # Sends a SEARCH command to search the mailbox for messages that
    # match the given searching criteria, and returns message sequence
    # numbers.  +keys+ can either be a string holding the entire 
    # search string, or a single-dimension array of search keywords and 
    # arguments.  The following are some common search criteria;
    # see [IMAP] section 6.4.4 for a full list.
    #
    # <message set>:: a set of message sequence numbers.  ',' indicates
    #                 an interval, ':' indicates a range.  For instance,
    #                 '2,10:12,15' means "2,10,11,12,15".
    #
    # BEFORE <date>:: messages with an internal date strictly before
    #                 <date>.  The date argument has a format similar
    #                 to 8-Aug-2002.
    #
    # BODY <string>:: messages that contain <string> within their body.
    #
    # CC <string>:: messages containing <string> in their CC field.
    #
    # FROM <string>:: messages that contain <string> in their FROM field.
    #
    # NEW:: messages with the \Recent, but not the \Seen, flag set.
    #
    # NOT <search-key>:: negate the following search key.
    #
    # OR <search-key> <search-key>:: "or" two search keys together.
    #
    # ON <date>:: messages with an internal date exactly equal to <date>, 
    #             which has a format similar to 8-Aug-2002.
    #
    # SINCE <date>:: messages with an internal date on or after <date>.
    #
    # SUBJECT <string>:: messages with <string> in their subject.
    #
    # TO <string>:: messages with <string> in their TO field.
    # 
    # For example:
    #
    #   p imap.search(["SUBJECT", "hello", "NOT", "NEW"])
    #   #=> [1, 6, 7, 8]
    def search(keys, charset = nil)
      return search_internal("SEARCH", keys, charset)
    end

    # As for #search(), but returns unique identifiers.
    def uid_search(keys, charset = nil)
      return search_internal("UID SEARCH", keys, charset)
    end

    # Sends a FETCH command to retrieve data associated with a message
    # in the mailbox. The +set+ parameter is a number or an array of
    # numbers or a Range object. The number is a message sequence
    # number.  +attr+ is a list of attributes to fetch; see the
    # documentation for Net::IMAP::FetchData for a list of valid
    # attributes.
    # The return value is an array of Net::IMAP::FetchData. For example:
    #
    #   p imap.fetch(6..8, "UID")
    #   #=> [#<Net::IMAP::FetchData seqno=6, attr={"UID"=>98}>, \\ 
    #        #<Net::IMAP::FetchData seqno=7, attr={"UID"=>99}>, \\ 
    #        #<Net::IMAP::FetchData seqno=8, attr={"UID"=>100}>]
    #   p imap.fetch(6, "BODY[HEADER.FIELDS (SUBJECT)]")
    #   #=> [#<Net::IMAP::FetchData seqno=6, attr={"BODY[HEADER.FIELDS (SUBJECT)]"=>"Subject: test\r\n\r\n"}>]
    #   data = imap.uid_fetch(98, ["RFC822.SIZE", "INTERNALDATE"])[0]
    #   p data.seqno
    #   #=> 6
    #   p data.attr["RFC822.SIZE"]
    #   #=> 611
    #   p data.attr["INTERNALDATE"]
    #   #=> "12-Oct-2000 22:40:59 +0900"
    #   p data.attr["UID"]
    #   #=> 98
    def fetch(set, attr)
      return fetch_internal("FETCH", set, attr)
    end

    # As for #fetch(), but +set+ contains unique identifiers.
    def uid_fetch(set, attr)
      return fetch_internal("UID FETCH", set, attr)
    end

    # Sends a STORE command to alter data associated with messages
    # in the mailbox, in particular their flags. The +set+ parameter 
    # is a number or an array of numbers or a Range object. Each number 
    # is a message sequence number.  +attr+ is the name of a data item 
    # to store: 'FLAGS' means to replace the message's flag list
    # with the provided one; '+FLAGS' means to add the provided flags;
    # and '-FLAGS' means to remove them.  +flags+ is a list of flags.
    #
    # The return value is an array of Net::IMAP::FetchData. For example:
    #
    #   p imap.store(6..8, "+FLAGS", [:Deleted])
    #   #=> [#<Net::IMAP::FetchData seqno=6, attr={"FLAGS"=>[:Seen, :Deleted]}>, \\ 
    #        #<Net::IMAP::FetchData seqno=7, attr={"FLAGS"=>[:Seen, :Deleted]}>, \\  
    #        #<Net::IMAP::FetchData seqno=8, attr={"FLAGS"=>[:Seen, :Deleted]}>]
    def store(set, attr, flags)
      return store_internal("STORE", set, attr, flags)
    end

    # As for #store(), but +set+ contains unique identifiers.
    def uid_store(set, attr, flags)
      return store_internal("UID STORE", set, attr, flags)
    end

    # Sends a COPY command to copy the specified message(s) to the end
    # of the specified destination +mailbox+. The +set+ parameter is
    # a number or an array of numbers or a Range object. The number is
    # a message sequence number.
    def copy(set, mailbox)
      copy_internal("COPY", set, mailbox)
    end

    # As for #copy(), but +set+ contains unique identifiers.
    def uid_copy(set, mailbox)
      copy_internal("UID COPY", set, mailbox)
    end

    # Sends a SORT command to sort messages in the mailbox.
    # Returns an array of message sequence numbers. For example:
    #
    #   p imap.sort(["FROM"], ["ALL"], "US-ASCII")
    #   #=> [1, 2, 3, 5, 6, 7, 8, 4, 9]
    #   p imap.sort(["DATE"], ["SUBJECT", "hello"], "US-ASCII")
    #   #=> [6, 7, 8, 1]
    #
    # See [SORT-THREAD-EXT] for more details.
    def sort(sort_keys, search_keys, charset)
      return sort_internal("SORT", sort_keys, search_keys, charset)
    end

    # As for #sort(), but returns an array of unique identifiers.
    def uid_sort(sort_keys, search_keys, charset)
      return sort_internal("UID SORT", sort_keys, search_keys, charset)
    end

    # Adds a response handler. For example, to detect when 
    # the server sends us a new EXISTS response (which normally
    # indicates new messages being added to the mail box), 
    # you could add the following handler after selecting the
    # mailbox.
    #
    #   imap.add_response_handler { |resp|
    #     if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS"
    #       puts "Mailbox now has #{resp.data} messages"
    #     end
    #   }
    #
    def add_response_handler(handler = Proc.new)
      @response_handlers.push(handler)
    end

    # Removes the response handler.
    def remove_response_handler(handler)
      @response_handlers.delete(handler)
    end

    # As for #search(), but returns message sequence numbers in threaded
    # format, as a Net::IMAP::ThreadMember tree.  The supported algorithms
    # are:
    #
    # ORDEREDSUBJECT:: split into single-level threads according to subject,
    #                  ordered by date.
    # REFERENCES:: split into threads by parent/child relationships determined
    #              by which message is a reply to which.
    #
    # Unlike #search(), +charset+ is a required argument.  US-ASCII
    # and UTF-8 are sample values.
    #
    # See [SORT-THREAD-EXT] for more details.
    def thread(algorithm, search_keys, charset)
      return thread_internal("THREAD", algorithm, search_keys, charset)
    end

    # As for #thread(), but returns unique identifiers instead of 
    # message sequence numbers.
    def uid_thread(algorithm, search_keys, charset)
      return thread_internal("UID THREAD", algorithm, search_keys, charset)
    end

    # Decode a string from modified UTF-7 format to UTF-8.
    #
    # UTF-7 is a 7-bit encoding of Unicode [UTF7].  IMAP uses a
    # slightly modified version of this to encode mailbox names
    # containing non-ASCII characters; see [IMAP] section 5.1.3.
    #
    # Net::IMAP does _not_ automatically encode and decode
    # mailbox names to and from utf7.
    def self.decode_utf7(s)
      return s.gsub(/&(.*?)-/n) {
        if $1.empty?
          "&"
        else
          base64 = $1.tr(",", "/")
          x = base64.length % 4
          if x > 0
            base64.concat("=" * (4 - x))
          end
          u16tou8(base64.unpack("m")[0])
        end
      }
    end

    # Encode a string from UTF-8 format to modified UTF-7.
    def self.encode_utf7(s)
      return s.gsub(/(&)|([^\x20-\x7e]+)/u) { |x|
        if $1
          "&-"
        else
          base64 = [u8tou16(x)].pack("m")
          "&" + base64.delete("=\n").tr("/", ",") + "-"
        end
      }
    end

    private

    CRLF = "\r\n"      # :nodoc:
    PORT = 143         # :nodoc:

    @@debug = false
    @@authenticators = {}

    # Creates a new Net::IMAP object and connects it to the specified
    # +port+ (143 by default) on the named +host+.  If +usessl+ is true, 
    # then an attempt will
    # be made to use SSL (now TLS) to connect to the server.  For this
    # to work OpenSSL [OSSL] and the Ruby OpenSSL [RSSL]
    # extensions need to be installed.  The +certs+ parameter indicates
    # the path or file containing the CA cert of the server, and the
    # +verify+ parameter is for the OpenSSL verification callback.
    #
    # The most common errors are:
    #
    # Errno::ECONNREFUSED:: connection refused by +host+ or an intervening
    #                       firewall.
    # Errno::ETIMEDOUT:: connection timed out (possibly due to packets
    #                    being dropped by an intervening firewall).
    # Errno::ENETUNREACH:: there is no route to that network.
    # SocketError:: hostname not known or other socket error.
    # Net::IMAP::ByeResponseError:: we connected to the host, but they 
    #                               immediately said goodbye to us.
    def initialize(host, port = PORT, usessl = false, certs = nil, verify = false)
      super()
      @host = host
      @port = port
      @tag_prefix = "RUBY"
      @tagno = 0
      @parser = ResponseParser.new
      @sock = TCPSocket.open(host, port)
      if usessl
        unless defined?(OpenSSL)
          raise "SSL extension not installed"
        end
        @usessl = true

        # verify the server.
        context = SSLContext::new()
        context.ca_file = certs if certs && FileTest::file?(certs)
        context.ca_path = certs if certs && FileTest::directory?(certs)
        context.verify_mode = VERIFY_PEER if verify
        if defined?(VerifyCallbackProc)
          context.verify_callback = VerifyCallbackProc 
        end
        @sock = SSLSocket.new(@sock, context)
        @sock.sync_close = true
        @sock.connect   # start ssl session.
        @sock.post_connection_check(@host) if verify
      else
        @usessl = false
      end
      @responses = Hash.new([].freeze)
      @tagged_responses = {}
      @response_handlers = []
      @response_arrival = new_cond
      @continuation_request = nil
      @logout_command_tag = nil
      @debug_output_bol = true
      @exception = nil

      @greeting = get_response
      if @greeting.name == "BYE"
        @sock.close
        raise ByeResponseError, @greeting.raw_data
      end

      @client_thread = Thread.current
      @receiver_thread = Thread.start {
        receive_responses
      }
    end

    def receive_responses
      while true
        synchronize do
          @exception = nil
        end
        begin
          resp = get_response
        rescue Exception => e
          synchronize do
            @sock.close unless @sock.closed?
            @exception = e
          end
          break
        end
        unless resp
          synchronize do
            @exception = EOFError.new("end of file reached")
          end
          break
        end
        begin
          synchronize do
            case resp
            when TaggedResponse
              @tagged_responses[resp.tag] = resp
              @response_arrival.broadcast
              if resp.tag == @logout_command_tag
                return
              end
            when UntaggedResponse
              record_response(resp.name, resp.data)
              if resp.data.instance_of?(ResponseText) &&
                  (code = resp.data.code)
                record_response(code.name, code.data)
              end
              if resp.name == "BYE" && @logout_command_tag.nil?
                @sock.close
                @exception = ByeResponseError.new(resp.raw_data)
                @response_arrival.broadcast
                return
              end
            when ContinuationRequest
              @continuation_request = resp
              @response_arrival.broadcast
            end
            @response_handlers.each do |handler|
              handler.call(resp)
            end
          end
        rescue Exception => e
          @exception = e
          synchronize do
            @response_arrival.broadcast
          end
        end
      end
      synchronize do
        @response_arrival.broadcast
      end
    end

    def get_tagged_response(tag)
      until @tagged_responses.key?(tag)
        raise @exception if @exception
        @response_arrival.wait
      end
      return pick_up_tagged_response(tag)
    end

    def pick_up_tagged_response(tag)
      resp = @tagged_responses.delete(tag)
      case resp.name
      when /\A(?:NO)\z/ni
        raise NoResponseError, resp.data.text
      when /\A(?:BAD)\z/ni
        raise BadResponseError, resp.data.text
      else
        return resp
      end
    end

    def get_response
      buff = ""
      while true
        s = @sock.gets(CRLF)
        break unless s
        buff.concat(s)
        if /\{(\d+)\}\r\n/n =~ s
          s = @sock.read($1.to_i)
          buff.concat(s)
        else
          break
        end
      end
      return nil if buff.length == 0
      if @@debug
        $stderr.print(buff.gsub(/^/n, "S: "))
      end
      return @parser.parse(buff)
    end

    def record_response(name, data)
      unless @responses.has_key?(name)
        @responses[name] = []
      end
      @responses[name].push(data)
    end

    def send_command(cmd, *args, &block)
      synchronize do
        tag = Thread.current[:net_imap_tag] = generate_tag
        put_string(tag + " " + cmd)
        args.each do |i|
          put_string(" ")
          send_data(i)
        end
        put_string(CRLF)
        if cmd == "LOGOUT"
          @logout_command_tag = tag
        end
        if block
          add_response_handler(block)
        end
        begin
          return get_tagged_response(tag)
        ensure
          if block
            remove_response_handler(block)
          end
        end
      end
    end

    def generate_tag
      @tagno += 1
      return format("%s%04d", @tag_prefix, @tagno)
    end
    
    def put_string(str)
      @sock.print(str)
      if @@debug
        if @debug_output_bol
          $stderr.print("C: ")
        end
        $stderr.print(str.gsub(/\n(?!\z)/n, "\nC: "))
        if /\r\n\z/n.match(str)
          @debug_output_bol = true
        else
          @debug_output_bol = false
        end
      end
    end

    def send_data(data)
      case data
      when nil
        put_string("NIL")
      when String
        send_string_data(data)
      when Integer
        send_number_data(data)
      when Array
        send_list_data(data)
      when Time
        send_time_data(data)
      when Symbol
        send_symbol_data(data)
      else
        data.send_data(self)
      end
    end

    def send_string_data(str)
      case str
      when ""
        put_string('""')
      when /[\x80-\xff\r\n]/n
        # literal
        send_literal(str)
      when /[(){ \x00-\x1f\x7f%*"\\]/n
        # quoted string
        send_quoted_string(str)
      else
        put_string(str)
      end
    end
    
    def send_quoted_string(str)
      put_string('"' + str.gsub(/["\\]/n, "\\\\\\&") + '"')
    end

    def send_literal(str)
      put_string("{" + str.length.to_s + "}" + CRLF)
      while @continuation_request.nil? &&
        !@tagged_responses.key?(Thread.current[:net_imap_tag])
        @response_arrival.wait
        raise @exception if @exception
      end
      if @continuation_request.nil?
        pick_up_tagged_response(Thread.current[:net_imap_tag])
        raise ResponseError.new("expected continuation request")
      end
      @continuation_request = nil
      put_string(str)
    end

    def send_number_data(num)
      if num < 0 || num >= 4294967296
        raise DataFormatError, num.to_s
      end
      put_string(num.to_s)
    end

    def send_list_data(list)
      put_string("(")
      first = true
      list.each do |i|
        if first
          first = false
        else
          put_string(" ")
        end
        send_data(i)
      end
      put_string(")")
    end

    DATE_MONTH = %w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)

    def send_time_data(time)
      t = time.dup.gmtime
      s = format('"%2d-%3s-%4d %02d:%02d:%02d +0000"',
                 t.day, DATE_MONTH[t.month - 1], t.year,
                 t.hour, t.min, t.sec)
      put_string(s)
    end

    def send_symbol_data(symbol)
      put_string("\\" + symbol.to_s)
    end

    def search_internal(cmd, keys, charset)
      if keys.instance_of?(String)
        keys = [RawData.new(keys)]
      else
        normalize_searching_criteria(keys)
      end
      synchronize do
        if charset
          send_command(cmd, "CHARSET", charset, *keys)
        else
          send_command(cmd, *keys)
        end
        return @responses.delete("SEARCH")[-1]
      end
    end

    def fetch_internal(cmd, set, attr)
      case attr
      when String then
        attr = RawData.new(attr)
      when Array then
        attr = attr.map { |arg|
          arg.is_a?(String) ? RawData.new(arg) : arg
        }
      end

      synchronize do
        @responses.delete("FETCH")
        send_command(cmd, MessageSet.new(set), attr)
        return @responses.delete("FETCH")
      end
    end

    def store_internal(cmd, set, attr, flags)
      if attr.instance_of?(String)
        attr = RawData.new(attr)
      end
      synchronize do
        @responses.delete("FETCH")
        send_command(cmd, MessageSet.new(set), attr, flags)
        return @responses.delete("FETCH")
      end
    end

    def copy_internal(cmd, set, mailbox)
      send_command(cmd, MessageSet.new(set), mailbox)
    end

    def sort_internal(cmd, sort_keys, search_keys, charset)
      if search_keys.instance_of?(String)
        search_keys = [RawData.new(search_keys)]
      else
        normalize_searching_criteria(search_keys)
      end
      normalize_searching_criteria(search_keys)
      synchronize do
        send_command(cmd, sort_keys, charset, *search_keys)
        return @responses.delete("SORT")[-1]
      end
    end

    def thread_internal(cmd, algorithm, search_keys, charset)
      if search_keys.instance_of?(String)
        search_keys = [RawData.new(search_keys)]
      else
        normalize_searching_criteria(search_keys)
      end
      normalize_searching_criteria(search_keys)
      send_command(cmd, algorithm, charset, *search_keys)
      return @responses.delete("THREAD")[-1]
    end

    def normalize_searching_criteria(keys)
      keys.collect! do |i|
        case i
        when -1, Range, Array
          MessageSet.new(i)
        else
          i
        end
      end
    end

    def self.u16tou8(s)
      len = s.length
      if len < 2
        return ""
      end
      buf = ""
      i = 0
      while i < len
        c = s[i] << 8 | s[i + 1]
        i += 2
        if c == 0xfeff
          next
        elsif c < 0x0080
          buf.concat(c)
        elsif c < 0x0800
          b2 = c & 0x003f
          b1 = c >> 6
          buf.concat(b1 | 0xc0)
          buf.concat(b2 | 0x80)
        elsif c >= 0xdc00 && c < 0xe000
          raise DataFormatError, "invalid surrogate detected"
        elsif c >= 0xd800 && c < 0xdc00
          if i + 2 > len
            raise DataFormatError, "invalid surrogate detected"
          end
          low = s[i] << 8 | s[i + 1]
          i += 2
          if low < 0xdc00 || low > 0xdfff
            raise DataFormatError, "invalid surrogate detected"
          end
          c = (((c & 0x03ff)) << 10 | (low & 0x03ff)) + 0x10000
          b4 = c & 0x003f
          b3 = (c >> 6) & 0x003f
          b2 = (c >> 12) & 0x003f
          b1 = c >> 18;
          buf.concat(b1 | 0xf0)
          buf.concat(b2 | 0x80)
          buf.concat(b3 | 0x80)
          buf.concat(b4 | 0x80)
        else # 0x0800-0xffff
          b3 = c & 0x003f
          b2 = (c >> 6) & 0x003f
          b1 = c >> 12
          buf.concat(b1 | 0xe0)
          buf.concat(b2 | 0x80)
          buf.concat(b3 | 0x80)
        end
      end
      return buf
    end
    private_class_method :u16tou8

    def self.u8tou16(s)
      len = s.length
      buf = ""
      i = 0
      while i < len
        c = s[i]
        if (c & 0x80) == 0
          buf.concat(0x00)
          buf.concat(c)
          i += 1
        elsif (c & 0xe0) == 0xc0 &&
            len >= 2 &&
            (s[i + 1] & 0xc0) == 0x80
          if c == 0xc0 || c == 0xc1
            raise DataFormatError, format("non-shortest UTF-8 sequence (%02x)", c)
          end
          u = ((c & 0x1f) << 6) | (s[i + 1] & 0x3f)
          buf.concat(u >> 8)
          buf.concat(u & 0x00ff)
          i += 2
        elsif (c & 0xf0) == 0xe0 &&
            i + 2 < len &&
            (s[i + 1] & 0xc0) == 0x80 &&
            (s[i + 2] & 0xc0) == 0x80
          if c == 0xe0 && s[i + 1] < 0xa0
            raise DataFormatError, format("non-shortest UTF-8 sequence (%02x)", c)
          end
          u = ((c & 0x0f) << 12) | ((s[i + 1] & 0x3f) << 6) | (s[i + 2] & 0x3f)
          # surrogate chars
          if u >= 0xd800 && u <= 0xdfff
            raise DataFormatError, format("none-UTF-16 char detected (%04x)", u)
          end
          buf.concat(u >> 8)
          buf.concat(u & 0x00ff)
          i += 3
        elsif (c & 0xf8) == 0xf0 &&
            i + 3 < len &&
            (s[i + 1] & 0xc0) == 0x80 &&
            (s[i + 2] & 0xc0) == 0x80 &&
            (s[i + 3] & 0xc0) == 0x80
          if c == 0xf0 && s[i + 1] < 0x90
            raise DataFormatError, format("non-shortest UTF-8 sequence (%02x)", c)
          end
          u = ((c & 0x07) << 18) | ((s[i + 1] & 0x3f) << 12) |
            ((s[i + 2] & 0x3f) << 6) | (s[i + 3] & 0x3f)
          if u < 0x10000
            buf.concat(u >> 8)
            buf.concat(u & 0x00ff)
          elsif u < 0x110000
            high = ((u - 0x10000) >> 10) | 0xd800
            low = (u & 0x03ff) | 0xdc00
            buf.concat(high >> 8)
            buf.concat(high & 0x00ff)
            buf.concat(low >> 8)
            buf.concat(low & 0x00ff)
          else
            raise DataFormatError, format("none-UTF-16 char detected (%04x)", u)
          end
          i += 4
        else
          raise DataFormatError, format("illegal UTF-8 sequence (%02x)", c)
        end
      end
      return buf
    end
    private_class_method :u8tou16

    class RawData # :nodoc:
      def send_data(imap)
        imap.send(:put_string, @data)
      end

      private

      def initialize(data)
        @data = data
      end
    end

    class Atom # :nodoc:
      def send_data(imap)
        imap.send(:put_string, @data)
      end

      private

      def initialize(data)
        @data = data
      end
    end

    class QuotedString # :nodoc:
      def send_data(imap)
        imap.send(:send_quoted_string, @data)
      end

      private

      def initialize(data)
        @data = data
      end
    end

    class Literal # :nodoc:
      def send_data(imap)
        imap.send(:send_literal, @data)
      end

      private

      def initialize(data)
        @data = data
      end
    end

    class MessageSet # :nodoc:
      def send_data(imap)
        imap.send(:put_string, format_internal(@data))
      end

      private

      def initialize(data)
        @data = data
      end

      def format_internal(data)
        case data
        when "*"
          return data
        when Integer
          ensure_nz_number(data)
          if data == -1
            return "*"
          else
            return data.to_s
          end
        when Range
          return format_internal(data.first) +
            ":" + format_internal(data.last)
        when Array
          return data.collect {|i| format_internal(i)}.join(",")
        when ThreadMember
          return data.seqno.to_s +
            ":" + data.children.collect {|i| format_internal(i).join(",")}
        else
          raise DataFormatError, data.inspect
        end
      end

      def ensure_nz_number(num)
        if num < -1 || num == 0 || num >= 4294967296
          msg = "nz_number must be non-zero unsigned 32-bit integer: " +
                num.inspect
          raise DataFormatError, msg
        end
      end
    end

    # Net::IMAP::ContinuationRequest represents command continuation requests.
    # 
    # The command continuation request response is indicated by a "+" token
    # instead of a tag.  This form of response indicates that the server is
    # ready to accept the continuation of a command from the client.  The
    # remainder of this response is a line of text.
    # 
    #   continue_req    ::= "+" SPACE (resp_text / base64)
    # 
    # ==== Fields:
    # 
    # data:: Returns the data (Net::IMAP::ResponseText).
    # 
    # raw_data:: Returns the raw data string.
    ContinuationRequest = Struct.new(:data, :raw_data)

    # Net::IMAP::UntaggedResponse represents untagged responses.
    # 
    # Data transmitted by the server to the client and status responses
    # that do not indicate command completion are prefixed with the token
    # "*", and are called untagged responses.
    # 
    #   response_data   ::= "*" SPACE (resp_cond_state / resp_cond_bye /
    #                       mailbox_data / message_data / capability_data)
    # 
    # ==== Fields:
    # 
    # name:: Returns the name such as "FLAGS", "LIST", "FETCH"....
    # 
    # data:: Returns the data such as an array of flag symbols,
    #         a ((<Net::IMAP::MailboxList>)) object....
    # 
    # raw_data:: Returns the raw data string.
    UntaggedResponse = Struct.new(:name, :data, :raw_data)
     
    # Net::IMAP::TaggedResponse represents tagged responses.
    # 
    # The server completion result response indicates the success or
    # failure of the operation.  It is tagged with the same tag as the
    # client command which began the operation.
    # 
    #   response_tagged ::= tag SPACE resp_cond_state CRLF
    #   
    #   tag             ::= 1*<any ATOM_CHAR except "+">
    #   
    #   resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text
    # 
    # ==== Fields:
    # 
    # tag:: Returns the tag.
    # 
    # name:: Returns the name. the name is one of "OK", "NO", "BAD".
    # 
    # data:: Returns the data. See ((<Net::IMAP::ResponseText>)).
    # 
    # raw_data:: Returns the raw data string.
    #
    TaggedResponse = Struct.new(:tag, :name, :data, :raw_data)
     
    # Net::IMAP::ResponseText represents texts of responses.
    # The text may be prefixed by the response code.
    # 
    #   resp_text       ::= ["[" resp_text_code "]" SPACE] (text_mime2 / text)
    #                       ;; text SHOULD NOT begin with "[" or "="
    # 
    # ==== Fields:
    # 
    # code:: Returns the response code. See ((<Net::IMAP::ResponseCode>)).
    #       
    # text:: Returns the text.
    # 
    ResponseText = Struct.new(:code, :text)

    # 
    # Net::IMAP::ResponseCode represents response codes.
    # 
    #   resp_text_code  ::= "ALERT" / "PARSE" /
    #                       "PERMANENTFLAGS" SPACE "(" #(flag / "\*") ")" /
    #                       "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
    #                       "UIDVALIDITY" SPACE nz_number /
    #                       "UNSEEN" SPACE nz_number /
    #                       atom [SPACE 1*<any TEXT_CHAR except "]">]
    # 
    # ==== Fields:
    # 
    # name:: Returns the name such as "ALERT", "PERMANENTFLAGS", "UIDVALIDITY"....
    # 
    # data:: Returns the data if it exists.
    #
    ResponseCode = Struct.new(:name, :data)

    # Net::IMAP::MailboxList represents contents of the LIST response.
    # 
    #   mailbox_list    ::= "(" #("\Marked" / "\Noinferiors" /
    #                       "\Noselect" / "\Unmarked" / flag_extension) ")"
    #                       SPACE (<"> QUOTED_CHAR <"> / nil) SPACE mailbox
    # 
    # ==== Fields:
    # 
    # attr:: Returns the name attributes. Each name attribute is a symbol
    #        capitalized by String#capitalize, such as :Noselect (not :NoSelect).
    # 
    # delim:: Returns the hierarchy delimiter
    # 
    # name:: Returns the mailbox name.
    #
    MailboxList = Struct.new(:attr, :delim, :name)

    # Net::IMAP::MailboxQuota represents contents of GETQUOTA response.
    # This object can also be a response to GETQUOTAROOT.  In the syntax
    # specification below, the delimiter used with the "#" construct is a
    # single space (SPACE).
    # 
    #    quota_list      ::= "(" #quota_resource ")"
    # 
    #    quota_resource  ::= atom SPACE number SPACE number
    # 
    #    quota_response  ::= "QUOTA" SPACE astring SPACE quota_list
    # 
    # ==== Fields:
    # 
    # mailbox:: The mailbox with the associated quota.
    # 
    # usage:: Current storage usage of mailbox.
    # 
    # quota:: Quota limit imposed on mailbox.
    #
    MailboxQuota = Struct.new(:mailbox, :usage, :quota)

    # Net::IMAP::MailboxQuotaRoot represents part of the GETQUOTAROOT
    # response. (GETQUOTAROOT can also return Net::IMAP::MailboxQuota.)
    # 
    #    quotaroot_response ::= "QUOTAROOT" SPACE astring *(SPACE astring)
    # 
    # ==== Fields:
    # 
    # mailbox:: The mailbox with the associated quota.
    # 
    # quotaroots:: Zero or more quotaroots that effect the quota on the
    #              specified mailbox.
    #
    MailboxQuotaRoot = Struct.new(:mailbox, :quotaroots)

    # Net::IMAP::MailboxACLItem represents response from GETACL.
    # 
    #    acl_data        ::= "ACL" SPACE mailbox *(SPACE identifier SPACE rights)
    # 
    #    identifier      ::= astring
    # 
    #    rights          ::= astring
    # 
    # ==== Fields:
    # 
    # user:: Login name that has certain rights to the mailbox
    #        that was specified with the getacl command.
    # 
    # rights:: The access rights the indicated user has to the
    #          mailbox.
    #
    MailboxACLItem = Struct.new(:user, :rights)

    # Net::IMAP::StatusData represents contents of the STATUS response.
    # 
    # ==== Fields:
    # 
    # mailbox:: Returns the mailbox name.
    # 
    # attr:: Returns a hash. Each key is one of "MESSAGES", "RECENT", "UIDNEXT",
    #        "UIDVALIDITY", "UNSEEN". Each value is a number.
    # 
    StatusData = Struct.new(:mailbox, :attr)

    # Net::IMAP::FetchData represents contents of the FETCH response.
    # 
    # ==== Fields:
    # 
    # seqno:: Returns the message sequence number.
    #         (Note: not the unique identifier, even for the UID command response.)
    # 
    # attr:: Returns a hash. Each key is a data item name, and each value is
    #        its value.
    # 
    #        The current data items are:
    # 
    #        [BODY]
    #           A form of BODYSTRUCTURE without extension data.
    #        [BODY[<section>]<<origin_octet>>]
    #           A string expressing the body contents of the specified section.
    #        [BODYSTRUCTURE]
    #           An object that describes the [MIME-IMB] body structure of a message.
    #           See Net::IMAP::BodyTypeBasic, Net::IMAP::BodyTypeText,
    #           Net::IMAP::BodyTypeMessage, Net::IMAP::BodyTypeMultipart.
    #        [ENVELOPE]
    #           A Net::IMAP::Envelope object that describes the envelope
    #           structure of a message.
    #        [FLAGS]
    #           A array of flag symbols that are set for this message. flag symbols
    #           are capitalized by String#capitalize.
    #        [INTERNALDATE]
    #           A string representing the internal date of the message.
    #        [RFC822]
    #           Equivalent to BODY[].
    #        [RFC822.HEADER]
    #           Equivalent to BODY.PEEK[HEADER].
    #        [RFC822.SIZE]
    #           A number expressing the [RFC-822] size of the message.
    #        [RFC822.TEXT]
    #           Equivalent to BODY[TEXT].
    #        [UID]
    #           A number expressing the unique identifier of the message.
    # 
    FetchData = Struct.new(:seqno, :attr)

    # Net::IMAP::Envelope represents envelope structures of messages.
    # 
    # ==== Fields:
    # 
    # date:: Returns a string that represents the date.
    # 
    # subject:: Returns a string that represents the subject.
    # 
    # from:: Returns an array of Net::IMAP::Address that represents the from.
    # 
    # sender:: Returns an array of Net::IMAP::Address that represents the sender.
    # 
    # reply_to:: Returns an array of Net::IMAP::Address that represents the reply-to.
    # 
    # to:: Returns an array of Net::IMAP::Address that represents the to.
    # 
    # cc:: Returns an array of Net::IMAP::Address that represents the cc.
    # 
    # bcc:: Returns an array of Net::IMAP::Address that represents the bcc.
    # 
    # in_reply_to:: Returns a string that represents the in-reply-to.
    # 
    # message_id:: Returns a string that represents the message-id.
    # 
    Envelope = Struct.new(:date, :subject, :from, :sender, :reply_to,
                          :to, :cc, :bcc, :in_reply_to, :message_id)

    # 
    # Net::IMAP::Address represents electronic mail addresses.
    # 
    # ==== Fields:
    # 
    # name:: Returns the phrase from [RFC-822] mailbox.
    # 
    # route:: Returns the route from [RFC-822] route-addr.
    # 
    # mailbox:: nil indicates end of [RFC-822] group.
    #           If non-nil and host is nil, returns [RFC-822] group name.
    #           Otherwise, returns [RFC-822] local-part
    # 
    # host:: nil indicates [RFC-822] group syntax.
    #        Otherwise, returns [RFC-822] domain name.
    #
    Address = Struct.new(:name, :route, :mailbox, :host)

    # 
    # Net::IMAP::ContentDisposition represents Content-Disposition fields.
    # 
    # ==== Fields:
    # 
    # dsp_type:: Returns the disposition type.
    # 
    # param:: Returns a hash that represents parameters of the Content-Disposition
    #         field.
    # 
    ContentDisposition = Struct.new(:dsp_type, :param)

    # Net::IMAP::ThreadMember represents a thread-node returned 
    # by Net::IMAP#thread
    #
    # ==== Fields:
    #
    # seqno:: The sequence number of this message.
    #
    # children:: an array of Net::IMAP::ThreadMember objects for mail
    # items that are children of this in the thread.
    #
    ThreadMember = Struct.new(:seqno, :children)

    # Net::IMAP::BodyTypeBasic represents basic body structures of messages.
    # 
    # ==== Fields:
    # 
    # media_type:: Returns the content media type name as defined in [MIME-IMB].
    # 
    # subtype:: Returns the content subtype name as defined in [MIME-IMB].
    # 
    # param:: Returns a hash that represents parameters as defined in [MIME-IMB].
    # 
    # content_id:: Returns a string giving the content id as defined in [MIME-IMB].
    # 
    # description:: Returns a string giving the content description as defined in
    #               [MIME-IMB].
    # 
    # encoding:: Returns a string giving the content transfer encoding as defined in
    #            [MIME-IMB].
    # 
    # size:: Returns a number giving the size of the body in octets.
    # 
    # md5:: Returns a string giving the body MD5 value as defined in [MD5].
    # 
    # disposition:: Returns a Net::IMAP::ContentDisposition object giving
    #               the content disposition.
    # 
    # language:: Returns a string or an array of strings giving the body
    #            language value as defined in [LANGUAGE-TAGS].
    # 
    # extension:: Returns extension data.
    # 
    # multipart?:: Returns false.
    # 
    class BodyTypeBasic < Struct.new(:media_type, :subtype,
                                     :param, :content_id,
                                     :description, :encoding, :size,
                                     :md5, :disposition, :language,
                                     :extension)
      def multipart?
        return false
      end

      # Obsolete: use +subtype+ instead.  Calling this will
      # generate a warning message to +stderr+, then return 
      # the value of +subtype+.
      def media_subtype
        $stderr.printf("warning: media_subtype is obsolete.\n")
        $stderr.printf("         use subtype instead.\n")
        return subtype
      end
    end

    # Net::IMAP::BodyTypeText represents TEXT body structures of messages.
    # 
    # ==== Fields:
    # 
    # lines:: Returns the size of the body in text lines.
    # 
    # And Net::IMAP::BodyTypeText has all fields of Net::IMAP::BodyTypeBasic.
    # 
    class BodyTypeText < Struct.new(:media_type, :subtype,
                                    :param, :content_id,
                                    :description, :encoding, :size,
                                    :lines,
                                    :md5, :disposition, :language,
                                    :extension)
      def multipart?
        return false
      end

      # Obsolete: use +subtype+ instead.  Calling this will
      # generate a warning message to +stderr+, then return 
      # the value of +subtype+.
      def media_subtype
        $stderr.printf("warning: media_subtype is obsolete.\n")
        $stderr.printf("         use subtype instead.\n")
        return subtype
      end
    end

    # Net::IMAP::BodyTypeMessage represents MESSAGE/RFC822 body structures of messages.
    # 
    # ==== Fields:
    # 
    # envelope:: Returns a Net::IMAP::Envelope giving the envelope structure.
    # 
    # body:: Returns an object giving the body structure.
    # 
    # And Net::IMAP::BodyTypeMessage has all methods of Net::IMAP::BodyTypeText.
    #
    class BodyTypeMessage < Struct.new(:media_type, :subtype,
                                       :param, :content_id,
                                       :description, :encoding, :size,
                                       :envelope, :body, :lines,
                                       :md5, :disposition, :language,
                                       :extension)
      def multipart?
        return false
      end

      # Obsolete: use +subtype+ instead.  Calling this will
      # generate a warning message to +stderr+, then return 
      # the value of +subtype+.
      def media_subtype
        $stderr.printf("warning: media_subtype is obsolete.\n")
        $stderr.printf("         use subtype instead.\n")
        return subtype
      end
    end

    # Net::IMAP::BodyTypeMultipart represents multipart body structures 
    # of messages.
    # 
    # ==== Fields:
    # 
    # media_type:: Returns the content media type name as defined in [MIME-IMB].
    # 
    # subtype:: Returns the content subtype name as defined in [MIME-IMB].
    # 
    # parts:: Returns multiple parts.
    # 
    # param:: Returns a hash that represents parameters as defined in [MIME-IMB].
    # 
    # disposition:: Returns a Net::IMAP::ContentDisposition object giving
    #               the content disposition.
    # 
    # language:: Returns a string or an array of strings giving the body
    #            language value as defined in [LANGUAGE-TAGS].
    # 
    # extension:: Returns extension data.
    # 
    # multipart?:: Returns true.
    # 
    class BodyTypeMultipart < Struct.new(:media_type, :subtype,
                                         :parts,
                                         :param, :disposition, :language,
                                         :extension)
      def multipart?
        return true
      end

      # Obsolete: use +subtype+ instead.  Calling this will
      # generate a warning message to +stderr+, then return 
      # the value of +subtype+.
      def media_subtype
        $stderr.printf("warning: media_subtype is obsolete.\n")
        $stderr.printf("         use subtype instead.\n")
        return subtype
      end
    end

    class ResponseParser # :nodoc:
      def parse(str)
        @str = str
        @pos = 0
        @lex_state = EXPR_BEG
        @token = nil
        return response
      end

      private

      EXPR_BEG          = :EXPR_BEG
      EXPR_DATA         = :EXPR_DATA
      EXPR_TEXT         = :EXPR_TEXT
      EXPR_RTEXT        = :EXPR_RTEXT
      EXPR_CTEXT        = :EXPR_CTEXT

      T_SPACE   = :SPACE
      T_NIL     = :NIL
      T_NUMBER  = :NUMBER
      T_ATOM    = :ATOM
      T_QUOTED  = :QUOTED
      T_LPAR    = :LPAR
      T_RPAR    = :RPAR
      T_BSLASH  = :BSLASH
      T_STAR    = :STAR
      T_LBRA    = :LBRA
      T_RBRA    = :RBRA
      T_LITERAL = :LITERAL
      T_PLUS    = :PLUS
      T_PERCENT = :PERCENT
      T_CRLF    = :CRLF
      T_EOF     = :EOF
      T_TEXT    = :TEXT

      BEG_REGEXP = /\G(?:\
(?# 1:  SPACE   )( +)|\
(?# 2:  NIL     )(NIL)(?=[\x80-\xff(){ \x00-\x1f\x7f%*"\\\[\]+])|\
(?# 3:  NUMBER  )(\d+)(?=[\x80-\xff(){ \x00-\x1f\x7f%*"\\\[\]+])|\
(?# 4:  ATOM    )([^\x80-\xff(){ \x00-\x1f\x7f%*"\\\[\]+]+)|\
(?# 5:  QUOTED  )"((?:[^\x00\r\n"\\]|\\["\\])*)"|\
(?# 6:  LPAR    )(\()|\
(?# 7:  RPAR    )(\))|\
(?# 8:  BSLASH  )(\\)|\
(?# 9:  STAR    )(\*)|\
(?# 10: LBRA    )(\[)|\
(?# 11: RBRA    )(\])|\
(?# 12: LITERAL )\{(\d+)\}\r\n|\
(?# 13: PLUS    )(\+)|\
(?# 14: PERCENT )(%)|\
(?# 15: CRLF    )(\r\n)|\
(?# 16: EOF     )(\z))/ni

      DATA_REGEXP = /\G(?:\
(?# 1:  SPACE   )( )|\
(?# 2:  NIL     )(NIL)|\
(?# 3:  NUMBER  )(\d+)|\
(?# 4:  QUOTED  )"((?:[^\x00\r\n"\\]|\\["\\])*)"|\
(?# 5:  LITERAL )\{(\d+)\}\r\n|\
(?# 6:  LPAR    )(\()|\
(?# 7:  RPAR    )(\)))/ni

      TEXT_REGEXP = /\G(?:\
(?# 1:  TEXT    )([^\x00\r\n]*))/ni

      RTEXT_REGEXP = /\G(?:\
(?# 1:  LBRA    )(\[)|\
(?# 2:  TEXT    )([^\x00\r\n]*))/ni

      CTEXT_REGEXP = /\G(?:\
(?# 1:  TEXT    )([^\x00\r\n\]]*))/ni

      Token = Struct.new(:symbol, :value)

      def response
        token = lookahead
        case token.symbol
        when T_PLUS
          result = continue_req
        when T_STAR
          result = response_untagged
        else
          result = response_tagged
        end
        match(T_CRLF)
        match(T_EOF)
        return result
      end

      def continue_req
        match(T_PLUS)
        match(T_SPACE)
        return ContinuationRequest.new(resp_text, @str)
      end

      def response_untagged
        match(T_STAR)
        match(T_SPACE)
        token = lookahead
        if token.symbol == T_NUMBER
          return numeric_response
        elsif token.symbol == T_ATOM
          case token.value
          when /\A(?:OK|NO|BAD|BYE|PREAUTH)\z/ni
            return response_cond
          when /\A(?:FLAGS)\z/ni
            return flags_response
          when /\A(?:LIST|LSUB)\z/ni
            return list_response
          when /\A(?:QUOTA)\z/ni
            return getquota_response
          when /\A(?:QUOTAROOT)\z/ni
            return getquotaroot_response
          when /\A(?:ACL)\z/ni
            return getacl_response
          when /\A(?:SEARCH|SORT)\z/ni
            return search_response
          when /\A(?:THREAD)\z/ni
            return thread_response
          when /\A(?:STATUS)\z/ni
            return status_response
          when /\A(?:CAPABILITY)\z/ni
            return capability_response
          else
            return text_response
          end
        else
          parse_error("unexpected token %s", token.symbol)
        end
      end

      def response_tagged
        tag = atom
        match(T_SPACE)
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        return TaggedResponse.new(tag, name, resp_text, @str)
      end

      def response_cond
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        return UntaggedResponse.new(name, resp_text, @str)
      end

      def numeric_response
        n = number
        match(T_SPACE)
        token = match(T_ATOM)
        name = token.value.upcase
        case name
        when "EXISTS", "RECENT", "EXPUNGE"
          return UntaggedResponse.new(name, n, @str)
        when "FETCH"
          shift_token
          match(T_SPACE)
          data = FetchData.new(n, msg_att)
          return UntaggedResponse.new(name, data, @str)
        end
      end

      def msg_att
        match(T_LPAR)
        attr = {}
        while true
          token = lookahead
          case token.symbol
          when T_RPAR
            shift_token
            break
          when T_SPACE
            shift_token
            token = lookahead
          end
          case token.value
          when /\A(?:ENVELOPE)\z/ni
            name, val = envelope_data
          when /\A(?:FLAGS)\z/ni
            name, val = flags_data
          when /\A(?:INTERNALDATE)\z/ni
            name, val = internaldate_data
          when /\A(?:RFC822(?:\.HEADER|\.TEXT)?)\z/ni
            name, val = rfc822_text
          when /\A(?:RFC822\.SIZE)\z/ni
            name, val = rfc822_size
          when /\A(?:BODY(?:STRUCTURE)?)\z/ni
            name, val = body_data
          when /\A(?:UID)\z/ni
            name, val = uid_data
          else
            parse_error("unknown attribute `%s'", token.value)
          end
          attr[name] = val
        end
        return attr
      end

      def envelope_data
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        return name, envelope
      end

      def envelope
        @lex_state = EXPR_DATA
        token = lookahead
        if token.symbol == T_NIL
          shift_token
          result = nil
        else
          match(T_LPAR)
          date = nstring
          match(T_SPACE)
          subject = nstring
          match(T_SPACE)
          from = address_list
          match(T_SPACE)
          sender = address_list
          match(T_SPACE)
          reply_to = address_list
          match(T_SPACE)
          to = address_list
          match(T_SPACE)
          cc = address_list
          match(T_SPACE)
          bcc = address_list
          match(T_SPACE)
          in_reply_to = nstring
          match(T_SPACE)
          message_id = nstring
          match(T_RPAR)
          result = Envelope.new(date, subject, from, sender, reply_to,
                                to, cc, bcc, in_reply_to, message_id)
        end
        @lex_state = EXPR_BEG
        return result
      end

      def flags_data
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        return name, flag_list
      end

      def internaldate_data
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        token = match(T_QUOTED)
        return name, token.value
      end

      def rfc822_text
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        return name, nstring
      end

      def rfc822_size
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        return name, number
      end

      def body_data
        token = match(T_ATOM)
        name = token.value.upcase
        token = lookahead
        if token.symbol == T_SPACE
          shift_token
          return name, body
        end
        name.concat(section)
        token = lookahead
        if token.symbol == T_ATOM
          name.concat(token.value)
          shift_token
        end
        match(T_SPACE)
        data = nstring
        return name, data
      end

      def body
        @lex_state = EXPR_DATA
        token = lookahead
        if token.symbol == T_NIL
          shift_token
          result = nil
        else
          match(T_LPAR)
          token = lookahead
          if token.symbol == T_LPAR
            result = body_type_mpart
          else
            result = body_type_1part
          end
          match(T_RPAR)
        end
        @lex_state = EXPR_BEG
        return result
      end

      def body_type_1part
        token = lookahead
        case token.value
        when /\A(?:TEXT)\z/ni
          return body_type_text
        when /\A(?:MESSAGE)\z/ni
          return body_type_msg
        else
          return body_type_basic
        end
      end

      def body_type_basic
        mtype, msubtype = media_type
        token = lookahead
        if token.symbol == T_RPAR
          return BodyTypeBasic.new(mtype, msubtype)
        end
        match(T_SPACE)
        param, content_id, desc, enc, size = body_fields
        md5, disposition, language, extension = body_ext_1part
        return BodyTypeBasic.new(mtype, msubtype,
                                 param, content_id,
                                 desc, enc, size,
                                 md5, disposition, language, extension)
      end

      def body_type_text
        mtype, msubtype = media_type
        match(T_SPACE)
        param, content_id, desc, enc, size = body_fields
        match(T_SPACE)
        lines = number
        md5, disposition, language, extension = body_ext_1part
        return BodyTypeText.new(mtype, msubtype,
                                param, content_id,
                                desc, enc, size,
                                lines,
                                md5, disposition, language, extension)
      end

      def body_type_msg
        mtype, msubtype = media_type
        match(T_SPACE)
        param, content_id, desc, enc, size = body_fields
        match(T_SPACE)
        env = envelope
        match(T_SPACE)
        b = body
        match(T_SPACE)
        lines = number
        md5, disposition, language, extension = body_ext_1part
        return BodyTypeMessage.new(mtype, msubtype,
                                   param, content_id,
                                   desc, enc, size,
                                   env, b, lines,
                                   md5, disposition, language, extension)
      end

      def body_type_mpart
        parts = []
        while true
          token = lookahead
          if token.symbol == T_SPACE
            shift_token
            break
          end
          parts.push(body)
        end
        mtype = "MULTIPART"
        msubtype = case_insensitive_string
        param, disposition, language, extension = body_ext_mpart
        return BodyTypeMultipart.new(mtype, msubtype, parts,
                                     param, disposition, language,
                                     extension)
      end

      def media_type
        mtype = case_insensitive_string
        match(T_SPACE)
        msubtype = case_insensitive_string
        return mtype, msubtype
      end

      def body_fields
        param = body_fld_param
        match(T_SPACE)
        content_id = nstring
        match(T_SPACE)
        desc = nstring
        match(T_SPACE)
        enc = case_insensitive_string
        match(T_SPACE)
        size = number
        return param, content_id, desc, enc, size
      end

      def body_fld_param
        token = lookahead
        if token.symbol == T_NIL
          shift_token
          return nil
        end
        match(T_LPAR)
        param = {}
        while true
          token = lookahead
          case token.symbol
          when T_RPAR
            shift_token
            break
          when T_SPACE
            shift_token
          end
          name = case_insensitive_string
          match(T_SPACE)
          val = string
          param[name] = val
        end
        return param
      end

      def body_ext_1part
        token = lookahead
        if token.symbol == T_SPACE
          shift_token
        else
          return nil
        end
        md5 = nstring

        token = lookahead
        if token.symbol == T_SPACE
          shift_token
        else
          return md5
        end
        disposition = body_fld_dsp

        token = lookahead
        if token.symbol == T_SPACE
          shift_token
        else
          return md5, disposition
        end
        language = body_fld_lang

        token = lookahead
        if token.symbol == T_SPACE
          shift_token
        else
          return md5, disposition, language
        end

        extension = body_extensions
        return md5, disposition, language, extension
      end

      def body_ext_mpart
        token = lookahead
        if token.symbol == T_SPACE
          shift_token
        else
          return nil
        end
        param = body_fld_param

        token = lookahead
        if token.symbol == T_SPACE
          shift_token
        else
          return param
        end
        disposition = body_fld_dsp
        match(T_SPACE)
        language = body_fld_lang

        token = lookahead
        if token.symbol == T_SPACE
          shift_token
        else
          return param, disposition, language
        end

        extension = body_extensions
        return param, disposition, language, extension
      end

      def body_fld_dsp
        token = lookahead
        if token.symbol == T_NIL
          shift_token
          return nil
        end
        match(T_LPAR)
        dsp_type = case_insensitive_string
        match(T_SPACE)
        param = body_fld_param
        match(T_RPAR)
        return ContentDisposition.new(dsp_type, param)
      end

      def body_fld_lang
        token = lookahead
        if token.symbol == T_LPAR
          shift_token
          result = []
          while true
            token = lookahead
            case token.symbol
            when T_RPAR
              shift_token
              return result
            when T_SPACE
              shift_token
            end
            result.push(case_insensitive_string)
          end
        else
          lang = nstring
          if lang
            return lang.upcase
          else
            return lang
          end
        end
      end

      def body_extensions
        result = []
        while true
          token = lookahead
          case token.symbol
          when T_RPAR
            return result
          when T_SPACE
            shift_token
          end
          result.push(body_extension)
        end
      end

      def body_extension
        token = lookahead
        case token.symbol
        when T_LPAR
          shift_token
          result = body_extensions
          match(T_RPAR)
          return result
        when T_NUMBER
          return number
        else
          return nstring
        end
      end

      def section
        str = ""
        token = match(T_LBRA)
        str.concat(token.value)
        token = match(T_ATOM, T_NUMBER, T_RBRA)
        if token.symbol == T_RBRA
          str.concat(token.value)
          return str
        end
        str.concat(token.value)
        token = lookahead
        if token.symbol == T_SPACE
          shift_token
          str.concat(token.value)
          token = match(T_LPAR)
          str.concat(token.value)
          while true
            token = lookahead
            case token.symbol
            when T_RPAR
              str.concat(token.value)
              shift_token
              break
            when T_SPACE
              shift_token
              str.concat(token.value)
            end
            str.concat(format_string(astring))
          end
        end
        token = match(T_RBRA)
        str.concat(token.value)
        return str
      end

      def format_string(str)
        case str
        when ""
          return '""'
        when /[\x80-\xff\r\n]/n
          # literal
          return "{" + str.length.to_s + "}" + CRLF + str
        when /[(){ \x00-\x1f\x7f%*"\\]/n
          # quoted string
          return '"' + str.gsub(/["\\]/n, "\\\\\\&") + '"'
        else
          # atom
          return str
        end
      end

      def uid_data
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        return name, number
      end

      def text_response
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        @lex_state = EXPR_TEXT
        token = match(T_TEXT)
        @lex_state = EXPR_BEG
        return UntaggedResponse.new(name, token.value)
      end

      def flags_response
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        return UntaggedResponse.new(name, flag_list, @str)
      end

      def list_response
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        return UntaggedResponse.new(name, mailbox_list, @str)
      end

      def mailbox_list
        attr = flag_list
        match(T_SPACE)
        token = match(T_QUOTED, T_NIL)
        if token.symbol == T_NIL
          delim = nil
        else
          delim = token.value
        end
        match(T_SPACE)
        name = astring
        return MailboxList.new(attr, delim, name)
      end

      def getquota_response
        # If quota never established, get back
        # `NO Quota root does not exist'.
        # If quota removed, get `()' after the
        # folder spec with no mention of `STORAGE'.
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        mailbox = astring
        match(T_SPACE)
        match(T_LPAR)
        token = lookahead
        case token.symbol
        when T_RPAR
          shift_token
          data = MailboxQuota.new(mailbox, nil, nil)
          return UntaggedResponse.new(name, data, @str)
        when T_ATOM
          shift_token
          match(T_SPACE)
          token = match(T_NUMBER)
          usage = token.value
          match(T_SPACE)
          token = match(T_NUMBER)
          quota = token.value
          match(T_RPAR)
          data = MailboxQuota.new(mailbox, usage, quota)
          return UntaggedResponse.new(name, data, @str)
        else
          parse_error("unexpected token %s", token.symbol)
        end
      end

      def getquotaroot_response
        # Similar to getquota, but only admin can use getquota.
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        mailbox = astring
        quotaroots = []
        while true
          token = lookahead
          break unless token.symbol == T_SPACE
          shift_token
          quotaroots.push(astring)
        end
        data = MailboxQuotaRoot.new(mailbox, quotaroots)
        return UntaggedResponse.new(name, data, @str)
      end

      def getacl_response
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        mailbox = astring
        data = []
        token = lookahead
        if token.symbol == T_SPACE
          shift_token
          while true
            token = lookahead
            case token.symbol
            when T_CRLF
              break
            when T_SPACE
              shift_token
            end
            user = astring
            match(T_SPACE)
            rights = astring
            ##XXX data.push([user, rights])
            data.push(MailboxACLItem.new(user, rights))
          end
        end
        return UntaggedResponse.new(name, data, @str)
      end

      def search_response
        token = match(T_ATOM)
        name = token.value.upcase
        token = lookahead
        if token.symbol == T_SPACE
          shift_token
          data = []
          while true
            token = lookahead
            case token.symbol
            when T_CRLF
              break
            when T_SPACE
              shift_token
            end
            data.push(number)
          end
        else
          data = []
        end
        return UntaggedResponse.new(name, data, @str)
      end

      def thread_response
        token = match(T_ATOM)
        name = token.value.upcase
        token = lookahead

        if token.symbol == T_SPACE
          threads = []

          while true
            shift_token
            token = lookahead

            case token.symbol
            when T_LPAR
              threads << thread_branch(token)
            when T_CRLF
              break
            end
          end
        else
          # no member
          threads = []
        end

        return UntaggedResponse.new(name, threads, @str)
      end

      def thread_branch(token)
        rootmember = nil
        lastmember = nil
        
        while true
          shift_token    # ignore first T_LPAR
          token = lookahead
          
          case token.symbol
          when T_NUMBER
            # new member
            newmember = ThreadMember.new(number, [])
            if rootmember.nil?
              rootmember = newmember
            else    
              lastmember.children << newmember
            end     
            lastmember = newmember
          when T_SPACE 
            # do nothing 
          when T_LPAR
            if rootmember.nil?
              # dummy member
              lastmember = rootmember = ThreadMember.new(nil, [])
            end     
            
            lastmember.children << thread_branch(token)
          when T_RPAR
            break   
          end     
        end
        
        return rootmember
      end

      def status_response
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        mailbox = astring
        match(T_SPACE)
        match(T_LPAR)
        attr = {}
        while true
          token = lookahead
          case token.symbol
          when T_RPAR
            shift_token
            break
          when T_SPACE
            shift_token
          end
          token = match(T_ATOM)
          key = token.value.upcase
          match(T_SPACE)
          val = number
          attr[key] = val
        end
        data = StatusData.new(mailbox, attr)
        return UntaggedResponse.new(name, data, @str)
      end

      def capability_response
        token = match(T_ATOM)
        name = token.value.upcase
        match(T_SPACE)
        data = []
        while true
          token = lookahead
          case token.symbol
          when T_CRLF
            break
          when T_SPACE
            shift_token
          end
          data.push(atom.upcase)
        end
        return UntaggedResponse.new(name, data, @str)
      end

      def resp_text
        @lex_state = EXPR_RTEXT
        token = lookahead
        if token.symbol == T_LBRA
          code = resp_text_code
        else
          code = nil
        end
        token = match(T_TEXT)
        @lex_state = EXPR_BEG
        return ResponseText.new(code, token.value)
      end

      def resp_text_code
        @lex_state = EXPR_BEG
        match(T_LBRA)
        token = match(T_ATOM)
        name = token.value.upcase
        case name
        when /\A(?:ALERT|PARSE|READ-ONLY|READ-WRITE|TRYCREATE|NOMODSEQ)\z/n
          result = ResponseCode.new(name, nil)
        when /\A(?:PERMANENTFLAGS)\z/n
          match(T_SPACE)
          result = ResponseCode.new(name, flag_list)
        when /\A(?:UIDVALIDITY|UIDNEXT|UNSEEN)\z/n
          match(T_SPACE)
          result = ResponseCode.new(name, number)
        else
          token = lookahead
          if token.symbol == T_SPACE
            shift_token
            @lex_state = EXPR_CTEXT
            token = match(T_TEXT)
            @lex_state = EXPR_BEG
            result = ResponseCode.new(name, token.value)
          else
            result = ResponseCode.new(name, nil)
          end
        end
        match(T_RBRA)
        @lex_state = EXPR_RTEXT
        return result
      end

      def address_list
        token = lookahead
        if token.symbol == T_NIL
          shift_token
          return nil
        else
          result = []
          match(T_LPAR)
          while true
            token = lookahead
            case token.symbol
            when T_RPAR
              shift_token
              break
            when T_SPACE
              shift_token
            end
            result.push(address)
          end
          return result
        end
      end

      ADDRESS_REGEXP = /\G\
(?# 1: NAME     )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
(?# 2: ROUTE    )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
(?# 3: MAILBOX  )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
(?# 4: HOST     )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)")\
\)/ni

      def address
        match(T_LPAR)
        if @str.index(ADDRESS_REGEXP, @pos)
          # address does not include literal.
          @pos = $~.end(0)
          name = $1
          route = $2
          mailbox = $3
          host = $4
          for s in [name, route, mailbox, host]
            if s
              s.gsub!(/\\(["\\])/n, "\\1")
            end
          end
        else
          name = nstring
          match(T_SPACE)
          route = nstring
          match(T_SPACE)
          mailbox = nstring
          match(T_SPACE)
          host = nstring
          match(T_RPAR)
        end
        return Address.new(name, route, mailbox, host)
      end

#        def flag_list
#       result = []
#       match(T_LPAR)
#       while true
#         token = lookahead
#         case token.symbol
#         when T_RPAR
#           shift_token
#           break
#         when T_SPACE
#           shift_token
#         end
#         result.push(flag)
#       end
#       return result
#        end

#        def flag
#       token = lookahead
#       if token.symbol == T_BSLASH
#         shift_token
#         token = lookahead
#         if token.symbol == T_STAR
#           shift_token
#           return token.value.intern
#         else
#           return atom.intern
#         end
#       else
#         return atom
#       end
#        end

      FLAG_REGEXP = /\
(?# FLAG        )\\([^\x80-\xff(){ \x00-\x1f\x7f%"\\]+)|\
(?# ATOM        )([^\x80-\xff(){ \x00-\x1f\x7f%*"\\]+)/n

      def flag_list
        if @str.index(/\(([^)]*)\)/ni, @pos)
          @pos = $~.end(0)
          return $1.scan(FLAG_REGEXP).collect { |flag, atom|
            atom || flag.capitalize.intern
          }
        else
          parse_error("invalid flag list")
        end
      end

      def nstring
        token = lookahead
        if token.symbol == T_NIL
          shift_token
          return nil
        else
          return string
        end
      end

      def astring
        token = lookahead
        if string_token?(token)
          return string
        else
          return atom
        end
      end

      def string
        token = lookahead
        if token.symbol == T_NIL
          shift_token
          return nil
        end
        token = match(T_QUOTED, T_LITERAL)
        return token.value
      end

      STRING_TOKENS = [T_QUOTED, T_LITERAL, T_NIL]

      def string_token?(token)
        return STRING_TOKENS.include?(token.symbol)
      end

      def case_insensitive_string
        token = lookahead
        if token.symbol == T_NIL
          shift_token
          return nil
        end
        token = match(T_QUOTED, T_LITERAL)
        return token.value.upcase
      end

      def atom
        result = ""
        while true
          token = lookahead
          if atom_token?(token)
            result.concat(token.value)
            shift_token
          else
            if result.empty?
              parse_error("unexpected token %s", token.symbol)
            else
              return result
            end
          end
        end
      end

      ATOM_TOKENS = [
        T_ATOM,
        T_NUMBER,
        T_NIL,
        T_LBRA,
        T_RBRA,
        T_PLUS
      ]

      def atom_token?(token)
        return ATOM_TOKENS.include?(token.symbol)
      end

      def number
        token = lookahead
        if token.symbol == T_NIL
          shift_token
          return nil
        end
        token = match(T_NUMBER)
        return token.value.to_i
      end

      def nil_atom
        match(T_NIL)
        return nil
      end

      def match(*args)
        token = lookahead
        unless args.include?(token.symbol)
          parse_error('unexpected token %s (expected %s)',
                      token.symbol.id2name,
                      args.collect {|i| i.id2name}.join(" or "))
        end
        shift_token
        return token
      end

      def lookahead
        unless @token
          @token = next_token
        end
        return @token
      end

      def shift_token
        @token = nil
      end

      def next_token
        case @lex_state
        when EXPR_BEG
          if @str.index(BEG_REGEXP, @pos)
            @pos = $~.end(0)
            if $1
              return Token.new(T_SPACE, $+)
            elsif $2
              return Token.new(T_NIL, $+)
            elsif $3
              return Token.new(T_NUMBER, $+)
            elsif $4
              return Token.new(T_ATOM, $+)
            elsif $5
              return Token.new(T_QUOTED,
                               $+.gsub(/\\(["\\])/n, "\\1"))
            elsif $6
              return Token.new(T_LPAR, $+)
            elsif $7
              return Token.new(T_RPAR, $+)
            elsif $8
              return Token.new(T_BSLASH, $+)
            elsif $9
              return Token.new(T_STAR, $+)
            elsif $10
              return Token.new(T_LBRA, $+)
            elsif $11
              return Token.new(T_RBRA, $+)
            elsif $12
              len = $+.to_i
              val = @str[@pos, len]
              @pos += len
              return Token.new(T_LITERAL, val)
            elsif $13
              return Token.new(T_PLUS, $+)
            elsif $14
              return Token.new(T_PERCENT, $+)
            elsif $15
              return Token.new(T_CRLF, $+)
            elsif $16
              return Token.new(T_EOF, $+)
            else
              parse_error("[Net::IMAP BUG] BEG_REGEXP is invalid")
            end
          else
            @str.index(/\S*/n, @pos)
            parse_error("unknown token - %s", $&.dump)
          end
        when EXPR_DATA
          if @str.index(DATA_REGEXP, @pos)
            @pos = $~.end(0)
            if $1
              return Token.new(T_SPACE, $+)
            elsif $2
              return Token.new(T_NIL, $+)
            elsif $3
              return Token.new(T_NUMBER, $+)
            elsif $4
              return Token.new(T_QUOTED,
                               $+.gsub(/\\(["\\])/n, "\\1"))
            elsif $5
              len = $+.to_i
              val = @str[@pos, len]
              @pos += len
              return Token.new(T_LITERAL, val)
            elsif $6
              return Token.new(T_LPAR, $+)
            elsif $7
              return Token.new(T_RPAR, $+)
            else
              parse_error("[Net::IMAP BUG] DATA_REGEXP is invalid")
            end
          else
            @str.index(/\S*/n, @pos)
            parse_error("unknown token - %s", $&.dump)
          end
        when EXPR_TEXT
          if @str.index(TEXT_REGEXP, @pos)
            @pos = $~.end(0)
            if $1
              return Token.new(T_TEXT, $+)
            else
              parse_error("[Net::IMAP BUG] TEXT_REGEXP is invalid")
            end
          else
            @str.index(/\S*/n, @pos)
            parse_error("unknown token - %s", $&.dump)
          end
        when EXPR_RTEXT
          if @str.index(RTEXT_REGEXP, @pos)
            @pos = $~.end(0)
            if $1
              return Token.new(T_LBRA, $+)
            elsif $2
              return Token.new(T_TEXT, $+)
            else
              parse_error("[Net::IMAP BUG] RTEXT_REGEXP is invalid")
            end
          else
            @str.index(/\S*/n, @pos)
            parse_error("unknown token - %s", $&.dump)
          end
        when EXPR_CTEXT
          if @str.index(CTEXT_REGEXP, @pos)
            @pos = $~.end(0)
            if $1
              return Token.new(T_TEXT, $+)
            else
              parse_error("[Net::IMAP BUG] CTEXT_REGEXP is invalid")
            end
          else
            @str.index(/\S*/n, @pos) #/
            parse_error("unknown token - %s", $&.dump)
          end
        else
          parse_error("illegal @lex_state - %s", @lex_state.inspect)
        end
      end

      def parse_error(fmt, *args)
        if IMAP.debug
          $stderr.printf("@str: %s\n", @str.dump)
          $stderr.printf("@pos: %d\n", @pos)
          $stderr.printf("@lex_state: %s\n", @lex_state)
          if @token
            $stderr.printf("@token.symbol: %s\n", @token.symbol)
            $stderr.printf("@token.value: %s\n", @token.value.inspect)
          end
        end
        raise ResponseParseError, format(fmt, *args)
      end
    end

    # Authenticator for the "LOGIN" authentication type.  See
    # #authenticate().
    class LoginAuthenticator
      def process(data)
        case @state
        when STATE_USER
          @state = STATE_PASSWORD
          return @user
        when STATE_PASSWORD
          return @password
        end
      end

      private

      STATE_USER = :USER
      STATE_PASSWORD = :PASSWORD

      def initialize(user, password)
        @user = user
        @password = password
        @state = STATE_USER
      end
    end
    add_authenticator "LOGIN", LoginAuthenticator

    # Authenticator for the "CRAM-MD5" authentication type.  See
    # #authenticate().
    class CramMD5Authenticator
      def process(challenge)
        digest = hmac_md5(challenge, @password)
        return @user + " " + digest
      end

      private

      def initialize(user, password)
        @user = user
        @password = password
      end

      def hmac_md5(text, key)
        if key.length > 64
          key = Digest::MD5.digest(key)
        end

        k_ipad = key + "\0" * (64 - key.length)
        k_opad = key + "\0" * (64 - key.length)
        for i in 0..63
          k_ipad[i] ^= 0x36
          k_opad[i] ^= 0x5c
        end

        digest = Digest::MD5.digest(k_ipad + text)

        return Digest::MD5.hexdigest(k_opad + digest)
      end
    end
    add_authenticator "CRAM-MD5", CramMD5Authenticator

    # Superclass of IMAP errors.
    class Error < StandardError
    end

    # Error raised when data is in the incorrect format.
    class DataFormatError < Error
    end

    # Error raised when a response from the server is non-parseable.
    class ResponseParseError < Error
    end

    # Superclass of all errors used to encapsulate "fail" responses
    # from the server.
    class ResponseError < Error
    end

    # Error raised upon a "NO" response from the server, indicating
    # that the client command could not be completed successfully.
    class NoResponseError < ResponseError
    end

    # Error raised upon a "BAD" response from the server, indicating
    # that the client command violated the IMAP protocol, or an internal
    # server failure has occurred.
    class BadResponseError < ResponseError
    end

    # Error raised upon a "BYE" response from the server, indicating 
    # that the client is not being allowed to login, or has been timed
    # out due to inactivity.
    class ByeResponseError < ResponseError
    end
  end
end

if __FILE__ == $0
  # :enddoc:
  require "getoptlong"

  $stdout.sync = true
  $port = nil
  $user = ENV["USER"] || ENV["LOGNAME"]
  $auth = "login"
  $ssl = false

  def usage
    $stderr.print <<EOF
usage: #{$0} [options] <host>

  --help                        print this message
  --port=PORT                   specifies port
  --user=USER                   specifies user
  --auth=AUTH                   specifies auth type
  --ssl                         use ssl
EOF
  end

  def get_password
    print "password: "
    system("stty", "-echo")
    begin
      return gets.chop
    ensure
      system("stty", "echo")
      print "\n"
    end
  end

  def get_command
    printf("%s@%s> ", $user, $host)
    if line = gets
      return line.strip.split(/\s+/)
    else
      return nil
    end
  end

  parser = GetoptLong.new
  parser.set_options(['--debug', GetoptLong::NO_ARGUMENT],
                     ['--help', GetoptLong::NO_ARGUMENT],
                     ['--port', GetoptLong::REQUIRED_ARGUMENT],
                     ['--user', GetoptLong::REQUIRED_ARGUMENT],
                     ['--auth', GetoptLong::REQUIRED_ARGUMENT],
                     ['--ssl', GetoptLong::NO_ARGUMENT])
  begin
    parser.each_option do |name, arg|
      case name
      when "--port"
        $port = arg
      when "--user"
        $user = arg
      when "--auth"
        $auth = arg
      when "--ssl"
        $ssl = true
      when "--debug"
        Net::IMAP.debug = true
      when "--help"
        usage
        exit(1)
      end
    end
  rescue
    usage
    exit(1)
  end

  $host = ARGV.shift
  unless $host
    usage
    exit(1)
  end
  $port ||= $ssl ? 993 : 143
    
  imap = Net::IMAP.new($host, $port, $ssl)
  begin
    password = get_password
    imap.authenticate($auth, $user, password)
    while true
      cmd, *args = get_command
      break unless cmd
      begin
        case cmd
        when "list"
          for mbox in imap.list("", args[0] || "*")
            if mbox.attr.include?(Net::IMAP::NOSELECT)
              prefix = "!"
            elsif mbox.attr.include?(Net::IMAP::MARKED)
              prefix = "*"
            else
              prefix = " "
            end
            print prefix, mbox.name, "\n"
          end
        when "select"
          imap.select(args[0] || "inbox")
          print "ok\n"
        when "close"
          imap.close
          print "ok\n"
        when "summary"
          unless messages = imap.responses["EXISTS"][-1]
            puts "not selected"
            next
          end
          if messages > 0
            for data in imap.fetch(1..-1, ["ENVELOPE"])
              print data.seqno, ": ", data.attr["ENVELOPE"].subject, "\n"
            end
          else
            puts "no message"
          end
        when "fetch"
          if args[0]
            data = imap.fetch(args[0].to_i, ["RFC822.HEADER", "RFC822.TEXT"])[0]
            puts data.attr["RFC822.HEADER"]
            puts data.attr["RFC822.TEXT"]
          else
            puts "missing argument"
          end
        when "logout", "exit", "quit"
          break
        when "help", "?"
          print <<EOF
list [pattern]                  list mailboxes
select [mailbox]                select mailbox
close                           close mailbox
summary                         display summary
fetch [msgno]                   display message
logout                          logout
help, ?                         display help message
EOF
        else
          print "unknown command: ", cmd, "\n"
        end
      rescue Net::IMAP::Error
        puts $!
      end
    end
  ensure
    imap.logout
    imap.disconnect
  end
end

PK     QZ\w;`      net/protocol.rbnu [        #
# = net/protocol.rb
#
#--
# Copyright (c) 1999-2005 Yukihiro Matsumoto
# Copyright (c) 1999-2005 Minero Aoki
#
# written and maintained by Minero Aoki <aamine@loveruby.net>
#
# This program is free software. You can re-distribute and/or
# modify this program under the same terms as Ruby itself,
# Ruby Distribute License or GNU General Public License.
#
# $Id: protocol.rb 12092 2007-03-19 02:39:22Z aamine $
#++
#
# WARNING: This file is going to remove.
# Do not rely on the implementation written in this file.
#

require 'socket'
require 'timeout'

module Net # :nodoc:

  class Protocol   #:nodoc: internal use only
    private
    def Protocol.protocol_param(name, val)
      module_eval(<<-End, __FILE__, __LINE__ + 1)
        def #{name}
          #{val}
        end
      End
    end
  end


  class ProtocolError          < StandardError; end
  class ProtoSyntaxError       < ProtocolError; end
  class ProtoFatalError        < ProtocolError; end
  class ProtoUnknownError      < ProtocolError; end
  class ProtoServerError       < ProtocolError; end
  class ProtoAuthError         < ProtocolError; end
  class ProtoCommandError      < ProtocolError; end
  class ProtoRetriableError    < ProtocolError; end
  ProtocRetryError = ProtoRetriableError


  class BufferedIO   #:nodoc: internal use only
    def initialize(io)
      @io = io
      @read_timeout = 60
      @debug_output = nil
      @rbuf = ''
    end

    attr_reader :io
    attr_accessor :read_timeout
    attr_accessor :debug_output

    def inspect
      "#<#{self.class} io=#{@io}>"
    end

    def closed?
      @io.closed?
    end

    def close
      @io.close
    end

    #
    # Read
    #

    public

    def read(len, dest = '', ignore_eof = false)
      LOG "reading #{len} bytes..."
      read_bytes = 0
      begin
        while read_bytes + @rbuf.size < len
          dest << (s = rbuf_consume(@rbuf.size))
          read_bytes += s.size
          rbuf_fill
        end
        dest << (s = rbuf_consume(len - read_bytes))
        read_bytes += s.size
      rescue EOFError
        raise unless ignore_eof
      end
      LOG "read #{read_bytes} bytes"
      dest
    end

    def read_all(dest = '')
      LOG 'reading all...'
      read_bytes = 0
      begin
        while true
          dest << (s = rbuf_consume(@rbuf.size))
          read_bytes += s.size
          rbuf_fill
        end
      rescue EOFError
        ;
      end
      LOG "read #{read_bytes} bytes"
      dest
    end

    def readuntil(terminator, ignore_eof = false)
      begin
        until idx = @rbuf.index(terminator)
          rbuf_fill
        end
        return rbuf_consume(idx + terminator.size)
      rescue EOFError
        raise unless ignore_eof
        return rbuf_consume(@rbuf.size)
      end
    end
        
    def readline
      readuntil("\n").chop
    end

    private

    BUFSIZE = 1024 * 16

    def rbuf_fill
      timeout(@read_timeout) {
        @rbuf << @io.sysread(BUFSIZE)
      }
    end

    def rbuf_consume(len)
      s = @rbuf.slice!(0, len)
      @debug_output << %Q[-> #{s.dump}\n] if @debug_output
      s
    end

    #
    # Write
    #

    public

    def write(str)
      writing {
        write0 str
      }
    end

    def writeline(str)
      writing {
        write0 str + "\r\n"
      }
    end

    private

    def writing
      @written_bytes = 0
      @debug_output << '<- ' if @debug_output
      yield
      @debug_output << "\n" if @debug_output
      bytes = @written_bytes
      @written_bytes = nil
      bytes
    end

    def write0(str)
      @debug_output << str.dump if @debug_output
      len = @io.write(str)
      @written_bytes += len
      len
    end

    #
    # Logging
    #

    private

    def LOG_off
      @save_debug_out = @debug_output
      @debug_output = nil
    end

    def LOG_on
      @debug_output = @save_debug_out
    end

    def LOG(msg)
      return unless @debug_output
      @debug_output << msg + "\n"
    end
  end


  class InternetMessageIO < BufferedIO   #:nodoc: internal use only
    def InternetMessageIO.old_open(addr, port,
        open_timeout = nil, read_timeout = nil, debug_output = nil)
      debug_output << "opening connection to #{addr}...\n" if debug_output
      s = timeout(open_timeout) { TCPsocket.new(addr, port) }
      io = new(s)
      io.read_timeout = read_timeout
      io.debug_output = debug_output
      io
    end

    def initialize(io)
      super
      @wbuf = nil
    end

    #
    # Read
    #

    def each_message_chunk
      LOG 'reading message...'
      LOG_off()
      read_bytes = 0
      while (line = readuntil("\r\n")) != ".\r\n"
        read_bytes += line.size
        yield line.sub(/\A\./, '')
      end
      LOG_on()
      LOG "read message (#{read_bytes} bytes)"
    end
  
    # *library private* (cannot handle 'break')
    def each_list_item
      while (str = readuntil("\r\n")) != ".\r\n"
        yield str.chop
      end
    end

    def write_message_0(src)
      prev = @written_bytes
      each_crlf_line(src) do |line|
        write0 line.sub(/\A\./, '..')
      end
      @written_bytes - prev
    end

    #
    # Write
    #

    def write_message(src)
      LOG "writing message from #{src.class}"
      LOG_off()
      len = writing {
        using_each_crlf_line {
          write_message_0 src
        }
      }
      LOG_on()
      LOG "wrote #{len} bytes"
      len
    end

    def write_message_by_block(&block)
      LOG 'writing message from block'
      LOG_off()
      len = writing {
        using_each_crlf_line {
          begin
            block.call(WriteAdapter.new(self, :write_message_0))
          rescue LocalJumpError
            # allow `break' from writer block
          end
        }
      }
      LOG_on()
      LOG "wrote #{len} bytes"
      len
    end

    private

    def using_each_crlf_line
      @wbuf = ''
      yield
      if not @wbuf.empty?   # unterminated last line
        write0 @wbuf.chomp + "\r\n"
      elsif @written_bytes == 0   # empty src
        write0 "\r\n"
      end
      write0 ".\r\n"
      @wbuf = nil
    end

    def each_crlf_line(src)
      buffer_filling(@wbuf, src) do
        while line = @wbuf.slice!(/\A.*(?:\n|\r\n|\r(?!\z))/n)
          yield line.chomp("\n") + "\r\n"
        end
      end
    end

    def buffer_filling(buf, src)
      case src
      when String    # for speeding up.
        0.step(src.size - 1, 1024) do |i|
          buf << src[i, 1024]
          yield
        end
      when File    # for speeding up.
        while s = src.read(1024)
          buf << s
          yield
        end
      else    # generic reader
        src.each do |s|
          buf << s
          yield if buf.size > 1024
        end
        yield unless buf.empty?
      end
    end
  end


  #
  # The writer adapter class
  #
  class WriteAdapter
    def initialize(socket, method)
      @socket = socket
      @method_id = method
    end

    def inspect
      "#<#{self.class} socket=#{@socket.inspect}>"
    end

    def write(str)
      @socket.__send__(@method_id, str)
    end

    alias print write

    def <<(str)
      write str
      self
    end

    def puts(str = '')
      write str.chomp("\n") + "\n"
    end

    def printf(*args)
      write sprintf(*args)
    end
  end


  class ReadAdapter   #:nodoc: internal use only
    def initialize(block)
      @block = block
    end

    def inspect
      "#<#{self.class}>"
    end

    def <<(str)
      call_block(str, &@block) if @block
    end

    private

    # This method is needed because @block must be called by yield,
    # not Proc#call.  You can see difference when using `break' in
    # the block.
    def call_block(str)
      yield str
    end
  end


  module NetPrivate   #:nodoc: obsolete
    Socket = ::Net::InternetMessageIO
  end

end   # module Net
PK     RZ\^/Yap  p    net/smtp.rbnu [        # = net/smtp.rb
# 
# Copyright (c) 1999-2007 Yukihiro Matsumoto.
#
# Copyright (c) 1999-2007 Minero Aoki.
# 
# Written & maintained by Minero Aoki <aamine@loveruby.net>.
#
# Documented by William Webber and Minero Aoki.
# 
# This program is free software. You can re-distribute and/or
# modify this program under the same terms as Ruby itself.
# 
# NOTE: You can find Japanese version of this document at:
# http://www.ruby-lang.org/ja/man/html/net_smtp.html
# 
# $Id: smtp.rb 28208 2010-06-08 06:14:59Z shyouhei $
#
# See Net::SMTP for documentation. 
# 

require 'net/protocol'
require 'digest/md5'
require 'timeout'
begin
  require 'openssl'
rescue LoadError
end

module Net

  # Module mixed in to all SMTP error classes
  module SMTPError
    # This *class* is a module for backward compatibility.
    # In later release, this module becomes a class.
  end

  # Represents an SMTP authentication error.
  class SMTPAuthenticationError < ProtoAuthError
    include SMTPError
  end

  # Represents SMTP error code 420 or 450, a temporary error.
  class SMTPServerBusy < ProtoServerError
    include SMTPError
  end

  # Represents an SMTP command syntax error (error code 500)
  class SMTPSyntaxError < ProtoSyntaxError
    include SMTPError
  end

  # Represents a fatal SMTP error (error code 5xx, except for 500)
  class SMTPFatalError < ProtoFatalError
    include SMTPError
  end

  # Unexpected reply code returned from server.
  class SMTPUnknownError < ProtoUnknownError
    include SMTPError
  end

  # Command is not supported on server.
  class SMTPUnsupportedCommand < ProtocolError
    include SMTPError
  end

  #
  # = Net::SMTP
  #
  # == What is This Library?
  # 
  # This library provides functionality to send internet
  # mail via SMTP, the Simple Mail Transfer Protocol. For details of
  # SMTP itself, see [RFC2821] (http://www.ietf.org/rfc/rfc2821.txt).
  # 
  # == What is This Library NOT?
  # 
  # This library does NOT provide functions to compose internet mails.
  # You must create them by yourself. If you want better mail support,
  # try RubyMail or TMail. You can get both libraries from RAA.
  # (http://www.ruby-lang.org/en/raa.html)
  # 
  # FYI: the official documentation on internet mail is: [RFC2822] (http://www.ietf.org/rfc/rfc2822.txt).
  # 
  # == Examples
  # 
  # === Sending Messages
  # 
  # You must open a connection to an SMTP server before sending messages.
  # The first argument is the address of your SMTP server, and the second 
  # argument is the port number. Using SMTP.start with a block is the simplest 
  # way to do this. This way, the SMTP connection is closed automatically 
  # after the block is executed.
  # 
  #     require 'net/smtp'
  #     Net::SMTP.start('your.smtp.server', 25) do |smtp|
  #       # Use the SMTP object smtp only in this block.
  #     end
  # 
  # Replace 'your.smtp.server' with your SMTP server. Normally
  # your system manager or internet provider supplies a server
  # for you.
  # 
  # Then you can send messages.
  # 
  #     msgstr = <<END_OF_MESSAGE
  #     From: Your Name <your@mail.address>
  #     To: Destination Address <someone@example.com>
  #     Subject: test message
  #     Date: Sat, 23 Jun 2001 16:26:43 +0900
  #     Message-Id: <unique.message.id.string@example.com>
  # 
  #     This is a test message.
  #     END_OF_MESSAGE
  # 
  #     require 'net/smtp'
  #     Net::SMTP.start('your.smtp.server', 25) do |smtp|
  #       smtp.send_message msgstr,
  #                         'your@mail.address',
  #                         'his_addess@example.com'
  #     end
  # 
  # === Closing the Session
  # 
  # You MUST close the SMTP session after sending messages, by calling 
  # the #finish method:
  # 
  #     # using SMTP#finish
  #     smtp = Net::SMTP.start('your.smtp.server', 25)
  #     smtp.send_message msgstr, 'from@address', 'to@address'
  #     smtp.finish
  # 
  # You can also use the block form of SMTP.start/SMTP#start.  This closes
  # the SMTP session automatically:
  # 
  #     # using block form of SMTP.start
  #     Net::SMTP.start('your.smtp.server', 25) do |smtp|
  #       smtp.send_message msgstr, 'from@address', 'to@address'
  #     end
  # 
  # I strongly recommend this scheme.  This form is simpler and more robust.
  # 
  # === HELO domain
  # 
  # In almost all situations, you must provide a third argument
  # to SMTP.start/SMTP#start. This is the domain name which you are on
  # (the host to send mail from). It is called the "HELO domain".
  # The SMTP server will judge whether it should send or reject
  # the SMTP session by inspecting the HELO domain.
  # 
  #     Net::SMTP.start('your.smtp.server', 25,
  #                     'mail.from.domain') { |smtp| ... }
  # 
  # === SMTP Authentication
  # 
  # The Net::SMTP class supports three authentication schemes;
  # PLAIN, LOGIN and CRAM MD5.  (SMTP Authentication: [RFC2554])
  # To use SMTP authentication, pass extra arguments to 
  # SMTP.start/SMTP#start.
  # 
  #     # PLAIN
  #     Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
  #                     'Your Account', 'Your Password', :plain)
  #     # LOGIN
  #     Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
  #                     'Your Account', 'Your Password', :login)
  # 
  #     # CRAM MD5
  #     Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
  #                     'Your Account', 'Your Password', :cram_md5)
  #
  class SMTP

    Revision = %q$Revision: 28208 $.split[1]

    # The default SMTP port number, 25.
    def SMTP.default_port
      25
    end

    # The default mail submission port number, 587.
    def SMTP.default_submission_port
      587
    end

    # The default SMTPS port number, 465.
    def SMTP.default_tls_port
      465
    end

    class << self
      alias default_ssl_port default_tls_port
    end

    def SMTP.default_ssl_context
      OpenSSL::SSL::SSLContext.new
    end
    
    #
    # Creates a new Net::SMTP object.
    #
    # +address+ is the hostname or ip address of your SMTP
    # server.  +port+ is the port to connect to; it defaults to
    # port 25.
    #
    # This method does not open the TCP connection.  You can use
    # SMTP.start instead of SMTP.new if you want to do everything
    # at once.  Otherwise, follow SMTP.new with SMTP#start.
    #
    def initialize(address, port = nil)
      @address = address
      @port = (port || SMTP.default_port)
      @esmtp = true
      @capabilities = nil
      @socket = nil
      @started = false
      @open_timeout = 30
      @read_timeout = 60
      @error_occured = false
      @debug_output = nil
      @tls = false
      @starttls = false
      @ssl_context = nil
    end
    
    # Provide human-readable stringification of class state.
    def inspect
      "#<#{self.class} #{@address}:#{@port} started=#{@started}>"
    end

    # +true+ if the SMTP object uses ESMTP (which it does by default).
    def esmtp?
      @esmtp
    end

    #
    # Set whether to use ESMTP or not.  This should be done before 
    # calling #start.  Note that if #start is called in ESMTP mode,
    # and the connection fails due to a ProtocolError, the SMTP
    # object will automatically switch to plain SMTP mode and
    # retry (but not vice versa).
    #
    def esmtp=(bool)
      @esmtp = bool
    end

    alias esmtp esmtp?

    # true if server advertises STARTTLS.
    # You cannot get valid value before opening SMTP session.
    def capable_starttls?
      capable?('STARTTLS')
    end

    def capable?(key)
      return nil unless @capabilities
      @capabilities[key] ? true : false
    end
    private :capable?

    # true if server advertises AUTH PLAIN.
    # You cannot get valid value before opening SMTP session.
    def capable_plain_auth?
      auth_capable?('PLAIN')
    end

    # true if server advertises AUTH LOGIN.
    # You cannot get valid value before opening SMTP session.
    def capable_login_auth?
      auth_capable?('LOGIN')
    end

    # true if server advertises AUTH CRAM-MD5.
    # You cannot get valid value before opening SMTP session.
    def capable_cram_md5_auth?
      auth_capable?('CRAM-MD5')
    end

    def auth_capable?(type)
      return nil unless @capabilities
      return false unless @capabilities['AUTH']
      @capabilities['AUTH'].include?(type)
    end
    private :auth_capable?

    # Returns supported authentication methods on this server.
    # You cannot get valid value before opening SMTP session.
    def capable_auth_types
      return [] unless @capabilities
      return [] unless @capabilities['AUTH']
      @capabilities['AUTH']
    end

    # true if this object uses SMTP/TLS (SMTPS).
    def tls?
      @tls
    end

    alias ssl? tls?

    # Enables SMTP/TLS (SMTPS: SMTP over direct TLS connection) for
    # this object.  Must be called before the connection is established
    # to have any effect.  +context+ is a OpenSSL::SSL::SSLContext object.
    def enable_tls(context = SMTP.default_ssl_context)
      raise 'openssl library not installed' unless defined?(OpenSSL)
      raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @starttls
      @tls = true
      @ssl_context = context
    end

    alias enable_ssl enable_tls
    
    # Disables SMTP/TLS for this object.  Must be called before the
    # connection is established to have any effect.
    def disable_tls
      @tls = false
      @ssl_context = nil
    end

    alias disable_ssl disable_tls

    # Returns truth value if this object uses STARTTLS.
    # If this object always uses STARTTLS, returns :always.
    # If this object uses STARTTLS when the server support TLS, returns :auto.
    def starttls?
      @starttls
    end

    # true if this object uses STARTTLS.
    def starttls_always?
      @starttls == :always
    end

    # true if this object uses STARTTLS when server advertises STARTTLS.
    def starttls_auto?
      @starttls == :auto
    end
    
    # Enables SMTP/TLS (STARTTLS) for this object.
    # +context+ is a OpenSSL::SSL::SSLContext object.
    def enable_starttls(context = SMTP.default_ssl_context)
      raise 'openssl library not installed' unless defined?(OpenSSL)
      raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
      @starttls = :always
      @ssl_context = context
    end

    # Enables SMTP/TLS (STARTTLS) for this object if server accepts.
    # +context+ is a OpenSSL::SSL::SSLContext object.
    def enable_starttls_auto(context = SMTP.default_ssl_context)
      raise 'openssl library not installed' unless defined?(OpenSSL)
      raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
      @starttls = :auto
      @ssl_context = context
    end

    # Disables SMTP/TLS (STARTTLS) for this object.  Must be called
    # before the connection is established to have any effect.
    def disable_starttls
      @starttls = false
      @ssl_context = nil
    end

    # The address of the SMTP server to connect to.
    attr_reader :address

    # The port number of the SMTP server to connect to.
    attr_reader :port

    # Seconds to wait while attempting to open a connection.
    # If the connection cannot be opened within this time, a
    # TimeoutError is raised.
    attr_accessor :open_timeout

    # Seconds to wait while reading one block (by one read(2) call).
    # If the read(2) call does not complete within this time, a
    # TimeoutError is raised.
    attr_reader :read_timeout

    # Set the number of seconds to wait until timing-out a read(2)
    # call.
    def read_timeout=(sec)
      @socket.read_timeout = sec if @socket
      @read_timeout = sec
    end

    #
    # WARNING: This method causes serious security holes.
    # Use this method for only debugging.
    #
    # Set an output stream for debug logging.
    # You must call this before #start.
    #
    #   # example
    #   smtp = Net::SMTP.new(addr, port)
    #   smtp.set_debug_output $stderr
    #   smtp.start do |smtp|
    #     ....
    #   end
    #
    def debug_output=(arg)
      @debug_output = arg
    end

    alias set_debug_output debug_output=

    #
    # SMTP session control
    #

    #
    # Creates a new Net::SMTP object and connects to the server.
    #
    # This method is equivalent to:
    # 
    #   Net::SMTP.new(address, port).start(helo_domain, account, password, authtype)
    #
    # === Example
    #
    #     Net::SMTP.start('your.smtp.server') do |smtp|
    #       smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
    #     end
    #
    # === Block Usage
    #
    # If called with a block, the newly-opened Net::SMTP object is yielded
    # to the block, and automatically closed when the block finishes.  If called
    # without a block, the newly-opened Net::SMTP object is returned to
    # the caller, and it is the caller's responsibility to close it when
    # finished.
    #
    # === Parameters
    #
    # +address+ is the hostname or ip address of your smtp server.
    #
    # +port+ is the port to connect to; it defaults to port 25.
    #
    # +helo+ is the _HELO_ _domain_ provided by the client to the
    # server (see overview comments); it defaults to 'localhost.localdomain'. 
    #
    # The remaining arguments are used for SMTP authentication, if required
    # or desired.  +user+ is the account name; +secret+ is your password
    # or other authentication token; and +authtype+ is the authentication
    # type, one of :plain, :login, or :cram_md5.  See the discussion of
    # SMTP Authentication in the overview notes.
    #
    # === Errors
    #
    # This method may raise:
    #
    # * Net::SMTPAuthenticationError
    # * Net::SMTPServerBusy
    # * Net::SMTPSyntaxError
    # * Net::SMTPFatalError
    # * Net::SMTPUnknownError
    # * IOError
    # * TimeoutError
    #
    def SMTP.start(address, port = nil, helo = 'localhost.localdomain',
                   user = nil, secret = nil, authtype = nil,
                   &block)   # :yield: smtp
      new(address, port).start(helo, user, secret, authtype, &block)
    end

    # +true+ if the SMTP session has been started.
    def started?
      @started
    end

    #
    # Opens a TCP connection and starts the SMTP session.
    #
    # === Parameters
    #
    # +helo+ is the _HELO_ _domain_ that you'll dispatch mails from; see
    # the discussion in the overview notes.
    #
    # If both of +user+ and +secret+ are given, SMTP authentication 
    # will be attempted using the AUTH command.  +authtype+ specifies 
    # the type of authentication to attempt; it must be one of
    # :login, :plain, and :cram_md5.  See the notes on SMTP Authentication
    # in the overview. 
    #
    # === Block Usage
    #
    # When this methods is called with a block, the newly-started SMTP
    # object is yielded to the block, and automatically closed after
    # the block call finishes.  Otherwise, it is the caller's 
    # responsibility to close the session when finished.
    #
    # === Example
    #
    # This is very similar to the class method SMTP.start.
    #
    #     require 'net/smtp' 
    #     smtp = Net::SMTP.new('smtp.mail.server', 25)
    #     smtp.start(helo_domain, account, password, authtype) do |smtp|
    #       smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
    #     end 
    #
    # The primary use of this method (as opposed to SMTP.start)
    # is probably to set debugging (#set_debug_output) or ESMTP
    # (#esmtp=), which must be done before the session is
    # started.  
    #
    # === Errors
    #
    # If session has already been started, an IOError will be raised.
    #
    # This method may raise:
    #
    # * Net::SMTPAuthenticationError
    # * Net::SMTPServerBusy
    # * Net::SMTPSyntaxError
    # * Net::SMTPFatalError
    # * Net::SMTPUnknownError
    # * IOError
    # * TimeoutError
    #
    def start(helo = 'localhost.localdomain',
              user = nil, secret = nil, authtype = nil)   # :yield: smtp
      if block_given?
        begin
          do_start helo, user, secret, authtype
          return yield(self)
        ensure
          do_finish
        end
      else
        do_start helo, user, secret, authtype
        return self
      end
    end

    # Finishes the SMTP session and closes TCP connection.
    # Raises IOError if not started.
    def finish
      raise IOError, 'not yet started' unless started?
      do_finish
    end

    private

    def do_start(helo_domain, user, secret, authtype)
      raise IOError, 'SMTP session already started' if @started
      if user or secret
        check_auth_method(authtype || DEFAULT_AUTH_TYPE)
        check_auth_args user, secret
      end
      s = timeout(@open_timeout) { TCPSocket.open(@address, @port) }   
      logging "Connection opened: #{@address}:#{@port}"
      @socket = new_internet_message_io(tls? ? tlsconnect(s) : s)
      check_response critical { recv_response() }
      do_helo helo_domain
      if starttls_always? or (capable_starttls? and starttls_auto?)
        unless capable_starttls?
          raise SMTPUnsupportedCommand,
              "STARTTLS is not supported on this server"
        end
        starttls
        @socket = new_internet_message_io(tlsconnect(s))
        # helo response may be different after STARTTLS
        do_helo helo_domain
      end
      authenticate user, secret, (authtype || DEFAULT_AUTH_TYPE) if user
      @started = true
    ensure
      unless @started
        # authentication failed, cancel connection.
        s.close if s and not s.closed?
        @socket = nil
      end
    end

    def tlsconnect(s)
      s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
      logging "TLS connection started"
      s.sync_close = true
      s.connect
      if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
        s.post_connection_check(@address)
      end
      s
    end

    def new_internet_message_io(s)
      io = InternetMessageIO.new(s)
      io.read_timeout = @read_timeout
      io.debug_output = @debug_output
      io
    end

    def do_helo(helo_domain)
      res = @esmtp ? ehlo(helo_domain) : helo(helo_domain)
      @capabilities = res.capabilities
    rescue SMTPError
      if @esmtp
        @esmtp = false
        @error_occured = false
        retry
      end
      raise
    end

    def do_finish
      quit if @socket and not @socket.closed? and not @error_occured
    ensure
      @started = false
      @error_occured = false
      @socket.close if @socket and not @socket.closed?
      @socket = nil
    end

    #
    # Message Sending
    #

    public

    #
    # Sends +msgstr+ as a message.  Single CR ("\r") and LF ("\n") found
    # in the +msgstr+, are converted into the CR LF pair.  You cannot send a
    # binary message with this method. +msgstr+ should include both 
    # the message headers and body.
    #
    # +from_addr+ is a String representing the source mail address.
    #
    # +to_addr+ is a String or Strings or Array of Strings, representing
    # the destination mail address or addresses.
    #
    # === Example
    #
    #     Net::SMTP.start('smtp.example.com') do |smtp|
    #       smtp.send_message msgstr,
    #                         'from@example.com',
    #                         ['dest@example.com', 'dest2@example.com']
    #     end
    #
    # === Errors
    #
    # This method may raise:
    #
    # * Net::SMTPServerBusy
    # * Net::SMTPSyntaxError
    # * Net::SMTPFatalError
    # * Net::SMTPUnknownError
    # * IOError
    # * TimeoutError
    #
    def send_message(msgstr, from_addr, *to_addrs)
      raise IOError, 'closed session' unless @socket
      mailfrom from_addr
      rcptto_list(to_addrs) {data msgstr}
    end

    alias send_mail send_message
    alias sendmail send_message   # obsolete

    #
    # Opens a message writer stream and gives it to the block.
    # The stream is valid only in the block, and has these methods:
    #
    # puts(str = '')::       outputs STR and CR LF.
    # print(str)::           outputs STR.
    # printf(fmt, *args)::   outputs sprintf(fmt,*args).
    # write(str)::           outputs STR and returns the length of written bytes.
    # <<(str)::              outputs STR and returns self.
    #
    # If a single CR ("\r") or LF ("\n") is found in the message,
    # it is converted to the CR LF pair.  You cannot send a binary
    # message with this method.
    #
    # === Parameters
    #
    # +from_addr+ is a String representing the source mail address.
    #
    # +to_addr+ is a String or Strings or Array of Strings, representing
    # the destination mail address or addresses.
    #
    # === Example
    #
    #     Net::SMTP.start('smtp.example.com', 25) do |smtp|
    #       smtp.open_message_stream('from@example.com', ['dest@example.com']) do |f|
    #         f.puts 'From: from@example.com'
    #         f.puts 'To: dest@example.com'
    #         f.puts 'Subject: test message'
    #         f.puts
    #         f.puts 'This is a test message.'
    #       end
    #     end
    #
    # === Errors
    #
    # This method may raise:
    #
    # * Net::SMTPServerBusy
    # * Net::SMTPSyntaxError
    # * Net::SMTPFatalError
    # * Net::SMTPUnknownError
    # * IOError
    # * TimeoutError
    #
    def open_message_stream(from_addr, *to_addrs, &block)   # :yield: stream
      raise IOError, 'closed session' unless @socket
      mailfrom from_addr
      rcptto_list(to_addrs) {data(&block)}
    end

    alias ready open_message_stream   # obsolete

    #
    # Authentication
    #

    public

    DEFAULT_AUTH_TYPE = :plain

    def authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE)
      check_auth_method authtype
      check_auth_args user, secret
      send auth_method(authtype), user, secret
    end

    def auth_plain(user, secret)
      check_auth_args user, secret
      res = critical {
        get_response('AUTH PLAIN ' + base64_encode("\0#{user}\0#{secret}"))
      }
      check_auth_response res
      res
    end

    def auth_login(user, secret)
      check_auth_args user, secret
      res = critical {
        check_auth_continue get_response('AUTH LOGIN')
        check_auth_continue get_response(base64_encode(user))
        get_response(base64_encode(secret))
      }
      check_auth_response res
      res
    end

    def auth_cram_md5(user, secret)
      check_auth_args user, secret
      res = critical {
        res0 = get_response('AUTH CRAM-MD5')
        check_auth_continue res0
        crammed = cram_md5_response(secret, res0.cram_md5_challenge)
        get_response(base64_encode("#{user} #{crammed}"))
      }
      check_auth_response res
      res
    end

    private

    def check_auth_method(type)
      unless respond_to?(auth_method(type), true)
        raise ArgumentError, "wrong authentication type #{type}"
      end
    end

    def auth_method(type)
      "auth_#{type.to_s.downcase}".intern
    end

    def check_auth_args(user, secret)
      unless user
        raise ArgumentError, 'SMTP-AUTH requested but missing user name'
      end
      unless secret
        raise ArgumentError, 'SMTP-AUTH requested but missing secret phrase'
      end
    end

    def base64_encode(str)
      # expects "str" may not become too long
      [str].pack('m').gsub(/\s+/, '')
    end

    IMASK = 0x36
    OMASK = 0x5c

    # CRAM-MD5: [RFC2195]
    def cram_md5_response(secret, challenge)
      tmp = Digest::MD5.digest(cram_secret(secret, IMASK) + challenge)
      Digest::MD5.hexdigest(cram_secret(secret, OMASK) + tmp)
    end

    CRAM_BUFSIZE = 64

    def cram_secret(secret, mask)
      secret = Digest::MD5.digest(secret) if secret.size > CRAM_BUFSIZE
      buf = secret.ljust(CRAM_BUFSIZE, "\0")
      0.upto(buf.size - 1) do |i|
        buf[i] = (buf[i].ord ^ mask).chr
      end
      buf
    end

    #
    # SMTP command dispatcher
    #

    public

    def starttls
      getok('STARTTLS')
    end

    def helo(domain)
      getok("HELO #{domain}")
    end

    def ehlo(domain)
      getok("EHLO #{domain}")
    end

    def mailfrom(from_addr)
      if $SAFE > 0
        raise SecurityError, 'tainted from_addr' if from_addr.tainted?
      end
      getok("MAIL FROM:<#{from_addr}>")
    end

    def rcptto_list(to_addrs)
      raise ArgumentError, 'mail destination not given' if to_addrs.empty?
      ok_users = []
      unknown_users = []
      to_addrs.flatten.each do |addr|
        begin
          rcptto addr
        rescue SMTPAuthenticationError
          unknown_users << addr.dump
        else
          ok_users << addr
        end
      end
      raise ArgumentError, 'mail destination not given' if ok_users.empty?
      ret = yield
      unless unknown_users.empty?
        raise SMTPAuthenticationError, "failed to deliver for #{unknown_users.join(', ')}"
      end
      ret
    end

    def rcptto(to_addr)
      if $SAFE > 0
        raise SecurityError, 'tainted to_addr' if to_addr.tainted?
      end
      getok("RCPT TO:<#{to_addr}>")
    end

    # This method sends a message.
    # If +msgstr+ is given, sends it as a message.
    # If block is given, yield a message writer stream.
    # You must write message before the block is closed.
    #
    #   # Example 1 (by string)
    #   smtp.data(<<EndMessage)
    #   From: john@example.com
    #   To: betty@example.com
    #   Subject: I found a bug
    #   
    #   Check vm.c:58879.
    #   EndMessage
    #
    #   # Example 2 (by block)
    #   smtp.data {|f|
    #     f.puts "From: john@example.com"
    #     f.puts "To: betty@example.com"
    #     f.puts "Subject: I found a bug"
    #     f.puts ""
    #     f.puts "Check vm.c:58879."
    #   }
    #
    def data(msgstr = nil, &block)   #:yield: stream
      if msgstr and block
        raise ArgumentError, "message and block are exclusive"
      end
      unless msgstr or block
        raise ArgumentError, "message or block is required"
      end
      res = critical {
        check_continue get_response('DATA')
        if msgstr
          @socket.write_message msgstr
        else
          @socket.write_message_by_block(&block)
        end
        recv_response()
      }
      check_response res
      res
    end

    def quit
      getok('QUIT')
    end

    private

    def getok(reqline)
      res = critical {
        @socket.writeline reqline
        recv_response()
      }
      check_response res
      res
    end

    def get_response(reqline)
      @socket.writeline reqline
      recv_response()
    end

    def recv_response
      buf = ''
      while true
        line = @socket.readline
        buf << line << "\n"
        break unless line[3,1] == '-'   # "210-PIPELINING"
      end
      Response.parse(buf)
    end

    def critical(&block)
      return '200 dummy reply code' if @error_occured
      begin
        return yield()
      rescue Exception
        @error_occured = true
        raise
      end
    end

    def check_response(res)
      unless res.success?
        raise res.exception_class, res.message
      end
    end

    def check_continue(res)
      unless res.continue?
        raise SMTPUnknownError, "could not get 3xx (#{res.status})"
      end
    end

    def check_auth_response(res)
      unless res.success?
        raise SMTPAuthenticationError, res.message
      end
    end

    def check_auth_continue(res)
      unless res.continue?
        raise res.exception_class, res.message
      end
    end

    class Response
      def Response.parse(str)
        new(str[0,3], str)
      end

      def initialize(status, string)
        @status = status
        @string = string
      end

      attr_reader :status
      attr_reader :string

      def status_type_char
        @status[0, 1]
      end

      def success?
        status_type_char() == '2'
      end

      def continue?
        status_type_char() == '3'
      end

      def message
        @string.lines.first
      end

      def cram_md5_challenge
        @string.split(/ /)[1].unpack('m')[0]
      end

      def capabilities
        return {} unless @string[3, 1] == '-'
        h = {}
        @string.lines.drop(1).each do |line|
          k, *v = line[4..-1].chomp.split(nil)
          h[k] = v
        end
        h
      end

      def exception_class
        case @status
        when /\A4/  then SMTPServerBusy
        when /\A50/ then SMTPSyntaxError
        when /\A53/ then SMTPAuthenticationError
        when /\A5/  then SMTPFatalError
        else             SMTPUnknownError
        end
      end
    end

    def logging(msg)
      @debug_output << msg + "\n" if @debug_output
    end

  end   # class SMTP

  SMTPSession = SMTP

end
PK     SZ\/ ;       net/https.rbnu [        =begin

= $RCSfile$ -- SSL/TLS enhancement for Net::HTTP.

== Info
  'OpenSSL for Ruby 2' project
  Copyright (C) 2001 GOTOU Yuuzou <gotoyuzo@notwork.org>
  All rights reserved.

== Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

== Requirements
  This program requires Net 1.2.0 or higher version.
  You can get it from RAA or Ruby's CVS repository.

== Version
  $Id: https.rb 16857 2008-06-06 08:05:24Z knu $
  
  2001-11-06: Contiributed to Ruby/OpenSSL project.
  2004-03-06: Some code is merged in to net/http.

== Example

Here is a simple HTTP client:

    require 'net/http'
    require 'uri'

    uri = URI.parse(ARGV[0] || 'http://localhost/')
    http = Net::HTTP.new(uri.host, uri.port)
    http.start {
      http.request_get(uri.path) {|res|
        print res.body
      }
    }

It can be replaced by the following code:

    require 'net/https'
    require 'uri'

    uri = URI.parse(ARGV[0] || 'https://localhost/')
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true if uri.scheme == "https"  # enable SSL/TLS
    http.start {
      http.request_get(uri.path) {|res|
        print res.body
      }
    }

== class Net::HTTP

=== Instance Methods

: use_ssl?
    returns true if use SSL/TLS with HTTP.

: use_ssl=((|true_or_false|))
    sets use_ssl.

: peer_cert
    return the X.509 certificates the server presented.

: key, key=((|key|))
    Sets an OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
    (This method is appeared in Michal Rokos's OpenSSL extension.)

: cert, cert=((|cert|))
    Sets an OpenSSL::X509::Certificate object as client certificate
    (This method is appeared in Michal Rokos's OpenSSL extension).

: ca_file, ca_file=((|path|))
    Sets path of a CA certification file in PEM format.
    The file can contrain several CA certificats.

: ca_path, ca_path=((|path|))
    Sets path of a CA certification directory containing certifications
    in PEM format.

: verify_mode, verify_mode=((|mode|))
    Sets the flags for server the certification verification at
    begining of SSL/TLS session.
    OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER is acceptable.

: verify_callback, verify_callback=((|proc|))
    Sets the verify callback for the server certification verification.

: verify_depth, verify_depth=((|num|))
    Sets the maximum depth for the certificate chain verification.

: cert_store, cert_store=((|store|))
    Sets the X509::Store to verify peer certificate.

: ssl_timeout, ssl_timeout=((|sec|))
    Sets the SSL timeout seconds.

=end

require 'net/http'
require 'openssl'

module Net

  class HTTP
    remove_method :use_ssl?
    def use_ssl?
      @use_ssl
    end

    # For backward compatibility.
    alias use_ssl use_ssl?

    # Turn on/off SSL.
    # This flag must be set before starting session.
    # If you change use_ssl value after session started,
    # a Net::HTTP object raises IOError.
    def use_ssl=(flag)
      flag = (flag ? true : false)
      raise IOError, "use_ssl value changed, but session already started" \
          if started? and @use_ssl != flag
      if flag and not @ssl_context
        @ssl_context = OpenSSL::SSL::SSLContext.new
      end
      @use_ssl = flag
    end

    def self.ssl_context_accessor(name)
      module_eval(<<-End, __FILE__, __LINE__ + 1)
        def #{name}
          return nil unless @ssl_context
          @ssl_context.#{name}
        end

        def #{name}=(val)
          @ssl_context ||= OpenSSL::SSL::SSLContext.new
          @ssl_context.#{name} = val
        end
      End
    end

    ssl_context_accessor :key
    ssl_context_accessor :cert
    ssl_context_accessor :ca_file
    ssl_context_accessor :ca_path
    ssl_context_accessor :verify_mode
    ssl_context_accessor :verify_callback
    ssl_context_accessor :verify_depth
    ssl_context_accessor :cert_store

    def ssl_timeout
      return nil unless @ssl_context
      @ssl_context.timeout
    end

    def ssl_timeout=(sec)
      raise ArgumentError, 'Net::HTTP#ssl_timeout= called but use_ssl=false' \
          unless use_ssl?
      @ssl_context ||= OpenSSL::SSL::SSLContext.new
      @ssl_context.timeout = sec
    end

    # For backward compatibility
    alias timeout= ssl_timeout=

    def peer_cert
      return nil if not use_ssl? or not @socket
      @socket.io.peer_cert
    end
  end

end
PK     TZ\QC  C    net/telnets.rbnu [        =begin
= $RCSfile$ -- SSL/TLS enhancement for Net::Telnet.

= Info
  'OpenSSL for Ruby 2' project
  Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
  All rights reserved.

= Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

= Version
  $Id: telnets.rb 13657 2007-10-08 11:16:54Z gotoyuzo $
  
  2001/11/06: Contiributed to Ruby/OpenSSL project.

== class Net::Telnet

This class will initiate SSL/TLS session automaticaly if the server
sent OPT_STARTTLS. Some options are added for SSL/TLS.

  host = Net::Telnet::new({
           "Host"       => "localhost",
           "Port"       => "telnets",
           ## follows are new options.
           'CertFile'   => "user.crt",
           'KeyFile'    => "user.key",
           'CAFile'     => "/some/where/certs/casert.pem",
           'CAPath'     => "/some/where/caserts",
           'VerifyMode' => SSL::VERIFY_PEER,
           'VerifyCallback' => verify_proc
         })

Or, the new options ('Cert', 'Key' and 'CACert') are available from
Michal Rokos's OpenSSL module.

  cert_data = File.open("user.crt"){|io| io.read }
  pkey_data = File.open("user.key"){|io| io.read }
  cacert_data = File.open("your_ca.pem"){|io| io.read }
  host = Net::Telnet::new({
           "Host"       => "localhost",
           "Port"       => "telnets",
           'Cert'       => OpenSSL::X509::Certificate.new(cert_data)
           'Key'        => OpenSSL::PKey::RSA.new(pkey_data)
           'CACert'     => OpenSSL::X509::Certificate.new(cacert_data)
           'CAFile'     => "/some/where/certs/casert.pem",
           'CAPath'     => "/some/where/caserts",
           'VerifyMode' => SSL::VERIFY_PEER,
           'VerifyCallback' => verify_proc
         })

This class is expected to be a superset of usual Net::Telnet.
=end

require "net/telnet"
require "openssl"

module Net
  class Telnet
    attr_reader :ssl

    OPT_STARTTLS       =  46.chr # "\056" # "\x2e" # Start TLS
    TLS_FOLLOWS        =   1.chr # "\001" # "\x01" # FOLLOWS (for STARTTLS)

    alias preprocess_orig preprocess

    def ssl?; @ssl; end

    def preprocess(string)
      # combine CR+NULL into CR
      string = string.gsub(/#{CR}#{NULL}/no, CR) if @options["Telnetmode"]

      # combine EOL into "\n"
      string = string.gsub(/#{EOL}/no, "\n") unless @options["Binmode"]

      string.gsub(/#{IAC}(
                   [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]|
                   [#{DO}#{DONT}#{WILL}#{WONT}][#{OPT_BINARY}-#{OPT_EXOPL}]|
                   #{SB}[#{OPT_BINARY}-#{OPT_EXOPL}]
                     (#{IAC}#{IAC}|[^#{IAC}])+#{IAC}#{SE}
                 )/xno) do
        if    IAC == $1  # handle escaped IAC characters
          IAC
        elsif AYT == $1  # respond to "IAC AYT" (are you there)
          self.write("nobody here but us pigeons" + EOL)
          ''
        elsif DO[0] == $1[0]  # respond to "IAC DO x"
          if    OPT_BINARY[0] == $1[1]
            @telnet_option["BINARY"] = true
            self.write(IAC + WILL + OPT_BINARY)
          elsif OPT_STARTTLS[0] == $1[1]
            self.write(IAC + WILL + OPT_STARTTLS)
            self.write(IAC + SB + OPT_STARTTLS + TLS_FOLLOWS + IAC + SE)
          else
            self.write(IAC + WONT + $1[1..1])
          end
          ''
        elsif DONT[0] == $1[0]  # respond to "IAC DON'T x" with "IAC WON'T x"
          self.write(IAC + WONT + $1[1..1])
          ''
        elsif WILL[0] == $1[0]  # respond to "IAC WILL x"
          if    OPT_BINARY[0] == $1[1]
            self.write(IAC + DO + OPT_BINARY)
          elsif OPT_ECHO[0] == $1[1]
            self.write(IAC + DO + OPT_ECHO)
          elsif OPT_SGA[0]  == $1[1]
            @telnet_option["SGA"] = true
            self.write(IAC + DO + OPT_SGA)
          else
            self.write(IAC + DONT + $1[1..1])
          end
          ''
        elsif WONT[0] == $1[0]  # respond to "IAC WON'T x"
          if    OPT_ECHO[0] == $1[1]
            self.write(IAC + DONT + OPT_ECHO)
          elsif OPT_SGA[0]  == $1[1]
            @telnet_option["SGA"] = false
            self.write(IAC + DONT + OPT_SGA)
          else
            self.write(IAC + DONT + $1[1..1])
          end
          ''
        elsif SB[0] == $1[0]    # respond to "IAC SB xxx IAC SE"
          if    OPT_STARTTLS[0] == $1[1] && TLS_FOLLOWS[0] == $2[0]
            @sock = OpenSSL::SSL::SSLSocket.new(@sock)
            @sock.cert            = @options['Cert'] unless @sock.cert
            @sock.key             = @options['Key'] unless @sock.key
            @sock.ca_cert         = @options['CACert']
            @sock.ca_file         = @options['CAFile']
            @sock.ca_path         = @options['CAPath']
            @sock.timeout         = @options['Timeout']
            @sock.verify_mode     = @options['VerifyMode']
            @sock.verify_callback = @options['VerifyCallback']
            @sock.verify_depth    = @options['VerifyDepth']
            @sock.connect
            if @options['VerifyMode'] != OpenSSL::SSL::VERIFY_NONE
              @sock.post_connection_check(@options['Host'])
            end
            @ssl = true
          end
          ''
        else
          ''
        end
      end
    end # preprocess
    
    alias waitfor_org waitfor

    def waitfor(options)
      time_out = @options["Timeout"]
      waittime = @options["Waittime"]

      if options.kind_of?(Hash)
        prompt   = if options.has_key?("Match")
                     options["Match"]
                   elsif options.has_key?("Prompt")
                     options["Prompt"]
                   elsif options.has_key?("String")
                     Regexp.new( Regexp.quote(options["String"]) )
                   end
        time_out = options["Timeout"]  if options.has_key?("Timeout")
        waittime = options["Waittime"] if options.has_key?("Waittime")
      else
        prompt = options
      end

      if time_out == false
        time_out = nil
      end

      line = ''
      buf = ''
      @rest = '' unless @rest

      until(prompt === line and not IO::select([@sock], nil, nil, waittime))
        unless IO::select([@sock], nil, nil, time_out)
          raise TimeoutError, "timed-out; wait for the next data"
        end
        begin
          c = @rest + @sock.sysread(1024 * 1024)
          @dumplog.log_dump('<', c) if @options.has_key?("Dump_log")
          if @options["Telnetmode"]   
            pos = 0
            catch(:next){
              while true
                case c[pos]
                when IAC[0]
                  case c[pos+1]
                  when DO[0], DONT[0], WILL[0], WONT[0]
                    throw :next unless c[pos+2]
                    pos += 3
                  when SB[0]
                    ret = detect_sub_negotiation(c, pos)
                    throw :next unless ret
                    pos = ret
                  when nil
                    throw :next
                  else
                    pos += 2
                  end
                when nil
                  throw :next
                else
                  pos += 1
                end
              end
            }

            buf = preprocess(c[0...pos])
            @rest = c[pos..-1]
          end
          @log.print(buf) if @options.has_key?("Output_log")
          line.concat(buf)
          yield buf if block_given?   
        rescue EOFError # End of file reached
          if line == ''
            line = nil
            yield nil if block_given? 
          end
          break
        end
      end
      line
    end

    private

    def detect_sub_negotiation(data, pos)
      return nil if data.length < pos+6  # IAC SB x param IAC SE
      pos += 3
      while true
        case data[pos]
        when IAC[0]
          if data[pos+1] == SE[0]
            pos += 2
            return pos
          else
            pos += 2
          end
        when nil
          return nil
        else
          pos += 1
        end
      end
    end

  end
end
PK     TZ\ҝf  f  
  net/pop.rbnu [        # = net/pop.rb
#
# Copyright (c) 1999-2007 Yukihiro Matsumoto.
#
# Copyright (c) 1999-2007 Minero Aoki.
# 
# Written & maintained by Minero Aoki <aamine@loveruby.net>.
#
# Documented by William Webber and Minero Aoki.
# 
# This program is free software. You can re-distribute and/or
# modify this program under the same terms as Ruby itself,
# Ruby Distribute License.
# 
# NOTE: You can find Japanese version of this document at:
# http://www.ruby-lang.org/ja/man/html/net_pop.html
# 
#   $Id: pop.rb 29903 2010-11-24 07:38:32Z shyouhei $
# 
# See Net::POP3 for documentation.
#

require 'net/protocol'
require 'digest/md5'
require 'timeout'

begin
  require "openssl/ssl"
rescue LoadError
end

module Net

  # Non-authentication POP3 protocol error
  # (reply code "-ERR", except authentication).
  class POPError < ProtocolError; end

  # POP3 authentication error.
  class POPAuthenticationError < ProtoAuthError; end

  # Unexpected response from the server.
  class POPBadResponse < POPError; end

  #
  # = Net::POP3
  #
  # == What is This Library?
  # 
  # This library provides functionality for retrieving 
  # email via POP3, the Post Office Protocol version 3. For details
  # of POP3, see [RFC1939] (http://www.ietf.org/rfc/rfc1939.txt).
  # 
  # == Examples
  # 
  # === Retrieving Messages 
  # 
  # This example retrieves messages from the server and deletes them 
  # on the server.
  #
  # Messages are written to files named 'inbox/1', 'inbox/2', ....
  # Replace 'pop.example.com' with your POP3 server address, and
  # 'YourAccount' and 'YourPassword' with the appropriate account
  # details.
  # 
  #     require 'net/pop'
  # 
  #     pop = Net::POP3.new('pop.example.com')
  #     pop.start('YourAccount', 'YourPassword')             # (1)
  #     if pop.mails.empty?
  #       puts 'No mail.'
  #     else
  #       i = 0
  #       pop.each_mail do |m|   # or "pop.mails.each ..."   # (2)
  #         File.open("inbox/#{i}", 'w') do |f|
  #           f.write m.pop
  #         end
  #         m.delete
  #         i += 1
  #       end
  #       puts "#{pop.mails.size} mails popped."
  #     end
  #     pop.finish                                           # (3)
  # 
  # 1. Call Net::POP3#start and start POP session.
  # 2. Access messages by using POP3#each_mail and/or POP3#mails.
  # 3. Close POP session by calling POP3#finish or use the block form of #start.
  # 
  # === Shortened Code
  # 
  # The example above is very verbose. You can shorten the code by using
  # some utility methods. First, the block form of Net::POP3.start can
  # be used instead of POP3.new, POP3#start and POP3#finish.
  # 
  #     require 'net/pop'
  # 
  #     Net::POP3.start('pop.example.com', 110,
  #                     'YourAccount', 'YourPassword') do |pop|
  #       if pop.mails.empty?
  #         puts 'No mail.'
  #       else
  #         i = 0
  #         pop.each_mail do |m|   # or "pop.mails.each ..."
  #           File.open("inbox/#{i}", 'w') do |f|
  #             f.write m.pop
  #           end
  #           m.delete
  #           i += 1
  #         end
  #         puts "#{pop.mails.size} mails popped."
  #       end
  #     end
  # 
  # POP3#delete_all is an alternative for #each_mail and #delete.
  # 
  #     require 'net/pop'
  # 
  #     Net::POP3.start('pop.example.com', 110,
  #                     'YourAccount', 'YourPassword') do |pop|
  #       if pop.mails.empty?
  #         puts 'No mail.'
  #       else
  #         i = 1
  #         pop.delete_all do |m|
  #           File.open("inbox/#{i}", 'w') do |f|
  #             f.write m.pop
  #           end
  #           i += 1
  #         end
  #       end
  #     end
  # 
  # And here is an even shorter example.
  # 
  #     require 'net/pop'
  # 
  #     i = 0
  #     Net::POP3.delete_all('pop.example.com', 110,
  #                          'YourAccount', 'YourPassword') do |m|
  #       File.open("inbox/#{i}", 'w') do |f|
  #         f.write m.pop
  #       end
  #       i += 1
  #     end
  # 
  # === Memory Space Issues
  # 
  # All the examples above get each message as one big string.
  # This example avoids this.
  # 
  #     require 'net/pop'
  # 
  #     i = 1
  #     Net::POP3.delete_all('pop.example.com', 110,
  #                          'YourAccount', 'YourPassword') do |m|
  #       File.open("inbox/#{i}", 'w') do |f|
  #         m.pop do |chunk|    # get a message little by little.
  #           f.write chunk
  #         end
  #         i += 1
  #       end
  #     end
  # 
  # === Using APOP
  # 
  # The net/pop library supports APOP authentication.
  # To use APOP, use the Net::APOP class instead of the Net::POP3 class.
  # You can use the utility method, Net::POP3.APOP(). For example:
  # 
  #     require 'net/pop'
  # 
  #     # Use APOP authentication if $isapop == true
  #     pop = Net::POP3.APOP($is_apop).new('apop.example.com', 110)
  #     pop.start(YourAccount', 'YourPassword') do |pop|
  #       # Rest of the code is the same.
  #     end
  # 
  # === Fetch Only Selected Mail Using 'UIDL' POP Command
  # 
  # If your POP server provides UIDL functionality,
  # you can grab only selected mails from the POP server.
  # e.g.
  # 
  #     def need_pop?( id )
  #       # determine if we need pop this mail...
  #     end
  # 
  #     Net::POP3.start('pop.example.com', 110,
  #                     'Your account', 'Your password') do |pop|
  #       pop.mails.select { |m| need_pop?(m.unique_id) }.each do |m|
  #         do_something(m.pop)
  #       end
  #     end
  # 
  # The POPMail#unique_id() method returns the unique-id of the message as a
  # String. Normally the unique-id is a hash of the message.
  # 
  class POP3 < Protocol

    Revision = %q$Revision: 29903 $.split[1]

    #
    # Class Parameters
    #

    def POP3.default_port
      default_pop3_port()
    end

    # The default port for POP3 connections, port 110
    def POP3.default_pop3_port
      110
    end
    
    # The default port for POP3S connections, port 995
    def POP3.default_pop3s_port
      995
    end

    def POP3.socket_type   #:nodoc: obsolete
      Net::InternetMessageIO
    end

    #
    # Utilities
    #

    # Returns the APOP class if +isapop+ is true; otherwise, returns
    # the POP class.  For example:
    #
    #     # Example 1
    #     pop = Net::POP3::APOP($is_apop).new(addr, port)
    #
    #     # Example 2
    #     Net::POP3::APOP($is_apop).start(addr, port) do |pop|
    #       ....
    #     end
    #
    def POP3.APOP(isapop)
      isapop ? APOP : POP3
    end

    # Starts a POP3 session and iterates over each POPMail object,
    # yielding it to the +block+.
    # This method is equivalent to:
    #
    #     Net::POP3.start(address, port, account, password) do |pop|
    #       pop.each_mail do |m|
    #         yield m
    #       end
    #     end
    #
    # This method raises a POPAuthenticationError if authentication fails.
    #
    # === Example
    #
    #     Net::POP3.foreach('pop.example.com', 110,
    #                       'YourAccount', 'YourPassword') do |m|
    #       file.write m.pop
    #       m.delete if $DELETE
    #     end
    #
    def POP3.foreach(address, port = nil,
                     account = nil, password = nil,
                     isapop = false, &block)  # :yields: message
      start(address, port, account, password, isapop) {|pop|
        pop.each_mail(&block)
      }
    end

    # Starts a POP3 session and deletes all messages on the server.
    # If a block is given, each POPMail object is yielded to it before
    # being deleted.
    #
    # This method raises a POPAuthenticationError if authentication fails.
    #
    # === Example
    #
    #     Net::POP3.delete_all('pop.example.com', 110,
    #                          'YourAccount', 'YourPassword') do |m|
    #       file.write m.pop
    #     end
    #
    def POP3.delete_all(address, port = nil,
                        account = nil, password = nil,
                        isapop = false, &block)
      start(address, port, account, password, isapop) {|pop|
        pop.delete_all(&block)
      }
    end

    # Opens a POP3 session, attempts authentication, and quits.
    #
    # This method raises POPAuthenticationError if authentication fails.
    #
    # === Example: normal POP3
    #
    #     Net::POP3.auth_only('pop.example.com', 110,
    #                         'YourAccount', 'YourPassword')
    #
    # === Example: APOP
    #
    #     Net::POP3.auth_only('pop.example.com', 110,
    #                         'YourAccount', 'YourPassword', true)
    #
    def POP3.auth_only(address, port = nil,
                       account = nil, password = nil,
                       isapop = false)
      new(address, port, isapop).auth_only account, password
    end

    # Starts a pop3 session, attempts authentication, and quits.
    # This method must not be called while POP3 session is opened.
    # This method raises POPAuthenticationError if authentication fails.
    def auth_only(account, password)
      raise IOError, 'opening previously opened POP session' if started?
      start(account, password) {
        ;
      }
    end

    #
    # SSL
    #

    @ssl_params = nil

    # call-seq:
    #    Net::POP.enable_ssl(params = {})
    #
    # Enable SSL for all new instances.
    # +params+ is passed to OpenSSL::SSLContext#set_params.
    def POP3.enable_ssl(*args)
      @ssl_params = create_ssl_params(*args)
    end

    def POP3.create_ssl_params(verify_or_params = {}, certs = nil)
      begin
        params = verify_or_params.to_hash
      rescue NoMethodError
        params = {}
        params[:verify_mode] = verify_or_params
        if certs
          if File.file?(certs)
            params[:ca_file] = certs
          elsif File.directory?(certs)
            params[:ca_path] = certs
          end
        end
      end
      return params
    end

    # Disable SSL for all new instances.
    def POP3.disable_ssl
      @ssl_params = nil
    end

    def POP3.ssl_params
      return @ssl_params
    end

    def POP3.use_ssl?
      return !@ssl_params.nil?
    end

    def POP3.verify
      return @ssl_params[:verify_mode]
    end

    def POP3.certs
      return @ssl_params[:ca_file] || @ssl_params[:ca_path]
    end

    #
    # Session management
    #

    # Creates a new POP3 object and open the connection.  Equivalent to 
    #
    #   Net::POP3.new(address, port, isapop).start(account, password)
    #
    # If +block+ is provided, yields the newly-opened POP3 object to it,
    # and automatically closes it at the end of the session.
    #
    # === Example
    #
    #    Net::POP3.start(addr, port, account, password) do |pop|
    #      pop.each_mail do |m|
    #        file.write m.pop
    #        m.delete
    #      end
    #    end
    #
    def POP3.start(address, port = nil,
                   account = nil, password = nil,
                   isapop = false, &block)   # :yield: pop
      new(address, port, isapop).start(account, password, &block)
    end
    
    # Creates a new POP3 object.
    #
    # +address+ is the hostname or ip address of your POP3 server.
    #
    # The optional +port+ is the port to connect to.
    #
    # The optional +isapop+ specifies whether this connection is going
    # to use APOP authentication; it defaults to +false+.
    #
    # This method does *not* open the TCP connection.
    def initialize(addr, port = nil, isapop = false)
      @address = addr
      @ssl_params = POP3.ssl_params
      @port = port
      @apop = isapop
      
      @command = nil
      @socket = nil
      @started = false
      @open_timeout = 30
      @read_timeout = 60
      @debug_output = nil

      @mails = nil
      @n_mails = nil
      @n_bytes = nil
    end

    # Does this instance use APOP authentication?
    def apop?
      @apop
    end

    # does this instance use SSL?
    def use_ssl?
      return !@ssl_params.nil?
    end
   
    # call-seq:
    #    Net::POP#enable_ssl(params = {})
    #
    # Enables SSL for this instance.  Must be called before the connection is
    # established to have any effect.
    # +params[:port]+ is port to establish the SSL connection on; Defaults to 995.
    # +params+ (except :port) is passed to OpenSSL::SSLContext#set_params.
    def enable_ssl(verify_or_params = {}, certs = nil, port = nil)
      begin
        @ssl_params = verify_or_params.to_hash.dup
        @port = @ssl_params.delete(:port) || @port
      rescue NoMethodError
        @ssl_params = POP3.create_ssl_params(verify_or_params, certs)
        @port = port || @port
      end
    end
    
    def disable_ssl
      @ssl_params = nil
    end

    # Provide human-readable stringification of class state.
    def inspect
      "#<#{self.class} #{@address}:#{@port} open=#{@started}>"
    end

    # *WARNING*: This method causes a serious security hole.
    # Use this method only for debugging.
    #
    # Set an output stream for debugging.
    #
    # === Example
    #
    #   pop = Net::POP.new(addr, port)
    #   pop.set_debug_output $stderr
    #   pop.start(account, passwd) do |pop|
    #     ....
    #   end
    #
    def set_debug_output(arg)
      @debug_output = arg
    end

    # The address to connect to.
    attr_reader :address

    # The port number to connect to.
    def port
      return @port || (use_ssl? ? POP3.default_pop3s_port : POP3.default_pop3_port)
    end

    # Seconds to wait until a connection is opened.
    # If the POP3 object cannot open a connection within this time,
    # it raises a TimeoutError exception.
    attr_accessor :open_timeout

    # Seconds to wait until reading one block (by one read(1) call).
    # If the POP3 object cannot complete a read() within this time,
    # it raises a TimeoutError exception.
    attr_reader :read_timeout

    # Set the read timeout.
    def read_timeout=(sec)
      @command.socket.read_timeout = sec if @command
      @read_timeout = sec
    end

    # +true+ if the POP3 session has started.
    def started?
      @started
    end

    alias active? started?   #:nodoc: obsolete

    # Starts a POP3 session.
    #
    # When called with block, gives a POP3 object to the block and
    # closes the session after block call finishes.
    #
    # This method raises a POPAuthenticationError if authentication fails.
    def start(account, password) # :yield: pop
      raise IOError, 'POP session already started' if @started
      if block_given?
        begin
          do_start account, password
          return yield(self)
        ensure
          do_finish
        end
      else
        do_start account, password
        return self
      end
    end

    def do_start(account, password)
      s = timeout(@open_timeout) { TCPSocket.open(@address, port) }
      if use_ssl?
        raise 'openssl library not installed' unless defined?(OpenSSL)
        context = OpenSSL::SSL::SSLContext.new
        context.set_params(@ssl_params)
        s = OpenSSL::SSL::SSLSocket.new(s, context)
        s.sync_close = true
        s.connect
        if context.verify_mode != OpenSSL::SSL::VERIFY_NONE
          s.post_connection_check(@address)
        end
      end
      @socket = InternetMessageIO.new(s)
      logging "POP session started: #{@address}:#{@port} (#{@apop ? 'APOP' : 'POP'})"
      @socket.read_timeout = @read_timeout
      @socket.debug_output = @debug_output
      on_connect
      @command = POP3Command.new(@socket)
      if apop?
        @command.apop account, password
      else
        @command.auth account, password
      end
      @started = true
    ensure
      # Authentication failed, clean up connection.
      unless @started
        s.close if s and not s.closed?
        @socket = nil
        @command = nil
      end
    end
    private :do_start

    def on_connect
    end
    private :on_connect

    # Finishes a POP3 session and closes TCP connection.
    def finish
      raise IOError, 'POP session not yet started' unless started?
      do_finish
    end

    def do_finish
      @mails = nil
      @n_mails = nil
      @n_bytes = nil
      @command.quit if @command
    ensure
      @started = false
      @command = nil
      @socket.close if @socket and not @socket.closed?
      @socket = nil
    end
    private :do_finish

    def command
      raise IOError, 'POP session not opened yet' \
                                      if not @socket or @socket.closed?
      @command
    end
    private :command

    #
    # POP protocol wrapper
    #

    # Returns the number of messages on the POP server.
    def n_mails
      return @n_mails if @n_mails
      @n_mails, @n_bytes = command().stat
      @n_mails
    end

    # Returns the total size in bytes of all the messages on the POP server.
    def n_bytes
      return @n_bytes if @n_bytes
      @n_mails, @n_bytes = command().stat
      @n_bytes
    end

    # Returns an array of Net::POPMail objects, representing all the
    # messages on the server.  This array is renewed when the session
    # restarts; otherwise, it is fetched from the server the first time
    # this method is called (directly or indirectly) and cached.
    #
    # This method raises a POPError if an error occurs.
    def mails
      return @mails.dup if @mails
      if n_mails() == 0
        # some popd raises error for LIST on the empty mailbox.
        @mails = []
        return []
      end

      @mails = command().list.map {|num, size|
        POPMail.new(num, size, self, command())
      }
      @mails.dup
    end

    # Yields each message to the passed-in block in turn.
    # Equivalent to:
    # 
    #   pop3.mails.each do |popmail|
    #     ....
    #   end
    #
    # This method raises a POPError if an error occurs.
    def each_mail(&block)  # :yield: message
      mails().each(&block)
    end

    alias each each_mail

    # Deletes all messages on the server.
    #
    # If called with a block, yields each message in turn before deleting it.
    #
    # === Example
    #
    #     n = 1
    #     pop.delete_all do |m|
    #       File.open("inbox/#{n}") do |f|
    #         f.write m.pop
    #       end
    #       n += 1
    #     end
    #
    # This method raises a POPError if an error occurs.
    #
    def delete_all # :yield: message
      mails().each do |m|
        yield m if block_given?
        m.delete unless m.deleted?
      end
    end

    # Resets the session.  This clears all "deleted" marks from messages.
    #
    # This method raises a POPError if an error occurs.
    def reset
      command().rset
      mails().each do |m|
        m.instance_eval {
          @deleted = false
        }
      end
    end

    def set_all_uids   #:nodoc: internal use only (called from POPMail#uidl)
      uidl = command().uidl
      @mails.each {|m| m.uid = uidl[m.number] }
    end

    def logging(msg)
      @debug_output << msg + "\n" if @debug_output
    end

  end   # class POP3

  # class aliases
  POP = POP3
  POPSession  = POP3
  POP3Session = POP3

  #
  # This class is equivalent to POP3, except that it uses APOP authentication.
  #
  class APOP < POP3
    # Always returns true.
    def apop?
      true
    end
  end

  # class aliases
  APOPSession = APOP

  #
  # This class represents a message which exists on the POP server.
  # Instances of this class are created by the POP3 class; they should
  # not be directly created by the user.
  #
  class POPMail

    def initialize(num, len, pop, cmd)   #:nodoc:
      @number = num
      @length = len
      @pop = pop
      @command = cmd
      @deleted = false
      @uid = nil
    end

    # The sequence number of the message on the server.
    attr_reader :number

    # The length of the message in octets.
    attr_reader :length
    alias size length

    # Provide human-readable stringification of class state.
    def inspect
      "#<#{self.class} #{@number}#{@deleted ? ' deleted' : ''}>"
    end

    #
    # This method fetches the message.  If called with a block, the
    # message is yielded to the block one chunk at a time.  If called
    # without a block, the message is returned as a String.  The optional 
    # +dest+ argument will be prepended to the returned String; this
    # argument is essentially obsolete.
    #
    # === Example without block
    #
    #     POP3.start('pop.example.com', 110,
    #                'YourAccount, 'YourPassword') do |pop|
    #       n = 1
    #       pop.mails.each do |popmail|
    #         File.open("inbox/#{n}", 'w') do |f|
    #           f.write popmail.pop              
    #         end
    #         popmail.delete
    #         n += 1
    #       end
    #     end
    #
    # === Example with block
    #
    #     POP3.start('pop.example.com', 110,
    #                'YourAccount, 'YourPassword') do |pop|
    #       n = 1
    #       pop.mails.each do |popmail|
    #         File.open("inbox/#{n}", 'w') do |f|
    #           popmail.pop do |chunk|            ####
    #             f.write chunk
    #           end
    #         end
    #         n += 1
    #       end
    #     end
    #
    # This method raises a POPError if an error occurs.
    #
    def pop( dest = '', &block ) # :yield: message_chunk
      if block_given?
        @command.retr(@number, &block)
        nil
      else
        @command.retr(@number) do |chunk|
          dest << chunk
        end
        dest
      end
    end

    alias all pop    #:nodoc: obsolete
    alias mail pop   #:nodoc: obsolete

    # Fetches the message header and +lines+ lines of body. 
    #
    # The optional +dest+ argument is obsolete.
    #
    # This method raises a POPError if an error occurs.
    def top(lines, dest = '')
      @command.top(@number, lines) do |chunk|
        dest << chunk
      end
      dest
    end

    # Fetches the message header.     
    #
    # The optional +dest+ argument is obsolete.
    #
    # This method raises a POPError if an error occurs.
    def header(dest = '')
      top(0, dest)
    end

    # Marks a message for deletion on the server.  Deletion does not
    # actually occur until the end of the session; deletion may be
    # cancelled for _all_ marked messages by calling POP3#reset().
    #
    # This method raises a POPError if an error occurs.
    #
    # === Example
    #
    #     POP3.start('pop.example.com', 110,
    #                'YourAccount, 'YourPassword') do |pop|
    #       n = 1
    #       pop.mails.each do |popmail|
    #         File.open("inbox/#{n}", 'w') do |f|
    #           f.write popmail.pop
    #         end
    #         popmail.delete         ####
    #         n += 1
    #       end
    #     end
    #
    def delete
      @command.dele @number
      @deleted = true
    end

    alias delete! delete    #:nodoc: obsolete

    # True if the mail has been deleted.
    def deleted?
      @deleted
    end

    # Returns the unique-id of the message.
    # Normally the unique-id is a hash string of the message.
    #
    # This method raises a POPError if an error occurs.
    def unique_id
      return @uid if @uid
      @pop.set_all_uids
      @uid
    end

    alias uidl unique_id

    def uid=(uid)   #:nodoc: internal use only
      @uid = uid
    end

  end   # class POPMail


  class POP3Command   #:nodoc: internal use only

    def initialize(sock)
      @socket = sock
      @error_occured = false
      res = check_response(critical { recv_response() })
      @apop_stamp = res.slice(/<[!-~]+@[!-~]+>/)
    end

    def inspect
      "#<#{self.class} socket=#{@socket}>"
    end

    def auth(account, password)
      check_response_auth(critical {
        check_response_auth(get_response('USER %s', account))
        get_response('PASS %s', password)
      })
    end

    def apop(account, password)
      raise POPAuthenticationError, 'not APOP server; cannot login' \
                                                      unless @apop_stamp
      check_response_auth(critical {
        get_response('APOP %s %s',
                     account,
                     Digest::MD5.hexdigest(@apop_stamp + password))
      })
    end

    def list
      critical {
        getok 'LIST'
        list = []
        @socket.each_list_item do |line|
          m = /\A(\d+)[ \t]+(\d+)/.match(line) or
                  raise POPBadResponse, "bad response: #{line}"
          list.push  [m[1].to_i, m[2].to_i]
        end
        return list
      }
    end

    def stat
      res = check_response(critical { get_response('STAT') })
      m = /\A\+OK\s+(\d+)\s+(\d+)/.match(res) or
              raise POPBadResponse, "wrong response format: #{res}"
      [m[1].to_i, m[2].to_i]
    end

    def rset
      check_response(critical { get_response('RSET') })
    end

    def top(num, lines = 0, &block)
      critical {
        getok('TOP %d %d', num, lines)
        @socket.each_message_chunk(&block)
      }
    end

    def retr(num, &block)
      critical {
        getok('RETR %d', num)
        @socket.each_message_chunk(&block)
      }
    end
    
    def dele(num)
      check_response(critical { get_response('DELE %d', num) })
    end

    def uidl(num = nil)
      if num
        res = check_response(critical { get_response('UIDL %d', num) })
        return res.split(/ /)[1]
      else
        critical {
          getok('UIDL')
          table = {}
          @socket.each_list_item do |line|
            num, uid = line.split
            table[num.to_i] = uid
          end
          return table
        }
      end
    end

    def quit
      check_response(critical { get_response('QUIT') })
    end

    private

    def getok(fmt, *fargs)
      @socket.writeline sprintf(fmt, *fargs)
      check_response(recv_response())
    end

    def get_response(fmt, *fargs)
      @socket.writeline sprintf(fmt, *fargs)
      recv_response()
    end

    def recv_response
      @socket.readline
    end

    def check_response(res)
      raise POPError, res unless /\A\+OK/i =~ res
      res
    end

    def check_response_auth(res)
      raise POPAuthenticationError, res unless /\A\+OK/i =~ res
      res
    end

    def critical
      return '+OK dummy ok response' if @error_occured
      begin
        return yield()
      rescue Exception
        @error_occured = true
        raise
      end
    end

  end   # class POP3Command

end   # module Net
PK     UZ\f      net/http.rbnu [        #
# = net/http.rb
#
# Copyright (c) 1999-2006 Yukihiro Matsumoto
# Copyright (c) 1999-2006 Minero Aoki
# Copyright (c) 2001 GOTOU Yuuzou
# 
# Written and maintained by Minero Aoki <aamine@loveruby.net>.
# HTTPS support added by GOTOU Yuuzou <gotoyuzo@notwork.org>.
#
# This file is derived from "http-access.rb".
#
# Documented by Minero Aoki; converted to RDoc by William Webber.
# 
# This program is free software. You can re-distribute and/or
# modify this program under the same terms of ruby itself ---
# Ruby Distribution License or GNU General Public License.
#
# See Net::HTTP for an overview and examples. 
# 
# NOTE: You can find Japanese version of this document here:
# http://www.ruby-lang.org/ja/man/?cmd=view;name=net%2Fhttp.rb
# 
#--
# $Id: http.rb 29865 2010-11-22 07:22:19Z shyouhei $
#++ 

require 'net/protocol'
require 'uri'

module Net   #:nodoc:

  # :stopdoc:
  class HTTPBadResponse < StandardError; end
  class HTTPHeaderSyntaxError < StandardError; end
  # :startdoc:

  # == What Is This Library?
  # 
  # This library provides your program functions to access WWW
  # documents via HTTP, Hyper Text Transfer Protocol version 1.1.
  # For details of HTTP, refer [RFC2616]
  # (http://www.ietf.org/rfc/rfc2616.txt).
  # 
  # == Examples
  # 
  # === Getting Document From WWW Server
  # 
  # Example #1: Simple GET+print
  # 
  #     require 'net/http'
  #     Net::HTTP.get_print 'www.example.com', '/index.html'
  # 
  # Example #2: Simple GET+print by URL
  # 
  #     require 'net/http'
  #     require 'uri'
  #     Net::HTTP.get_print URI.parse('http://www.example.com/index.html')
  # 
  # Example #3: More generic GET+print
  # 
  #     require 'net/http'
  #     require 'uri'
  #
  #     url = URI.parse('http://www.example.com/index.html')
  #     res = Net::HTTP.start(url.host, url.port) {|http|
  #       http.get('/index.html')
  #     }
  #     puts res.body
  #
  # Example #4: More generic GET+print
  # 
  #     require 'net/http'
  #
  #     url = URI.parse('http://www.example.com/index.html')
  #     req = Net::HTTP::Get.new(url.path)
  #     res = Net::HTTP.start(url.host, url.port) {|http|
  #       http.request(req)
  #     }
  #     puts res.body
  # 
  # === Posting Form Data
  # 
  #     require 'net/http'
  #     require 'uri'
  #
  #     #1: Simple POST
  #     res = Net::HTTP.post_form(URI.parse('http://www.example.com/search.cgi'),
  #                               {'q'=>'ruby', 'max'=>'50'})
  #     puts res.body
  #
  #     #2: POST with basic authentication
  #     res = Net::HTTP.post_form(URI.parse('http://jack:pass@www.example.com/todo.cgi'),
  #                                         {'from'=>'2005-01-01', 'to'=>'2005-03-31'})
  #     puts res.body
  #
  #     #3: Detailed control
  #     url = URI.parse('http://www.example.com/todo.cgi')
  #     req = Net::HTTP::Post.new(url.path)
  #     req.basic_auth 'jack', 'pass'
  #     req.set_form_data({'from'=>'2005-01-01', 'to'=>'2005-03-31'}, ';')
  #     res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
  #     case res
  #     when Net::HTTPSuccess, Net::HTTPRedirection
  #       # OK
  #     else
  #       res.error!
  #     end
  # 
  # === Accessing via Proxy
  # 
  # Net::HTTP.Proxy creates http proxy class. It has same
  # methods of Net::HTTP but its instances always connect to
  # proxy, instead of given host.
  # 
  #     require 'net/http'
  # 
  #     proxy_addr = 'your.proxy.host'
  #     proxy_port = 8080
  #             :
  #     Net::HTTP::Proxy(proxy_addr, proxy_port).start('www.example.com') {|http|
  #       # always connect to your.proxy.addr:8080
  #             :
  #     }
  # 
  # Since Net::HTTP.Proxy returns Net::HTTP itself when proxy_addr is nil,
  # there's no need to change code if there's proxy or not.
  # 
  # There are two additional parameters in Net::HTTP.Proxy which allow to
  # specify proxy user name and password:
  # 
  #     Net::HTTP::Proxy(proxy_addr, proxy_port, proxy_user = nil, proxy_pass = nil)
  # 
  # You may use them to work with authorization-enabled proxies:
  # 
  #     require 'net/http'
  #     require 'uri'
  #     
  #     proxy_host = 'your.proxy.host'
  #     proxy_port = 8080
  #     uri = URI.parse(ENV['http_proxy'])
  #     proxy_user, proxy_pass = uri.userinfo.split(/:/) if uri.userinfo
  #     Net::HTTP::Proxy(proxy_host, proxy_port,
  #                      proxy_user, proxy_pass).start('www.example.com') {|http|
  #       # always connect to your.proxy.addr:8080 using specified username and password
  #             :
  #     }
  #
  # Note that net/http never rely on HTTP_PROXY environment variable.
  # If you want to use proxy, set it explicitly.
  # 
  # === Following Redirection
  # 
  #     require 'net/http'
  #     require 'uri'
  # 
  #     def fetch(uri_str, limit = 10)
  #       # You should choose better exception. 
  #       raise ArgumentError, 'HTTP redirect too deep' if limit == 0
  # 
  #       response = Net::HTTP.get_response(URI.parse(uri_str))
  #       case response
  #       when Net::HTTPSuccess     then response
  #       when Net::HTTPRedirection then fetch(response['location'], limit - 1)
  #       else
  #         response.error!
  #       end
  #     end
  # 
  #     print fetch('http://www.ruby-lang.org')
  # 
  # Net::HTTPSuccess and Net::HTTPRedirection is a HTTPResponse class.
  # All HTTPResponse objects belong to its own response class which
  # indicate HTTP result status. For details of response classes,
  # see section "HTTP Response Classes".
  # 
  # === Basic Authentication
  # 
  #     require 'net/http'
  # 
  #     Net::HTTP.start('www.example.com') {|http|
  #       req = Net::HTTP::Get.new('/secret-page.html')
  #       req.basic_auth 'account', 'password'
  #       response = http.request(req)
  #       print response.body
  #     }
  # 
  # === HTTP Request Classes
  #
  # Here is HTTP request class hierarchy.
  #
  #   Net::HTTPRequest
  #       Net::HTTP::Get
  #       Net::HTTP::Head
  #       Net::HTTP::Post
  #       Net::HTTP::Put
  #       Net::HTTP::Proppatch
  #       Net::HTTP::Lock
  #       Net::HTTP::Unlock
  #       Net::HTTP::Options
  #       Net::HTTP::Propfind
  #       Net::HTTP::Delete
  #       Net::HTTP::Move
  #       Net::HTTP::Copy
  #       Net::HTTP::Mkcol
  #       Net::HTTP::Trace
  #
  # === HTTP Response Classes
  #
  # Here is HTTP response class hierarchy.
  # All classes are defined in Net module.
  #
  #   HTTPResponse
  #       HTTPUnknownResponse
  #       HTTPInformation                    # 1xx
  #           HTTPContinue                       # 100
  #           HTTPSwitchProtocl                  # 101
  #       HTTPSuccess                        # 2xx
  #           HTTPOK                             # 200
  #           HTTPCreated                        # 201
  #           HTTPAccepted                       # 202
  #           HTTPNonAuthoritativeInformation    # 203
  #           HTTPNoContent                      # 204
  #           HTTPResetContent                   # 205
  #           HTTPPartialContent                 # 206
  #       HTTPRedirection                    # 3xx
  #           HTTPMultipleChoice                 # 300
  #           HTTPMovedPermanently               # 301
  #           HTTPFound                          # 302
  #           HTTPSeeOther                       # 303
  #           HTTPNotModified                    # 304
  #           HTTPUseProxy                       # 305
  #           HTTPTemporaryRedirect              # 307
  #       HTTPClientError                    # 4xx
  #           HTTPBadRequest                     # 400
  #           HTTPUnauthorized                   # 401
  #           HTTPPaymentRequired                # 402
  #           HTTPForbidden                      # 403
  #           HTTPNotFound                       # 404
  #           HTTPMethodNotAllowed               # 405
  #           HTTPNotAcceptable                  # 406
  #           HTTPProxyAuthenticationRequired    # 407
  #           HTTPRequestTimeOut                 # 408
  #           HTTPConflict                       # 409
  #           HTTPGone                           # 410
  #           HTTPLengthRequired                 # 411
  #           HTTPPreconditionFailed             # 412
  #           HTTPRequestEntityTooLarge          # 413
  #           HTTPRequestURITooLong              # 414
  #           HTTPUnsupportedMediaType           # 415
  #           HTTPRequestedRangeNotSatisfiable   # 416
  #           HTTPExpectationFailed              # 417
  #       HTTPServerError                    # 5xx
  #           HTTPInternalServerError            # 500
  #           HTTPNotImplemented                 # 501
  #           HTTPBadGateway                     # 502
  #           HTTPServiceUnavailable             # 503
  #           HTTPGatewayTimeOut                 # 504
  #           HTTPVersionNotSupported            # 505
  # 
  # == Switching Net::HTTP versions
  # 
  # You can use net/http.rb 1.1 features (bundled with Ruby 1.6)
  # by calling HTTP.version_1_1. Calling Net::HTTP.version_1_2
  # allows you to use 1.2 features again.
  # 
  #     # example
  #     Net::HTTP.start {|http1| ...(http1 has 1.2 features)... }
  # 
  #     Net::HTTP.version_1_1
  #     Net::HTTP.start {|http2| ...(http2 has 1.1 features)... }
  # 
  #     Net::HTTP.version_1_2
  #     Net::HTTP.start {|http3| ...(http3 has 1.2 features)... }
  # 
  # This function is NOT thread-safe.
  #
  class HTTP < Protocol

    # :stopdoc:
    Revision = %q$Revision: 29865 $.split[1]
    HTTPVersion = '1.1'
    @newimpl = true
    # :startdoc:

    # Turns on net/http 1.2 (ruby 1.8) features.
    # Defaults to ON in ruby 1.8.
    #
    # I strongly recommend to call this method always.
    #
    #   require 'net/http'
    #   Net::HTTP.version_1_2
    #
    def HTTP.version_1_2
      @newimpl = true
    end

    # Turns on net/http 1.1 (ruby 1.6) features.
    # Defaults to OFF in ruby 1.8.
    def HTTP.version_1_1
      @newimpl = false
    end

    # true if net/http is in version 1.2 mode.
    # Defaults to true.
    def HTTP.version_1_2?
      @newimpl
    end

    # true if net/http is in version 1.1 compatible mode.
    # Defaults to true.
    def HTTP.version_1_1?
      not @newimpl
    end

    class << HTTP
      alias is_version_1_1? version_1_1?   #:nodoc:
      alias is_version_1_2? version_1_2?   #:nodoc:
    end

    #
    # short cut methods
    #

    #
    # Get body from target and output it to +$stdout+.  The
    # target can either be specified as (+uri+), or as
    # (+host+, +path+, +port+ = 80); so: 
    #
    #    Net::HTTP.get_print URI.parse('http://www.example.com/index.html')
    #
    # or:
    #
    #    Net::HTTP.get_print 'www.example.com', '/index.html'
    #
    def HTTP.get_print(uri_or_host, path = nil, port = nil)
      get_response(uri_or_host, path, port) {|res|
        res.read_body do |chunk|
          $stdout.print chunk
        end
      }
      nil
    end

    # Send a GET request to the target and return the response
    # as a string.  The target can either be specified as
    # (+uri+), or as (+host+, +path+, +port+ = 80); so:
    # 
    #    print Net::HTTP.get(URI.parse('http://www.example.com/index.html'))
    #
    # or:
    #
    #    print Net::HTTP.get('www.example.com', '/index.html')
    #
    def HTTP.get(uri_or_host, path = nil, port = nil)
      get_response(uri_or_host, path, port).body
    end

    # Send a GET request to the target and return the response
    # as a Net::HTTPResponse object.  The target can either be specified as
    # (+uri+), or as (+host+, +path+, +port+ = 80); so:
    # 
    #    res = Net::HTTP.get_response(URI.parse('http://www.example.com/index.html'))
    #    print res.body
    #
    # or:
    #
    #    res = Net::HTTP.get_response('www.example.com', '/index.html')
    #    print res.body
    #
    def HTTP.get_response(uri_or_host, path = nil, port = nil, &block)
      if path
        host = uri_or_host
        new(host, port || HTTP.default_port).start {|http|
          return http.request_get(path, &block)
        }
      else
        uri = uri_or_host
        new(uri.host, uri.port).start {|http|
          return http.request_get(uri.request_uri, &block)
        }
      end
    end

    # Posts HTML form data to the +URL+.
    # Form data must be represented as a Hash of String to String, e.g:
    #
    #   { "cmd" => "search", "q" => "ruby", "max" => "50" }
    #
    # This method also does Basic Authentication iff +URL+.user exists.
    #
    # Example:
    #
    #   require 'net/http'
    #   require 'uri'
    #
    #   HTTP.post_form URI.parse('http://www.example.com/search.cgi'),
    #                  { "q" => "ruby", "max" => "50" }
    #
    def HTTP.post_form(url, params)
      req = Post.new(url.path)
      req.form_data = params
      req.basic_auth url.user, url.password if url.user
      new(url.host, url.port).start {|http|
        http.request(req)
      }
    end

    #
    # HTTP session management
    #

    # The default port to use for HTTP requests; defaults to 80.
    def HTTP.default_port
      http_default_port()
    end

    # The default port to use for HTTP requests; defaults to 80.
    def HTTP.http_default_port
      80
    end

    # The default port to use for HTTPS requests; defaults to 443.
    def HTTP.https_default_port
      443
    end

    def HTTP.socket_type   #:nodoc: obsolete
      BufferedIO
    end

    # creates a new Net::HTTP object and opens its TCP connection and 
    # HTTP session.  If the optional block is given, the newly 
    # created Net::HTTP object is passed to it and closed when the 
    # block finishes.  In this case, the return value of this method
    # is the return value of the block.  If no block is given, the
    # return value of this method is the newly created Net::HTTP object
    # itself, and the caller is responsible for closing it upon completion.
    def HTTP.start(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil, &block) # :yield: +http+
      new(address, port, p_addr, p_port, p_user, p_pass).start(&block)
    end

    class << HTTP
      alias newobj new
    end

    # Creates a new Net::HTTP object.
    # If +proxy_addr+ is given, creates an Net::HTTP object with proxy support.
    # This method does not open the TCP connection.
    def HTTP.new(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil)
      h = Proxy(p_addr, p_port, p_user, p_pass).newobj(address, port)
      h.instance_eval {
        @newimpl = ::Net::HTTP.version_1_2?
      }
      h
    end

    # Creates a new Net::HTTP object for the specified +address+.
    # This method does not open the TCP connection.
    def initialize(address, port = nil)
      @address = address
      @port    = (port || HTTP.default_port)
      @curr_http_version = HTTPVersion
      @seems_1_0_server = false
      @close_on_empty_response = false
      @socket  = nil
      @started = false
      @open_timeout = nil
      @read_timeout = 60
      @debug_output = nil
      @use_ssl = false
      @ssl_context = nil
    end

    def inspect
      "#<#{self.class} #{@address}:#{@port} open=#{started?}>"
    end

    # *WARNING* This method causes serious security hole.
    # Never use this method in production code.
    #
    # Set an output stream for debugging.
    #
    #   http = Net::HTTP.new
    #   http.set_debug_output $stderr
    #   http.start { .... }
    #
    def set_debug_output(output)
      warn 'Net::HTTP#set_debug_output called after HTTP started' if started?
      @debug_output = output
    end

    # The host name to connect to.
    attr_reader :address

    # The port number to connect to.
    attr_reader :port

    # Seconds to wait until connection is opened.
    # If the HTTP object cannot open a connection in this many seconds,
    # it raises a TimeoutError exception.
    attr_accessor :open_timeout

    # Seconds to wait until reading one block (by one read(2) call).
    # If the HTTP object cannot open a connection in this many seconds,
    # it raises a TimeoutError exception.
    attr_reader :read_timeout

    # Setter for the read_timeout attribute.
    def read_timeout=(sec)
      @socket.read_timeout = sec if @socket
      @read_timeout = sec
    end

    # returns true if the HTTP session is started.
    def started?
      @started
    end

    alias active? started?   #:nodoc: obsolete

    attr_accessor :close_on_empty_response

    # returns true if use SSL/TLS with HTTP.
    def use_ssl?
      false   # redefined in net/https
    end

    # Opens TCP connection and HTTP session.
    # 
    # When this method is called with block, gives a HTTP object
    # to the block and closes the TCP connection / HTTP session
    # after the block executed.
    #
    # When called with a block, returns the return value of the
    # block; otherwise, returns self.
    #
    def start  # :yield: http
      raise IOError, 'HTTP session already opened' if @started
      if block_given?
        begin
          do_start
          return yield(self)
        ensure
          do_finish
        end
      end
      do_start
      self
    end

    def do_start
      connect
      @started = true
    end
    private :do_start

    def connect
      D "opening connection to #{conn_address()}..."
      s = timeout(@open_timeout) { TCPSocket.open(conn_address(), conn_port()) }
      D "opened"
      if use_ssl?
        unless @ssl_context.verify_mode
          warn "warning: peer certificate won't be verified in this SSL session"
          @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
        end
        s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
        s.sync_close = true
      end
      @socket = BufferedIO.new(s)
      @socket.read_timeout = @read_timeout
      @socket.debug_output = @debug_output
      if use_ssl?
        if proxy?
          @socket.writeline sprintf('CONNECT %s:%s HTTP/%s',
                                    @address, @port, HTTPVersion)
          @socket.writeline "Host: #{@address}:#{@port}"
          if proxy_user
            credential = ["#{proxy_user}:#{proxy_pass}"].pack('m')
            credential.delete!("\r\n")
            @socket.writeline "Proxy-Authorization: Basic #{credential}"
          end
          @socket.writeline ''
          HTTPResponse.read_new(@socket).value
        end
        s.connect
        if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
          s.post_connection_check(@address)
        end
      end
      on_connect
    end
    private :connect

    def on_connect
    end
    private :on_connect

    # Finishes HTTP session and closes TCP connection.
    # Raises IOError if not started.
    def finish
      raise IOError, 'HTTP session not yet started' unless started?
      do_finish
    end

    def do_finish
      @started = false
      @socket.close if @socket and not @socket.closed?
      @socket = nil
    end
    private :do_finish

    #
    # proxy
    #

    public

    # no proxy
    @is_proxy_class = false
    @proxy_addr = nil
    @proxy_port = nil
    @proxy_user = nil
    @proxy_pass = nil

    # Creates an HTTP proxy class.
    # Arguments are address/port of proxy host and username/password
    # if authorization on proxy server is required.
    # You can replace the HTTP class with created proxy class.
    # 
    # If ADDRESS is nil, this method returns self (Net::HTTP).
    # 
    #     # Example
    #     proxy_class = Net::HTTP::Proxy('proxy.example.com', 8080)
    #                     :
    #     proxy_class.start('www.ruby-lang.org') {|http|
    #       # connecting proxy.foo.org:8080
    #                     :
    #     }
    # 
    def HTTP.Proxy(p_addr, p_port = nil, p_user = nil, p_pass = nil)
      return self unless p_addr
      delta = ProxyDelta
      proxyclass = Class.new(self)
      proxyclass.module_eval {
        include delta
        # with proxy
        @is_proxy_class = true
        @proxy_address = p_addr
        @proxy_port    = p_port || default_port()
        @proxy_user    = p_user
        @proxy_pass    = p_pass
      }
      proxyclass
    end

    class << HTTP
      # returns true if self is a class which was created by HTTP::Proxy.
      def proxy_class?
        @is_proxy_class
      end

      attr_reader :proxy_address
      attr_reader :proxy_port
      attr_reader :proxy_user
      attr_reader :proxy_pass
    end

    # True if self is a HTTP proxy class.
    def proxy?
      self.class.proxy_class?
    end

    # Address of proxy host. If self does not use a proxy, nil.
    def proxy_address
      self.class.proxy_address
    end

    # Port number of proxy host. If self does not use a proxy, nil.
    def proxy_port
      self.class.proxy_port
    end

    # User name for accessing proxy. If self does not use a proxy, nil.
    def proxy_user
      self.class.proxy_user
    end

    # User password for accessing proxy. If self does not use a proxy, nil.
    def proxy_pass
      self.class.proxy_pass
    end

    alias proxyaddr proxy_address   #:nodoc: obsolete
    alias proxyport proxy_port      #:nodoc: obsolete

    private

    # without proxy

    def conn_address
      address()
    end

    def conn_port
      port()
    end

    def edit_path(path)
      path
    end

    module ProxyDelta   #:nodoc: internal use only
      private

      def conn_address
        proxy_address()
      end

      def conn_port
        proxy_port()
      end

      def edit_path(path)
        use_ssl? ? path : "http://#{addr_port()}#{path}"
      end
    end

    #
    # HTTP operations
    #

    public

    # Gets data from +path+ on the connected-to host.
    # +header+ must be a Hash like { 'Accept' => '*/*', ... }.
    #
    # In version 1.1 (ruby 1.6), this method returns a pair of objects,
    # a Net::HTTPResponse object and the entity body string.
    # In version 1.2 (ruby 1.8), this method returns a Net::HTTPResponse
    # object.
    #
    # If called with a block, yields each fragment of the
    # entity body in turn as a string as it is read from
    # the socket.  Note that in this case, the returned response
    # object will *not* contain a (meaningful) body.
    #
    # +dest+ argument is obsolete.
    # It still works but you must not use it.
    #
    # In version 1.1, this method might raise an exception for 
    # 3xx (redirect). In this case you can get a HTTPResponse object
    # by "anException.response".
    #
    # In version 1.2, this method never raises exception.
    #
    #     # version 1.1 (bundled with Ruby 1.6)
    #     response, body = http.get('/index.html')
    #
    #     # version 1.2 (bundled with Ruby 1.8 or later)
    #     response = http.get('/index.html')
    #     
    #     # using block
    #     File.open('result.txt', 'w') {|f|
    #       http.get('/~foo/') do |str|
    #         f.write str
    #       end
    #     }
    #
    def get(path, initheader = nil, dest = nil, &block) # :yield: +body_segment+
      res = nil
      request(Get.new(path, initheader)) {|r|
        r.read_body dest, &block
        res = r
      }
      unless @newimpl
        res.value
        return res, res.body
      end

      res
    end

    # Gets only the header from +path+ on the connected-to host.
    # +header+ is a Hash like { 'Accept' => '*/*', ... }.
    # 
    # This method returns a Net::HTTPResponse object.
    # 
    # In version 1.1, this method might raise an exception for 
    # 3xx (redirect). On the case you can get a HTTPResponse object
    # by "anException.response".
    # In version 1.2, this method never raises an exception.
    # 
    #     response = nil
    #     Net::HTTP.start('some.www.server', 80) {|http|
    #       response = http.head('/index.html')
    #     }
    #     p response['content-type']
    #
    def head(path, initheader = nil) 
      res = request(Head.new(path, initheader))
      res.value unless @newimpl
      res
    end

    # Posts +data+ (must be a String) to +path+. +header+ must be a Hash
    # like { 'Accept' => '*/*', ... }.
    # 
    # In version 1.1 (ruby 1.6), this method returns a pair of objects, a
    # Net::HTTPResponse object and an entity body string.
    # In version 1.2 (ruby 1.8), this method returns a Net::HTTPResponse object.
    # 
    # If called with a block, yields each fragment of the
    # entity body in turn as a string as it are read from
    # the socket.  Note that in this case, the returned response
    # object will *not* contain a (meaningful) body.
    #
    # +dest+ argument is obsolete.
    # It still works but you must not use it.
    # 
    # In version 1.1, this method might raise an exception for 
    # 3xx (redirect). In this case you can get an HTTPResponse object
    # by "anException.response".
    # In version 1.2, this method never raises exception.
    # 
    #     # version 1.1
    #     response, body = http.post('/cgi-bin/search.rb', 'query=foo')
    # 
    #     # version 1.2
    #     response = http.post('/cgi-bin/search.rb', 'query=foo')
    # 
    #     # using block
    #     File.open('result.txt', 'w') {|f|
    #       http.post('/cgi-bin/search.rb', 'query=foo') do |str|
    #         f.write str
    #       end
    #     }
    #
    # You should set Content-Type: header field for POST.
    # If no Content-Type: field given, this method uses
    # "application/x-www-form-urlencoded" by default.
    #
    def post(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
      res = nil
      request(Post.new(path, initheader), data) {|r|
        r.read_body dest, &block
        res = r
      }
      unless @newimpl
        res.value
        return res, res.body
      end
      res
    end

    def put(path, data, initheader = nil)   #:nodoc:
      res = request(Put.new(path, initheader), data)
      res.value unless @newimpl
      res
    end

    # Sends a PROPPATCH request to the +path+ and gets a response,
    # as an HTTPResponse object.
    def proppatch(path, body, initheader = nil)
      request(Proppatch.new(path, initheader), body)
    end

    # Sends a LOCK request to the +path+ and gets a response,
    # as an HTTPResponse object.
    def lock(path, body, initheader = nil)
      request(Lock.new(path, initheader), body)
    end

    # Sends a UNLOCK request to the +path+ and gets a response,
    # as an HTTPResponse object.
    def unlock(path, body, initheader = nil)
      request(Unlock.new(path, initheader), body)
    end

    # Sends a OPTIONS request to the +path+ and gets a response,
    # as an HTTPResponse object.
    def options(path, initheader = nil)
      request(Options.new(path, initheader))
    end

    # Sends a PROPFIND request to the +path+ and gets a response,
    # as an HTTPResponse object.
    def propfind(path, body = nil, initheader = {'Depth' => '0'})
      request(Propfind.new(path, initheader), body)
    end

    # Sends a DELETE request to the +path+ and gets a response,
    # as an HTTPResponse object.
    def delete(path, initheader = {'Depth' => 'Infinity'})
      request(Delete.new(path, initheader))
    end

    # Sends a MOVE request to the +path+ and gets a response,
    # as an HTTPResponse object.
    def move(path, initheader = nil)
      request(Move.new(path, initheader))
    end

    # Sends a COPY request to the +path+ and gets a response,
    # as an HTTPResponse object.
    def copy(path, initheader = nil)
      request(Copy.new(path, initheader))
    end

    # Sends a MKCOL request to the +path+ and gets a response,
    # as an HTTPResponse object.
    def mkcol(path, body = nil, initheader = nil)
      request(Mkcol.new(path, initheader), body)
    end

    # Sends a TRACE request to the +path+ and gets a response,
    # as an HTTPResponse object.
    def trace(path, initheader = nil)
      request(Trace.new(path, initheader))
    end

    # Sends a GET request to the +path+ and gets a response,
    # as an HTTPResponse object.
    # 
    # When called with a block, yields an HTTPResponse object.
    # The body of this response will not have been read yet;
    # the caller can process it using HTTPResponse#read_body,
    # if desired.
    #
    # Returns the response.
    # 
    # This method never raises Net::* exceptions.
    # 
    #     response = http.request_get('/index.html')
    #     # The entity body is already read here.
    #     p response['content-type']
    #     puts response.body
    # 
    #     # using block
    #     http.request_get('/index.html') {|response|
    #       p response['content-type']
    #       response.read_body do |str|   # read body now
    #         print str
    #       end
    #     }
    #
    def request_get(path, initheader = nil, &block) # :yield: +response+
      request(Get.new(path, initheader), &block)
    end

    # Sends a HEAD request to the +path+ and gets a response,
    # as an HTTPResponse object.
    #
    # Returns the response.
    # 
    # This method never raises Net::* exceptions.
    # 
    #     response = http.request_head('/index.html')
    #     p response['content-type']
    #
    def request_head(path, initheader = nil, &block)
      request(Head.new(path, initheader), &block)
    end

    # Sends a POST request to the +path+ and gets a response,
    # as an HTTPResponse object.
    # 
    # When called with a block, yields an HTTPResponse object.
    # The body of this response will not have been read yet;
    # the caller can process it using HTTPResponse#read_body,
    # if desired.
    #
    # Returns the response.
    # 
    # This method never raises Net::* exceptions.
    # 
    #     # example
    #     response = http.request_post('/cgi-bin/nice.rb', 'datadatadata...')
    #     p response.status
    #     puts response.body          # body is already read
    # 
    #     # using block
    #     http.request_post('/cgi-bin/nice.rb', 'datadatadata...') {|response|
    #       p response.status
    #       p response['content-type']
    #       response.read_body do |str|   # read body now
    #         print str
    #       end
    #     }
    #
    def request_post(path, data, initheader = nil, &block) # :yield: +response+
      request Post.new(path, initheader), data, &block
    end

    def request_put(path, data, initheader = nil, &block)   #:nodoc:
      request Put.new(path, initheader), data, &block
    end

    alias get2   request_get    #:nodoc: obsolete
    alias head2  request_head   #:nodoc: obsolete
    alias post2  request_post   #:nodoc: obsolete
    alias put2   request_put    #:nodoc: obsolete


    # Sends an HTTP request to the HTTP server.
    # This method also sends DATA string if DATA is given.
    #
    # Returns a HTTPResponse object.
    # 
    # This method never raises Net::* exceptions.
    #
    #    response = http.send_request('GET', '/index.html')
    #    puts response.body
    #
    def send_request(name, path, data = nil, header = nil)
      r = HTTPGenericRequest.new(name,(data ? true : false),true,path,header)
      request r, data
    end

    # Sends an HTTPRequest object REQUEST to the HTTP server.
    # This method also sends DATA string if REQUEST is a post/put request.
    # Giving DATA for get/head request causes ArgumentError.
    # 
    # When called with a block, yields an HTTPResponse object.
    # The body of this response will not have been read yet;
    # the caller can process it using HTTPResponse#read_body,
    # if desired.
    #
    # Returns a HTTPResponse object.
    # 
    # This method never raises Net::* exceptions.
    #
    def request(req, body = nil, &block)  # :yield: +response+
      unless started?
        start {
          req['connection'] ||= 'close'
          return request(req, body, &block)
        }
      end
      if proxy_user()
        unless use_ssl?
          req.proxy_basic_auth proxy_user(), proxy_pass()
        end
      end

      req.set_body_internal body
      begin
        begin_transport req
        req.exec @socket, @curr_http_version, edit_path(req.path)
        begin
          res = HTTPResponse.read_new(@socket)
        end while res.kind_of?(HTTPContinue)
        res.reading_body(@socket, req.response_body_permitted?) {
          yield res if block_given?
        }
        end_transport req, res
      rescue => exception
        D "Conn close because of error #{exception}"
        @socket.close if @socket and not @socket.closed?
        raise exception
      end

      res
    end

    private

    def begin_transport(req)
      if @socket.closed?
        connect
      end
      if @seems_1_0_server
        req['connection'] ||= 'close'
      end
      if not req.response_body_permitted? and @close_on_empty_response
        req['connection'] ||= 'close'
      end
      req['host'] ||= addr_port()
    end

    def end_transport(req, res)
      @curr_http_version = res.http_version
      if not res.body and @close_on_empty_response
        D 'Conn close'
        @socket.close
      elsif keep_alive?(req, res)
        D 'Conn keep-alive'
        if @socket.closed?
          D 'Conn (but seems 1.0 server)'
          @seems_1_0_server = true
        end
      else
        D 'Conn close'
        @socket.close
      end
    end

    def keep_alive?(req, res)
      return false if /close/i =~ req['connection'].to_s
      return false if @seems_1_0_server
      return true  if /keep-alive/i =~ res['connection'].to_s
      return false if /close/i      =~ res['connection'].to_s
      return true  if /keep-alive/i =~ res['proxy-connection'].to_s
      return false if /close/i      =~ res['proxy-connection'].to_s
      (@curr_http_version == '1.1')
    end

    #
    # utils
    #

    private

    def addr_port
      if use_ssl?
        address() + (port == HTTP.https_default_port ? '' : ":#{port()}")
      else
        address() + (port == HTTP.http_default_port ? '' : ":#{port()}")
      end
    end

    def D(msg)
      return unless @debug_output
      @debug_output << msg
      @debug_output << "\n"
    end

  end

  HTTPSession = HTTP


  #
  # Header module.
  #
  # Provides access to @header in the mixed-into class as a hash-like
  # object, except with case-insensitive keys.  Also provides
  # methods for accessing commonly-used header values in a more
  # convenient format.
  #
  module HTTPHeader

    def initialize_http_header(initheader)
      @header = {}
      return unless initheader
      initheader.each do |key, value|
        warn "net/http: warning: duplicated HTTP header: #{key}" if key?(key) and $VERBOSE
        @header[key.downcase] = [value.strip]
      end
    end

    def size   #:nodoc: obsolete
      @header.size
    end

    alias length size   #:nodoc: obsolete

    # Returns the header field corresponding to the case-insensitive key.
    # For example, a key of "Content-Type" might return "text/html"
    def [](key)
      a = @header[key.downcase] or return nil
      a.join(', ')
    end

    # Sets the header field corresponding to the case-insensitive key.
    def []=(key, val)
      unless val
        @header.delete key.downcase
        return val
      end
      @header[key.downcase] = [val]
    end

    # [Ruby 1.8.3]
    # Adds header field instead of replace.
    # Second argument +val+ must be a String.
    # See also #[]=, #[] and #get_fields.
    #
    #   request.add_field 'X-My-Header', 'a'
    #   p request['X-My-Header']              #=> "a"
    #   p request.get_fields('X-My-Header')   #=> ["a"]
    #   request.add_field 'X-My-Header', 'b'
    #   p request['X-My-Header']              #=> "a, b"
    #   p request.get_fields('X-My-Header')   #=> ["a", "b"]
    #   request.add_field 'X-My-Header', 'c'
    #   p request['X-My-Header']              #=> "a, b, c"
    #   p request.get_fields('X-My-Header')   #=> ["a", "b", "c"]
    #
    def add_field(key, val)
      if @header.key?(key.downcase)
        @header[key.downcase].push val
      else
        @header[key.downcase] = [val]
      end
    end

    # [Ruby 1.8.3]
    # Returns an array of header field strings corresponding to the
    # case-insensitive +key+.  This method allows you to get duplicated
    # header fields without any processing.  See also #[].
    #
    #   p response.get_fields('Set-Cookie')
    #     #=> ["session=al98axx; expires=Fri, 31-Dec-1999 23:58:23",
    #          "query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"]
    #   p response['Set-Cookie']
    #     #=> "session=al98axx; expires=Fri, 31-Dec-1999 23:58:23, query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"
    #
    def get_fields(key)
      return nil unless @header[key.downcase]
      @header[key.downcase].dup
    end

    # Returns the header field corresponding to the case-insensitive key.
    # Returns the default value +args+, or the result of the block, or nil,
    # if there's no header field named key.  See Hash#fetch
    def fetch(key, *args, &block)   #:yield: +key+
      a = @header.fetch(key.downcase, *args, &block)
      a.join(', ')
    end

    # Iterates for each header names and values.
    def each_header   #:yield: +key+, +value+
      @header.each do |k,va|
        yield k, va.join(', ')
      end
    end

    alias each each_header

    # Iterates for each header names.
    def each_name(&block)   #:yield: +key+
      @header.each_key(&block)
    end

    alias each_key each_name

    # Iterates for each capitalized header names.
    def each_capitalized_name(&block)   #:yield: +key+
      @header.each_key do |k|
        yield capitalize(k)
      end
    end

    # Iterates for each header values.
    def each_value   #:yield: +value+
      @header.each_value do |va|
        yield va.join(', ')
      end
    end

    # Removes a header field.
    def delete(key)
      @header.delete(key.downcase)
    end

    # true if +key+ header exists.
    def key?(key)
      @header.key?(key.downcase)
    end

    # Returns a Hash consist of header names and values.
    def to_hash
      @header.dup
    end

    # As for #each_header, except the keys are provided in capitalized form.
    def each_capitalized
      @header.each do |k,v|
        yield capitalize(k), v.join(', ')
      end
    end

    alias canonical_each each_capitalized

    def capitalize(name)
      name.split(/-/).map {|s| s.capitalize }.join('-')
    end
    private :capitalize

    # Returns an Array of Range objects which represents Range: header field,
    # or +nil+ if there is no such header.
    def range
      return nil unless @header['range']
      self['Range'].split(/,/).map {|spec|
        m = /bytes\s*=\s*(\d+)?\s*-\s*(\d+)?/i.match(spec) or
                raise HTTPHeaderSyntaxError, "wrong Range: #{spec}"
        d1 = m[1].to_i
        d2 = m[2].to_i
        if    m[1] and m[2] then  d1..d2
        elsif m[1]          then  d1..-1
        elsif          m[2] then -d2..-1
        else
          raise HTTPHeaderSyntaxError, 'range is not specified'
        end
      }
    end

    # Set Range: header from Range (arg r) or beginning index and
    # length from it (arg idx&len).
    #
    #   req.range = (0..1023)
    #   req.set_range 0, 1023
    #
    def set_range(r, e = nil)
      unless r
        @header.delete 'range'
        return r
      end
      r = (r...r+e) if e
      case r
      when Numeric
        n = r.to_i
        rangestr = (n > 0 ? "0-#{n-1}" : "-#{-n}")
      when Range
        first = r.first
        last = r.last
        last -= 1 if r.exclude_end?
        if last == -1
          rangestr = (first > 0 ? "#{first}-" : "-#{-first}")
        else
          raise HTTPHeaderSyntaxError, 'range.first is negative' if first < 0
          raise HTTPHeaderSyntaxError, 'range.last is negative' if last < 0
          raise HTTPHeaderSyntaxError, 'must be .first < .last' if first > last
          rangestr = "#{first}-#{last}"
        end
      else
        raise TypeError, 'Range/Integer is required'
      end
      @header['range'] = ["bytes=#{rangestr}"]
      r
    end

    alias range= set_range

    # Returns an Integer object which represents the Content-Length: header field
    # or +nil+ if that field is not provided.
    def content_length
      return nil unless key?('Content-Length')
      len = self['Content-Length'].slice(/\d+/) or
          raise HTTPHeaderSyntaxError, 'wrong Content-Length format'
      len.to_i
    end
    
    def content_length=(len)
      unless len
        @header.delete 'content-length'
        return nil
      end
      @header['content-length'] = [len.to_i.to_s]
    end

    # Returns "true" if the "transfer-encoding" header is present and
    # set to "chunked".  This is an HTTP/1.1 feature, allowing the 
    # the content to be sent in "chunks" without at the outset
    # stating the entire content length.
    def chunked?
      return false unless @header['transfer-encoding']
      field = self['Transfer-Encoding']
      (/(?:\A|[^\-\w])chunked(?![\-\w])/i =~ field) ? true : false
    end

    # Returns a Range object which represents Content-Range: header field.
    # This indicates, for a partial entity body, where this fragment
    # fits inside the full entity body, as range of byte offsets.
    def content_range
      return nil unless @header['content-range']
      m = %r<bytes\s+(\d+)-(\d+)/(\d+|\*)>i.match(self['Content-Range']) or
          raise HTTPHeaderSyntaxError, 'wrong Content-Range format'
      m[1].to_i .. m[2].to_i
    end

    # The length of the range represented in Content-Range: header.
    def range_length
      r = content_range() or return nil
      r.end - r.begin + 1
    end

    # Returns a content type string such as "text/html".
    # This method returns nil if Content-Type: header field does not exist.
    def content_type
      return nil unless main_type()
      if sub_type()
      then "#{main_type()}/#{sub_type()}"
      else main_type()
      end
    end

    # Returns a content type string such as "text".
    # This method returns nil if Content-Type: header field does not exist.
    def main_type
      return nil unless @header['content-type']
      self['Content-Type'].split(';').first.to_s.split('/')[0].to_s.strip
    end
    
    # Returns a content type string such as "html".
    # This method returns nil if Content-Type: header field does not exist
    # or sub-type is not given (e.g. "Content-Type: text").
    def sub_type
      return nil unless @header['content-type']
      main, sub = *self['Content-Type'].split(';').first.to_s.split('/')
      return nil unless sub
      sub.strip
    end

    # Returns content type parameters as a Hash as like
    # {"charset" => "iso-2022-jp"}.
    def type_params
      result = {}
      list = self['Content-Type'].to_s.split(';')
      list.shift
      list.each do |param|
        k, v = *param.split('=', 2)
        result[k.strip] = v.strip
      end
      result
    end

    # Set Content-Type: header field by +type+ and +params+.
    # +type+ must be a String, +params+ must be a Hash.
    def set_content_type(type, params = {})
      @header['content-type'] = [type + params.map{|k,v|"; #{k}=#{v}"}.join('')]
    end

    alias content_type= set_content_type

    # Set header fields and a body from HTML form data.
    # +params+ should be a Hash containing HTML form data.
    # Optional argument +sep+ means data record separator.
    #
    # This method also set Content-Type: header field to
    # application/x-www-form-urlencoded.
    def set_form_data(params, sep = '&')
      self.body = params.map {|k,v| "#{urlencode(k.to_s)}=#{urlencode(v.to_s)}" }.join(sep)
      self.content_type = 'application/x-www-form-urlencoded'
    end

    alias form_data= set_form_data

    def urlencode(str)
      str.gsub(/[^a-zA-Z0-9_\.\-]/n) {|s| sprintf('%%%02x', s[0]) }
    end
    private :urlencode

    # Set the Authorization: header for "Basic" authorization.
    def basic_auth(account, password)
      @header['authorization'] = [basic_encode(account, password)]
    end

    # Set Proxy-Authorization: header for "Basic" authorization.
    def proxy_basic_auth(account, password)
      @header['proxy-authorization'] = [basic_encode(account, password)]
    end

    def basic_encode(account, password)
      'Basic ' + ["#{account}:#{password}"].pack('m').delete("\r\n")
    end
    private :basic_encode

  end


  #
  # Parent of HTTPRequest class.  Do not use this directly; use
  # a subclass of HTTPRequest.
  #
  # Mixes in the HTTPHeader module.
  #
  class HTTPGenericRequest

    include HTTPHeader

    BUFSIZE = 16*1024

    def initialize(m, reqbody, resbody, path, initheader = nil)
      @method = m
      @request_has_body = reqbody
      @response_has_body = resbody
      raise ArgumentError, "HTTP request path is empty" if path.empty?
      @path = path
      initialize_http_header initheader
      self['Accept'] ||= '*/*'
      @body = nil
      @body_stream = nil
    end

    attr_reader :method
    attr_reader :path

    def inspect
      "\#<#{self.class} #{@method}>"
    end

    def request_body_permitted?
      @request_has_body
    end

    def response_body_permitted?
      @response_has_body
    end

    def body_exist?
      warn "Net::HTTPRequest#body_exist? is obsolete; use response_body_permitted?" if $VERBOSE
      response_body_permitted?
    end

    attr_reader :body

    def body=(str)
      @body = str
      @body_stream = nil
      str
    end

    attr_reader :body_stream

    def body_stream=(input)
      @body = nil
      @body_stream = input
      input
    end

    def set_body_internal(str)   #:nodoc: internal use only
      raise ArgumentError, "both of body argument and HTTPRequest#body set" if str and (@body or @body_stream)
      self.body = str if str
    end

    #
    # write
    #

    def exec(sock, ver, path)   #:nodoc: internal use only
      if @body
        send_request_with_body sock, ver, path, @body
      elsif @body_stream
        send_request_with_body_stream sock, ver, path, @body_stream
      else
        write_header sock, ver, path
      end
    end

    private

    def send_request_with_body(sock, ver, path, body)
      self.content_length = body.length
      delete 'Transfer-Encoding'
      supply_default_content_type
      write_header sock, ver, path
      sock.write body
    end

    def send_request_with_body_stream(sock, ver, path, f)
      unless content_length() or chunked?
        raise ArgumentError,
            "Content-Length not given and Transfer-Encoding is not `chunked'"
      end
      supply_default_content_type
      write_header sock, ver, path
      if chunked?
        while s = f.read(BUFSIZE)
          sock.write(sprintf("%x\r\n", s.length) << s << "\r\n")
        end
        sock.write "0\r\n\r\n"
      else
        while s = f.read(BUFSIZE)
          sock.write s
        end
      end
    end

    def supply_default_content_type
      return if content_type()
      warn 'net/http: warning: Content-Type did not set; using application/x-www-form-urlencoded' if $VERBOSE
      set_content_type 'application/x-www-form-urlencoded'
    end

    def write_header(sock, ver, path)
      buf = "#{@method} #{path} HTTP/#{ver}\r\n"
      each_capitalized do |k,v|
        buf << "#{k}: #{v}\r\n"
      end
      buf << "\r\n"
      sock.write buf
    end
  
  end


  # 
  # HTTP request class. This class wraps request header and entity path.
  # You *must* use its subclass, Net::HTTP::Get, Post, Head.
  # 
  class HTTPRequest < HTTPGenericRequest

    # Creates HTTP request object.
    def initialize(path, initheader = nil)
      super self.class::METHOD,
            self.class::REQUEST_HAS_BODY,
            self.class::RESPONSE_HAS_BODY,
            path, initheader
    end
  end


  class HTTP   # reopen
    #
    # HTTP 1.1 methods --- RFC2616
    #

    class Get < HTTPRequest
      METHOD = 'GET'
      REQUEST_HAS_BODY  = false
      RESPONSE_HAS_BODY = true
    end

    class Head < HTTPRequest
      METHOD = 'HEAD'
      REQUEST_HAS_BODY = false
      RESPONSE_HAS_BODY = false
    end

    class Post < HTTPRequest
      METHOD = 'POST'
      REQUEST_HAS_BODY = true
      RESPONSE_HAS_BODY = true
    end

    class Put < HTTPRequest
      METHOD = 'PUT'
      REQUEST_HAS_BODY = true
      RESPONSE_HAS_BODY = true
    end

    class Delete < HTTPRequest
      METHOD = 'DELETE'
      REQUEST_HAS_BODY = false
      RESPONSE_HAS_BODY = true
    end

    class Options < HTTPRequest
      METHOD = 'OPTIONS'
      REQUEST_HAS_BODY = false
      RESPONSE_HAS_BODY = false
    end

    class Trace < HTTPRequest
      METHOD = 'TRACE'
      REQUEST_HAS_BODY = false
      RESPONSE_HAS_BODY = true
    end

    #
    # WebDAV methods --- RFC2518
    #

    class Propfind < HTTPRequest
      METHOD = 'PROPFIND'
      REQUEST_HAS_BODY = true
      RESPONSE_HAS_BODY = true
    end

    class Proppatch < HTTPRequest
      METHOD = 'PROPPATCH'
      REQUEST_HAS_BODY = true
      RESPONSE_HAS_BODY = true
    end

    class Mkcol < HTTPRequest
      METHOD = 'MKCOL'
      REQUEST_HAS_BODY = true
      RESPONSE_HAS_BODY = true
    end

    class Copy < HTTPRequest
      METHOD = 'COPY'
      REQUEST_HAS_BODY = false
      RESPONSE_HAS_BODY = true
    end

    class Move < HTTPRequest
      METHOD = 'MOVE'
      REQUEST_HAS_BODY = false
      RESPONSE_HAS_BODY = true
    end

    class Lock < HTTPRequest
      METHOD = 'LOCK'
      REQUEST_HAS_BODY = true
      RESPONSE_HAS_BODY = true
    end

    class Unlock < HTTPRequest
      METHOD = 'UNLOCK'
      REQUEST_HAS_BODY = true
      RESPONSE_HAS_BODY = true
    end
  end


  ###
  ### Response
  ###

  # HTTP exception class.
  # You must use its subclasses.
  module HTTPExceptions
    def initialize(msg, res)   #:nodoc:
      super msg
      @response = res
    end
    attr_reader :response
    alias data response    #:nodoc: obsolete
  end
  class HTTPError < ProtocolError
    include HTTPExceptions
  end
  class HTTPRetriableError < ProtoRetriableError
    include HTTPExceptions
  end
  class HTTPServerException < ProtoServerError
    # We cannot use the name "HTTPServerError", it is the name of the response.
    include HTTPExceptions
  end
  class HTTPFatalError < ProtoFatalError
    include HTTPExceptions
  end


  # HTTP response class. This class wraps response header and entity.
  # Mixes in the HTTPHeader module, which provides access to response
  # header values both via hash-like methods and individual readers.
  # Note that each possible HTTP response code defines its own 
  # HTTPResponse subclass.  These are listed below.
  # All classes are
  # defined under the Net module. Indentation indicates inheritance.
  # 
  #   xxx        HTTPResponse
  # 
  #     1xx        HTTPInformation
  #       100        HTTPContinue    
  #       101        HTTPSwitchProtocol
  # 
  #     2xx        HTTPSuccess
  #       200        HTTPOK
  #       201        HTTPCreated
  #       202        HTTPAccepted
  #       203        HTTPNonAuthoritativeInformation
  #       204        HTTPNoContent
  #       205        HTTPResetContent
  #       206        HTTPPartialContent
  # 
  #     3xx        HTTPRedirection
  #       300        HTTPMultipleChoice
  #       301        HTTPMovedPermanently
  #       302        HTTPFound
  #       303        HTTPSeeOther
  #       304        HTTPNotModified
  #       305        HTTPUseProxy
  #       307        HTTPTemporaryRedirect
  # 
  #     4xx        HTTPClientError
  #       400        HTTPBadRequest
  #       401        HTTPUnauthorized
  #       402        HTTPPaymentRequired
  #       403        HTTPForbidden
  #       404        HTTPNotFound
  #       405        HTTPMethodNotAllowed
  #       406        HTTPNotAcceptable
  #       407        HTTPProxyAuthenticationRequired
  #       408        HTTPRequestTimeOut
  #       409        HTTPConflict
  #       410        HTTPGone
  #       411        HTTPLengthRequired
  #       412        HTTPPreconditionFailed
  #       413        HTTPRequestEntityTooLarge
  #       414        HTTPRequestURITooLong
  #       415        HTTPUnsupportedMediaType
  #       416        HTTPRequestedRangeNotSatisfiable
  #       417        HTTPExpectationFailed
  # 
  #     5xx        HTTPServerError
  #       500        HTTPInternalServerError
  #       501        HTTPNotImplemented
  #       502        HTTPBadGateway
  #       503        HTTPServiceUnavailable
  #       504        HTTPGatewayTimeOut
  #       505        HTTPVersionNotSupported
  # 
  #     xxx        HTTPUnknownResponse
  #
  class HTTPResponse
    # true if the response has body.
    def HTTPResponse.body_permitted?
      self::HAS_BODY
    end

    def HTTPResponse.exception_type   # :nodoc: internal use only
      self::EXCEPTION_TYPE
    end
  end   # reopened after

  # :stopdoc:

  class HTTPUnknownResponse < HTTPResponse
    HAS_BODY = true
    EXCEPTION_TYPE = HTTPError
  end
  class HTTPInformation < HTTPResponse           # 1xx
    HAS_BODY = false
    EXCEPTION_TYPE = HTTPError
  end
  class HTTPSuccess < HTTPResponse               # 2xx
    HAS_BODY = true
    EXCEPTION_TYPE = HTTPError
  end
  class HTTPRedirection < HTTPResponse           # 3xx
    HAS_BODY = true
    EXCEPTION_TYPE = HTTPRetriableError
  end
  class HTTPClientError < HTTPResponse           # 4xx
    HAS_BODY = true
    EXCEPTION_TYPE = HTTPServerException   # for backward compatibility
  end
  class HTTPServerError < HTTPResponse           # 5xx
    HAS_BODY = true
    EXCEPTION_TYPE = HTTPFatalError    # for backward compatibility
  end

  class HTTPContinue < HTTPInformation           # 100
    HAS_BODY = false
  end
  class HTTPSwitchProtocol < HTTPInformation     # 101
    HAS_BODY = false
  end

  class HTTPOK < HTTPSuccess                            # 200
    HAS_BODY = true
  end
  class HTTPCreated < HTTPSuccess                       # 201
    HAS_BODY = true
  end
  class HTTPAccepted < HTTPSuccess                      # 202
    HAS_BODY = true
  end
  class HTTPNonAuthoritativeInformation < HTTPSuccess   # 203
    HAS_BODY = true
  end
  class HTTPNoContent < HTTPSuccess                     # 204
    HAS_BODY = false
  end
  class HTTPResetContent < HTTPSuccess                  # 205
    HAS_BODY = false
  end
  class HTTPPartialContent < HTTPSuccess                # 206
    HAS_BODY = true
  end

  class HTTPMultipleChoice < HTTPRedirection     # 300
    HAS_BODY = true
  end
  class HTTPMovedPermanently < HTTPRedirection   # 301
    HAS_BODY = true
  end
  class HTTPFound < HTTPRedirection              # 302
    HAS_BODY = true
  end
  HTTPMovedTemporarily = HTTPFound
  class HTTPSeeOther < HTTPRedirection           # 303
    HAS_BODY = true
  end
  class HTTPNotModified < HTTPRedirection        # 304
    HAS_BODY = false
  end
  class HTTPUseProxy < HTTPRedirection           # 305
    HAS_BODY = false
  end
  # 306 unused
  class HTTPTemporaryRedirect < HTTPRedirection  # 307
    HAS_BODY = true
  end

  class HTTPBadRequest < HTTPClientError                    # 400
    HAS_BODY = true
  end
  class HTTPUnauthorized < HTTPClientError                  # 401
    HAS_BODY = true
  end
  class HTTPPaymentRequired < HTTPClientError               # 402
    HAS_BODY = true
  end
  class HTTPForbidden < HTTPClientError                     # 403
    HAS_BODY = true
  end
  class HTTPNotFound < HTTPClientError                      # 404
    HAS_BODY = true
  end
  class HTTPMethodNotAllowed < HTTPClientError              # 405
    HAS_BODY = true
  end
  class HTTPNotAcceptable < HTTPClientError                 # 406
    HAS_BODY = true
  end
  class HTTPProxyAuthenticationRequired < HTTPClientError   # 407
    HAS_BODY = true
  end
  class HTTPRequestTimeOut < HTTPClientError                # 408
    HAS_BODY = true
  end
  class HTTPConflict < HTTPClientError                      # 409
    HAS_BODY = true
  end
  class HTTPGone < HTTPClientError                          # 410
    HAS_BODY = true
  end
  class HTTPLengthRequired < HTTPClientError                # 411
    HAS_BODY = true
  end
  class HTTPPreconditionFailed < HTTPClientError            # 412
    HAS_BODY = true
  end
  class HTTPRequestEntityTooLarge < HTTPClientError         # 413
    HAS_BODY = true
  end
  class HTTPRequestURITooLong < HTTPClientError             # 414
    HAS_BODY = true
  end
  HTTPRequestURITooLarge = HTTPRequestURITooLong
  class HTTPUnsupportedMediaType < HTTPClientError          # 415
    HAS_BODY = true
  end
  class HTTPRequestedRangeNotSatisfiable < HTTPClientError  # 416
    HAS_BODY = true
  end
  class HTTPExpectationFailed < HTTPClientError             # 417
    HAS_BODY = true
  end

  class HTTPInternalServerError < HTTPServerError   # 500
    HAS_BODY = true
  end
  class HTTPNotImplemented < HTTPServerError        # 501
    HAS_BODY = true
  end
  class HTTPBadGateway < HTTPServerError            # 502
    HAS_BODY = true
  end
  class HTTPServiceUnavailable < HTTPServerError    # 503
    HAS_BODY = true
  end
  class HTTPGatewayTimeOut < HTTPServerError        # 504
    HAS_BODY = true
  end
  class HTTPVersionNotSupported < HTTPServerError   # 505
    HAS_BODY = true
  end

  # :startdoc:


  class HTTPResponse   # reopen

    CODE_CLASS_TO_OBJ = {
      '1' => HTTPInformation,
      '2' => HTTPSuccess,
      '3' => HTTPRedirection,
      '4' => HTTPClientError,
      '5' => HTTPServerError
    }
    CODE_TO_OBJ = {
      '100' => HTTPContinue,
      '101' => HTTPSwitchProtocol,

      '200' => HTTPOK,
      '201' => HTTPCreated,
      '202' => HTTPAccepted,
      '203' => HTTPNonAuthoritativeInformation,
      '204' => HTTPNoContent,
      '205' => HTTPResetContent,
      '206' => HTTPPartialContent,

      '300' => HTTPMultipleChoice,
      '301' => HTTPMovedPermanently,
      '302' => HTTPFound,
      '303' => HTTPSeeOther,
      '304' => HTTPNotModified,
      '305' => HTTPUseProxy,
      '307' => HTTPTemporaryRedirect,

      '400' => HTTPBadRequest,
      '401' => HTTPUnauthorized,
      '402' => HTTPPaymentRequired,
      '403' => HTTPForbidden,
      '404' => HTTPNotFound,
      '405' => HTTPMethodNotAllowed,
      '406' => HTTPNotAcceptable,
      '407' => HTTPProxyAuthenticationRequired,
      '408' => HTTPRequestTimeOut,
      '409' => HTTPConflict,
      '410' => HTTPGone,
      '411' => HTTPLengthRequired,
      '412' => HTTPPreconditionFailed,
      '413' => HTTPRequestEntityTooLarge,
      '414' => HTTPRequestURITooLong,
      '415' => HTTPUnsupportedMediaType,
      '416' => HTTPRequestedRangeNotSatisfiable,
      '417' => HTTPExpectationFailed,

      '500' => HTTPInternalServerError,
      '501' => HTTPNotImplemented,
      '502' => HTTPBadGateway,
      '503' => HTTPServiceUnavailable,
      '504' => HTTPGatewayTimeOut,
      '505' => HTTPVersionNotSupported
    }

    class << HTTPResponse
      def read_new(sock)   #:nodoc: internal use only
        httpv, code, msg = read_status_line(sock)
        res = response_class(code).new(httpv, code, msg)
        each_response_header(sock) do |k,v|
          res.add_field k, v
        end
        res
      end

      private

      def read_status_line(sock)
        str = sock.readline
        m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/in.match(str) or
          raise HTTPBadResponse, "wrong status line: #{str.dump}"
        m.captures
      end

      def response_class(code)
        CODE_TO_OBJ[code] or
        CODE_CLASS_TO_OBJ[code[0,1]] or
        HTTPUnknownResponse
      end

      def each_response_header(sock)
        while true
          line = sock.readuntil("\n", true).sub(/\s+\z/, '')
          break if line.empty?
          m = /\A([^:]+):\s*/.match(line) or
              raise HTTPBadResponse, 'wrong header line format'
          yield m[1], m.post_match
        end
      end
    end

    # next is to fix bug in RDoc, where the private inside class << self
    # spills out.
    public 

    include HTTPHeader

    def initialize(httpv, code, msg)   #:nodoc: internal use only
      @http_version = httpv
      @code         = code
      @message      = msg
      initialize_http_header nil
      @body = nil
      @read = false
    end

    # The HTTP version supported by the server.
    attr_reader :http_version

    # HTTP result code string. For example, '302'.  You can also
    # determine the response type by which response subclass the
    # response object is an instance of.
    attr_reader :code

    # HTTP result message. For example, 'Not Found'.
    attr_reader :message
    alias msg message   # :nodoc: obsolete

    def inspect
      "#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
    end

    # For backward compatibility.
    # To allow Net::HTTP 1.1 style assignment
    # e.g.
    #    response, body = Net::HTTP.get(....)
    # 
    def to_ary
      warn "net/http.rb: warning: Net::HTTP v1.1 style assignment found at #{caller(1)[0]}; use `response = http.get(...)' instead." if $VERBOSE
      res = self.dup
      class << res
        undef to_ary
      end
      [res, res.body]
    end

    #
    # response <-> exception relationship
    #

    def code_type   #:nodoc:
      self.class
    end

    def error!   #:nodoc:
      raise error_type().new(@code + ' ' + @message.dump, self)
    end

    def error_type   #:nodoc:
      self.class::EXCEPTION_TYPE
    end

    # Raises HTTP error if the response is not 2xx.
    def value
      error! unless self.kind_of?(HTTPSuccess)
    end

    #
    # header (for backward compatibility only; DO NOT USE)
    #

    def response   #:nodoc:
      warn "#{caller(1)[0]}: warning: HTTPResponse#response is obsolete" if $VERBOSE
      self
    end

    def header   #:nodoc:
      warn "#{caller(1)[0]}: warning: HTTPResponse#header is obsolete" if $VERBOSE
      self
    end

    def read_header   #:nodoc:
      warn "#{caller(1)[0]}: warning: HTTPResponse#read_header is obsolete" if $VERBOSE
      self
    end

    #
    # body
    #

    def reading_body(sock, reqmethodallowbody)  #:nodoc: internal use only
      @socket = sock
      @body_exist = reqmethodallowbody && self.class.body_permitted?
      begin
        yield
        self.body   # ensure to read body
      ensure
        @socket = nil
      end
    end

    # Gets entity body.  If the block given, yields it to +block+.
    # The body is provided in fragments, as it is read in from the socket.
    #
    # Calling this method a second or subsequent time will return the
    # already read string.
    #
    #   http.request_get('/index.html') {|res|
    #     puts res.read_body
    #   }
    #
    #   http.request_get('/index.html') {|res|
    #     p res.read_body.object_id   # 538149362
    #     p res.read_body.object_id   # 538149362
    #   }
    #
    #   # using iterator
    #   http.request_get('/index.html') {|res|
    #     res.read_body do |segment|
    #       print segment
    #     end
    #   }
    #
    def read_body(dest = nil, &block)
      if @read
        raise IOError, "#{self.class}\#read_body called twice" if dest or block
        return @body
      end
      to = procdest(dest, block)
      stream_check
      if @body_exist
        read_body_0 to
        @body = to
      else
        @body = nil
      end
      @read = true

      @body
    end

    # Returns the entity body.
    #
    # Calling this method a second or subsequent time will return the
    # already read string.
    #
    #   http.request_get('/index.html') {|res|
    #     puts res.body
    #   }
    #
    #   http.request_get('/index.html') {|res|
    #     p res.body.object_id   # 538149362
    #     p res.body.object_id   # 538149362
    #   }
    #
    def body
      read_body()
    end

    alias entity body   #:nodoc: obsolete

    private

    def read_body_0(dest)
      if chunked?
        read_chunked dest
        return
      end
      clen = content_length()
      if clen
        @socket.read clen, dest, true   # ignore EOF
        return
      end
      clen = range_length()
      if clen
        @socket.read clen, dest
        return
      end
      @socket.read_all dest
    end

    def read_chunked(dest)
      len = nil
      total = 0
      while true
        line = @socket.readline
        hexlen = line.slice(/[0-9a-fA-F]+/) or
            raise HTTPBadResponse, "wrong chunk size line: #{line}"
        len = hexlen.hex
        break if len == 0
        @socket.read len, dest; total += len
        @socket.read 2   # \r\n
      end
      until @socket.readline.empty?
        # none
      end
    end

    def stream_check
      raise IOError, 'attempt to read body out of block' if @socket.closed?
    end

    def procdest(dest, block)
      raise ArgumentError, 'both arg and block given for HTTP method' \
          if dest and block
      if block
        ReadAdapter.new(block)
      else
        dest || ''
      end
    end

  end


  # :enddoc:

  #--
  # for backward compatibility
  class HTTP
    ProxyMod = ProxyDelta
  end
  module NetPrivate
    HTTPRequest = ::Net::HTTPRequest
  end

  HTTPInformationCode = HTTPInformation
  HTTPSuccessCode     = HTTPSuccess
  HTTPRedirectionCode = HTTPRedirection
  HTTPRetriableCode   = HTTPRedirection
  HTTPClientErrorCode = HTTPClientError
  HTTPFatalErrorCode  = HTTPClientError
  HTTPServerErrorCode = HTTPServerError
  HTTPResponceReceiver = HTTPResponse

end   # module Net
PK     UZ\@      net/ftptls.rbnu [        =begin
= $RCSfile$ -- SSL/TLS enhancement for Net::HTTP.

= Info
  'OpenSSL for Ruby 2' project
  Copyright (C) 2003 Blaz Grilc <farmer@gmx.co.uk>
  All rights reserved.

= Licence
  This program is licenced under the same licence as Ruby.
  (See the file 'LICENCE'.)

= Requirements

= Version
  $Id: ftptls.rb 13657 2007-10-08 11:16:54Z gotoyuzo $
  
= Notes
  Tested on FreeBSD 5-CURRENT and 4-STABLE
  - ruby 1.6.8 (2003-01-17) [i386-freebsd5]
  - OpenSSL 0.9.7a Feb 19 2003
  - ruby-openssl-0.2.0.p0
  tested on ftp server: glftpd 1.30
=end

require 'socket'
require 'openssl'
require 'net/ftp'

module Net
  class FTPTLS < FTP
    def connect(host, port=FTP_PORT)
      @hostname = host
      super
    end

    def login(user = "anonymous", passwd = nil, acct = nil)
       store = OpenSSL::X509::Store.new
       store.set_default_paths
       ctx = OpenSSL::SSL::SSLContext.new('SSLv23')
       ctx.cert_store = store
       ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
       ctx.key = nil
       ctx.cert = nil
       voidcmd("AUTH TLS")
       @sock = OpenSSL::SSL::SSLSocket.new(@sock, ctx)
       @sock.connect
       @sock.post_connection_check(@hostname)
       super(user, passwd, acct)
       voidcmd("PBSZ 0")
    end
  end
end
PK     UZ\e;V  ;V  
  net/ftp.rbnu [        # 
# = net/ftp.rb - FTP Client Library
# 
# Written by Shugo Maeda <shugo@ruby-lang.org>.
#
# Documentation by Gavin Sinclair, sourced from "Programming Ruby" (Hunt/Thomas)
# and "Ruby In a Nutshell" (Matsumoto), used with permission.
# 
# This library is distributed under the terms of the Ruby license.
# You can freely distribute/modify this library.
#
# It is included in the Ruby standard library.
#
# See the Net::FTP class for an overview.
#

require "socket"
require "monitor"

module Net

  # :stopdoc:
  class FTPError < StandardError; end
  class FTPReplyError < FTPError; end
  class FTPTempError < FTPError; end 
  class FTPPermError < FTPError; end 
  class FTPProtoError < FTPError; end
  # :startdoc:

  #
  # This class implements the File Transfer Protocol.  If you have used a
  # command-line FTP program, and are familiar with the commands, you will be
  # able to use this class easily.  Some extra features are included to take
  # advantage of Ruby's style and strengths.
  #
  # == Example
  # 
  #   require 'net/ftp'
  #
  # === Example 1
  #  
  #   ftp = Net::FTP.new('ftp.netlab.co.jp')
  #   ftp.login
  #   files = ftp.chdir('pub/lang/ruby/contrib')
  #   files = ftp.list('n*')
  #   ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024)
  #   ftp.close
  #
  # === Example 2
  #
  #   Net::FTP.open('ftp.netlab.co.jp') do |ftp|
  #     ftp.login
  #     files = ftp.chdir('pub/lang/ruby/contrib')
  #     files = ftp.list('n*')
  #     ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024)
  #   end
  #
  # == Major Methods
  #
  # The following are the methods most likely to be useful to users:
  # - FTP.open
  # - #getbinaryfile
  # - #gettextfile
  # - #putbinaryfile
  # - #puttextfile
  # - #chdir
  # - #nlst
  # - #size
  # - #rename
  # - #delete
  #
  class FTP
    include MonitorMixin
    
    # :stopdoc:
    FTP_PORT = 21
    CRLF = "\r\n"
    DEFAULT_BLOCKSIZE = 4096
    # :startdoc:
    
    # When +true+, transfers are performed in binary mode.  Default: +true+.
    attr_accessor :binary

    # When +true+, the connection is in passive mode.  Default: +false+.
    attr_accessor :passive

    # When +true+, all traffic to and from the server is written
    # to +$stdout+.  Default: +false+.
    attr_accessor :debug_mode

    # Sets or retrieves the +resume+ status, which decides whether incomplete
    # transfers are resumed or restarted.  Default: +false+.
    attr_accessor :resume

    # The server's welcome message.
    attr_reader :welcome

    # The server's last response code.
    attr_reader :last_response_code
    alias lastresp last_response_code

    # The server's last response.
    attr_reader :last_response
    
    #
    # A synonym for <tt>FTP.new</tt>, but with a mandatory host parameter.
    #
    # If a block is given, it is passed the +FTP+ object, which will be closed
    # when the block finishes, or when an exception is raised.
    #
    def FTP.open(host, user = nil, passwd = nil, acct = nil)
      if block_given?
        ftp = new(host, user, passwd, acct)
        begin
          yield ftp
        ensure
          ftp.close
        end
      else
        new(host, user, passwd, acct)
      end
    end
    
    #
    # Creates and returns a new +FTP+ object. If a +host+ is given, a connection
    # is made. Additionally, if the +user+ is given, the given user name,
    # password, and (optionally) account are used to log in.  See #login.
    #
    def initialize(host = nil, user = nil, passwd = nil, acct = nil)
      super()
      @binary = true
      @passive = false
      @debug_mode = false
      @resume = false
      if host
	connect(host)
	if user
	  login(user, passwd, acct)
	end
      end
    end

    # Obsolete
    def return_code
      $stderr.puts("warning: Net::FTP#return_code is obsolete and do nothing")
      return "\n"
    end

    # Obsolete
    def return_code=(s)
      $stderr.puts("warning: Net::FTP#return_code= is obsolete and do nothing")
    end

    def open_socket(host, port)
      if defined? SOCKSSocket and ENV["SOCKS_SERVER"]
	@passive = true
	return SOCKSSocket.open(host, port)
      else
	return TCPSocket.open(host, port)
      end
    end
    private :open_socket
    
    #
    # Establishes an FTP connection to host, optionally overriding the default
    # port. If the environment variable +SOCKS_SERVER+ is set, sets up the
    # connection through a SOCKS proxy. Raises an exception (typically
    # <tt>Errno::ECONNREFUSED</tt>) if the connection cannot be established.
    #
    def connect(host, port = FTP_PORT)
      if @debug_mode
	print "connect: ", host, ", ", port, "\n"
      end
      synchronize do
	@sock = open_socket(host, port)
	voidresp
      end
    end

    #
    # WRITEME or make private
    #
    def set_socket(sock, get_greeting = true)
      synchronize do
	@sock = sock
	if get_greeting
	  voidresp
	end
      end
    end

    def sanitize(s)
      if s =~ /^PASS /i
	return s[0, 5] + "*" * (s.length - 5)
      else
	return s
      end
    end
    private :sanitize
    
    def putline(line)
      if @debug_mode
	print "put: ", sanitize(line), "\n"
      end
      line = line + CRLF
      @sock.write(line)
    end
    private :putline
    
    def getline
      line = @sock.readline # if get EOF, raise EOFError
      line.sub!(/(\r\n|\n|\r)\z/n, "")
      if @debug_mode
	print "get: ", sanitize(line), "\n"
      end
      return line
    end
    private :getline
    
    def getmultiline
      line = getline
      buff = line
      if line[3] == ?-
	  code = line[0, 3]
	begin
	  line = getline
	  buff << "\n" << line
	end until line[0, 3] == code and line[3] != ?-
      end
      return buff << "\n"
    end
    private :getmultiline
    
    def getresp
      @last_response = getmultiline
      @last_response_code = @last_response[0, 3]
      case @last_response_code
      when /\A[123]/
	return @last_response
      when /\A4/
	raise FTPTempError, @last_response
      when /\A5/
	raise FTPPermError, @last_response
      else
	raise FTPProtoError, @last_response
      end
    end
    private :getresp
    
    def voidresp
      resp = getresp
      if resp[0] != ?2
	raise FTPReplyError, resp
      end
    end
    private :voidresp
    
    #
    # Sends a command and returns the response.
    #
    def sendcmd(cmd)
      synchronize do
	putline(cmd)
	return getresp
      end
    end
    
    #
    # Sends a command and expect a response beginning with '2'.
    #
    def voidcmd(cmd)
      synchronize do
	putline(cmd)
	voidresp
      end
    end
    
    def sendport(host, port)
      af = (@sock.peeraddr)[0]
      if af == "AF_INET"
	cmd = "PORT " + (host.split(".") + port.divmod(256)).join(",")
      elsif af == "AF_INET6"
	cmd = sprintf("EPRT |2|%s|%d|", host, port)
      else
	raise FTPProtoError, host
      end
      voidcmd(cmd)
    end
    private :sendport
    
    def makeport
      sock = TCPServer.open(@sock.addr[3], 0)
      port = sock.addr[1]
      host = sock.addr[3]
      resp = sendport(host, port)
      return sock
    end
    private :makeport
    
    def makepasv
      if @sock.peeraddr[0] == "AF_INET"
	host, port = parse227(sendcmd("PASV"))
      else
	host, port = parse229(sendcmd("EPSV"))
	#     host, port = parse228(sendcmd("LPSV"))
      end
      return host, port
    end
    private :makepasv
    
    def transfercmd(cmd, rest_offset = nil)
      if @passive
	host, port = makepasv
	conn = open_socket(host, port)
	if @resume and rest_offset
	  resp = sendcmd("REST " + rest_offset.to_s) 
	  if resp[0] != ?3
	    raise FTPReplyError, resp
	  end
	end
	resp = sendcmd(cmd)
        # skip 2XX for some ftp servers
        resp = getresp if resp[0] == ?2
	if resp[0] != ?1
	  raise FTPReplyError, resp
	end
      else
	sock = makeport
	if @resume and rest_offset
	  resp = sendcmd("REST " + rest_offset.to_s) 
	  if resp[0] != ?3
	    raise FTPReplyError, resp
	  end
	end
	resp = sendcmd(cmd)
        # skip 2XX for some ftp servers
        resp = getresp if resp[0] == ?2
	if resp[0] != ?1
	  raise FTPReplyError, resp
	end
	conn = sock.accept
	sock.close
      end
      return conn
    end
    private :transfercmd
    
    def getaddress
      thishost = Socket.gethostname rescue ""
      if not thishost.index(".")
        thishost = Socket.gethostbyname(thishost)[0] rescue ""
      end
      if ENV.has_key?("LOGNAME")
	realuser = ENV["LOGNAME"]
      elsif ENV.has_key?("USER")
	realuser = ENV["USER"]
      else
	realuser = "anonymous"
      end
      return realuser + "@" + thishost
    end
    private :getaddress
    
    #
    # Logs in to the remote host. The session must have been previously
    # connected.  If +user+ is the string "anonymous" and the +password+ is
    # +nil+, a password of <tt>user@host</tt> is synthesized. If the +acct+
    # parameter is not +nil+, an FTP ACCT command is sent following the
    # successful login.  Raises an exception on error (typically
    # <tt>Net::FTPPermError</tt>).
    #
    def login(user = "anonymous", passwd = nil, acct = nil)
      if user == "anonymous" and passwd == nil
	passwd = getaddress
      end
      
      resp = ""
      synchronize do
	resp = sendcmd('USER ' + user)
	if resp[0] == ?3
          raise FTPReplyError, resp if passwd.nil?
	  resp = sendcmd('PASS ' + passwd)
	end
	if resp[0] == ?3
          raise FTPReplyError, resp if acct.nil?
	  resp = sendcmd('ACCT ' + acct)
	end
      end
      if resp[0] != ?2
	raise FTPReplyError, resp
      end
      @welcome = resp
    end
    
    #
    # Puts the connection into binary (image) mode, issues the given command,
    # and fetches the data returned, passing it to the associated block in
    # chunks of +blocksize+ characters. Note that +cmd+ is a server command
    # (such as "RETR myfile").
    #
    def retrbinary(cmd, blocksize, rest_offset = nil) # :yield: data
      synchronize do
	voidcmd("TYPE I")
	conn = transfercmd(cmd, rest_offset)
	loop do
	  data = conn.read(blocksize)
	  break if data == nil
	  yield(data)
	end
	conn.close
	voidresp
      end
    end
    
    #
    # Puts the connection into ASCII (text) mode, issues the given command, and
    # passes the resulting data, one line at a time, to the associated block. If
    # no block is given, prints the lines. Note that +cmd+ is a server command
    # (such as "RETR myfile").
    #
    def retrlines(cmd) # :yield: line
      synchronize do
	voidcmd("TYPE A")
	conn = transfercmd(cmd)
	loop do
	  line = conn.gets
	  break if line == nil
	  if line[-2, 2] == CRLF
	    line = line[0 .. -3]
	  elsif line[-1] == ?\n
	    line = line[0 .. -2]
	  end
	  yield(line)
	end
	conn.close
	voidresp
      end
    end
    
    #
    # Puts the connection into binary (image) mode, issues the given server-side
    # command (such as "STOR myfile"), and sends the contents of the file named
    # +file+ to the server. If the optional block is given, it also passes it
    # the data, in chunks of +blocksize+ characters.
    #
    def storbinary(cmd, file, blocksize, rest_offset = nil, &block) # :yield: data
      if rest_offset
        file.seek(rest_offset, IO::SEEK_SET)
      end
      synchronize do
	voidcmd("TYPE I")
	conn = transfercmd(cmd, rest_offset)
	loop do
	  buf = file.read(blocksize)
	  break if buf == nil
	  conn.write(buf)
	  yield(buf) if block
	end
	conn.close
	voidresp
      end
    end
    
    #
    # Puts the connection into ASCII (text) mode, issues the given server-side
    # command (such as "STOR myfile"), and sends the contents of the file
    # named +file+ to the server, one line at a time. If the optional block is
    # given, it also passes it the lines.
    #
    def storlines(cmd, file, &block) # :yield: line
      synchronize do
	voidcmd("TYPE A")
	conn = transfercmd(cmd)
	loop do
	  buf = file.gets
	  break if buf == nil
	  if buf[-2, 2] != CRLF
	    buf = buf.chomp + CRLF
	  end
	  conn.write(buf)
	  yield(buf) if block
	end
	conn.close
	voidresp
      end
    end

    #
    # Retrieves +remotefile+ in binary mode, storing the result in +localfile+.
    # If a block is supplied, it is passed the retrieved data in +blocksize+
    # chunks.
    #
    def getbinaryfile(remotefile, localfile = File.basename(remotefile),
		      blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
      if @resume
	rest_offset = File.size?(localfile)
	f = open(localfile, "a")
      else
	rest_offset = nil
	f = open(localfile, "w")
      end
      begin
	f.binmode
	retrbinary("RETR " + remotefile, blocksize, rest_offset) do |data|
	  f.write(data)
	  yield(data) if block
	end
      ensure
	f.close
      end
    end
    
    #
    # Retrieves +remotefile+ in ASCII (text) mode, storing the result in
    # +localfile+. If a block is supplied, it is passed the retrieved data one
    # line at a time.
    #
    def gettextfile(remotefile, localfile = File.basename(remotefile), &block) # :yield: line
      f = open(localfile, "w")
      begin
	retrlines("RETR " + remotefile) do |line|
	  f.puts(line)
	  yield(line) if block
	end
      ensure
	f.close
      end
    end

    #
    # Retrieves +remotefile+ in whatever mode the session is set (text or
    # binary).  See #gettextfile and #getbinaryfile.
    #
    def get(remotefile, localfile = File.basename(remotefile),
	    blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
      unless @binary
	gettextfile(remotefile, localfile, &block)
      else
	getbinaryfile(remotefile, localfile, blocksize, &block)
      end
    end
    
    #
    # Transfers +localfile+ to the server in binary mode, storing the result in
    # +remotefile+. If a block is supplied, calls it, passing in the transmitted
    # data in +blocksize+ chunks.
    #
    def putbinaryfile(localfile, remotefile = File.basename(localfile),
		      blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
      if @resume
        begin
          rest_offset = size(remotefile)
        rescue Net::FTPPermError
          rest_offset = nil
        end
      else
	rest_offset = nil
      end
      f = open(localfile)
      begin
	f.binmode
	storbinary("STOR " + remotefile, f, blocksize, rest_offset, &block)
      ensure
	f.close
      end
    end
    
    #
    # Transfers +localfile+ to the server in ASCII (text) mode, storing the result
    # in +remotefile+. If callback or an associated block is supplied, calls it,
    # passing in the transmitted data one line at a time.
    #
    def puttextfile(localfile, remotefile = File.basename(localfile), &block) # :yield: line
      f = open(localfile)
      begin
	storlines("STOR " + remotefile, f, &block)
      ensure
	f.close
      end
    end

    #
    # Transfers +localfile+ to the server in whatever mode the session is set
    # (text or binary).  See #puttextfile and #putbinaryfile.
    #
    def put(localfile, remotefile = File.basename(localfile),
	    blocksize = DEFAULT_BLOCKSIZE, &block)
      unless @binary
	puttextfile(localfile, remotefile, &block)
      else
	putbinaryfile(localfile, remotefile, blocksize, &block)
      end
    end

    #
    # Sends the ACCT command.  TODO: more info.
    #
    def acct(account)
      cmd = "ACCT " + account
      voidcmd(cmd)
    end
    
    #
    # Returns an array of filenames in the remote directory.
    #
    def nlst(dir = nil)
      cmd = "NLST"
      if dir
	cmd = cmd + " " + dir
      end
      files = []
      retrlines(cmd) do |line|
	files.push(line)
      end
      return files
    end
    
    #
    # Returns an array of file information in the directory (the output is like
    # `ls -l`).  If a block is given, it iterates through the listing.
    #
    def list(*args, &block) # :yield: line
      cmd = "LIST"
      args.each do |arg|
	cmd = cmd + " " + arg
      end
      if block
	retrlines(cmd, &block)
      else
	lines = []
	retrlines(cmd) do |line|
	  lines << line
	end
	return lines
      end
    end
    alias ls list
    alias dir list
    
    #
    # Renames a file on the server.
    #
    def rename(fromname, toname)
      resp = sendcmd("RNFR " + fromname)
      if resp[0] != ?3
	raise FTPReplyError, resp
      end
      voidcmd("RNTO " + toname)
    end
    
    #
    # Deletes a file on the server.
    #
    def delete(filename)
      resp = sendcmd("DELE " + filename)
      if resp[0, 3] == "250"
	return
      elsif resp[0] == ?5
	raise FTPPermError, resp
      else
	raise FTPReplyError, resp
      end
    end
    
    #
    # Changes the (remote) directory.
    #
    def chdir(dirname)
      if dirname == ".."
	begin
	  voidcmd("CDUP")
	  return
	rescue FTPPermError => e
	  if e.message[0, 3] != "500"
	    raise e
	  end
	end
      end
      cmd = "CWD " + dirname
      voidcmd(cmd)
    end
    
    #
    # Returns the size of the given (remote) filename.
    #
    def size(filename)
      voidcmd("TYPE I")
      resp = sendcmd("SIZE " + filename)
      if resp[0, 3] != "213" 
	raise FTPReplyError, resp
      end
      return resp[3..-1].strip.to_i
    end
    
    MDTM_REGEXP = /^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/  # :nodoc:
    
    #
    # Returns the last modification time of the (remote) file.  If +local+ is
    # +true+, it is returned as a local time, otherwise it's a UTC time.
    #
    def mtime(filename, local = false)
      str = mdtm(filename)
      ary = str.scan(MDTM_REGEXP)[0].collect {|i| i.to_i}
      return local ? Time.local(*ary) : Time.gm(*ary)
    end
    
    #
    # Creates a remote directory.
    #
    def mkdir(dirname)
      resp = sendcmd("MKD " + dirname)
      return parse257(resp)
    end
    
    #
    # Removes a remote directory.
    #
    def rmdir(dirname)
      voidcmd("RMD " + dirname)
    end
    
    #
    # Returns the current remote directory.
    #
    def pwd
      resp = sendcmd("PWD")
      return parse257(resp)
    end
    alias getdir pwd
    
    #
    # Returns system information.
    #
    def system
      resp = sendcmd("SYST")
      if resp[0, 3] != "215"
	raise FTPReplyError, resp
      end
      return resp[4 .. -1]
    end
    
    #
    # Aborts the previous command (ABOR command).
    #
    def abort
      line = "ABOR" + CRLF
      print "put: ABOR\n" if @debug_mode
      @sock.send(line, Socket::MSG_OOB)
      resp = getmultiline
      unless ["426", "226", "225"].include?(resp[0, 3])
	raise FTPProtoError, resp
      end
      return resp
    end
    
    #
    # Returns the status (STAT command).
    #
    def status
      line = "STAT" + CRLF
      print "put: STAT\n" if @debug_mode
      @sock.send(line, Socket::MSG_OOB)
      return getresp
    end
    
    #
    # Issues the MDTM command.  TODO: more info.
    #
    def mdtm(filename)
      resp = sendcmd("MDTM " + filename)
      if resp[0, 3] == "213"
	return resp[3 .. -1].strip
      end
    end
    
    #
    # Issues the HELP command.
    #
    def help(arg = nil)
      cmd = "HELP"
      if arg
	cmd = cmd + " " + arg
      end
      sendcmd(cmd)
    end
    
    #
    # Exits the FTP session.
    #
    def quit
      voidcmd("QUIT")
    end

    #
    # Issues a NOOP command.
    #
    def noop
      voidcmd("NOOP")
    end

    #
    # Issues a SITE command.
    #
    def site(arg)
      cmd = "SITE " + arg
      voidcmd(cmd)
    end
    
    #
    # Closes the connection.  Further operations are impossible until you open
    # a new connection with #connect.
    #
    def close
      @sock.close if @sock and not @sock.closed?
    end
    
    #
    # Returns +true+ iff the connection is closed.
    #
    def closed?
      @sock == nil or @sock.closed?
    end
    
    def parse227(resp)
      if resp[0, 3] != "227"
	raise FTPReplyError, resp
      end
      left = resp.index("(")
      right = resp.index(")")
      if left == nil or right == nil
	raise FTPProtoError, resp
      end
      numbers = resp[left + 1 .. right - 1].split(",")
      if numbers.length != 6
	raise FTPProtoError, resp
      end
      host = numbers[0, 4].join(".")
      port = (numbers[4].to_i << 8) + numbers[5].to_i
      return host, port
    end
    private :parse227
    
    def parse228(resp)
      if resp[0, 3] != "228"
	raise FTPReplyError, resp
      end
      left = resp.index("(")
      right = resp.index(")")
      if left == nil or right == nil
	raise FTPProtoError, resp
      end
      numbers = resp[left + 1 .. right - 1].split(",")
      if numbers[0] == "4"
	if numbers.length != 9 || numbers[1] != "4" || numbers[2 + 4] != "2"
	  raise FTPProtoError, resp
	end
	host = numbers[2, 4].join(".")
	port = (numbers[7].to_i << 8) + numbers[8].to_i
      elsif numbers[0] == "6"
	if numbers.length != 21 || numbers[1] != "16" || numbers[2 + 16] != "2"
	  raise FTPProtoError, resp
	end
	v6 = ["", "", "", "", "", "", "", ""]
	for i in 0 .. 7
	  v6[i] = sprintf("%02x%02x", numbers[(i * 2) + 2].to_i,
			  numbers[(i * 2) + 3].to_i)
	end
	host = v6[0, 8].join(":")
	port = (numbers[19].to_i << 8) + numbers[20].to_i
      end 
      return host, port
    end
    private :parse228
    
    def parse229(resp)
      if resp[0, 3] != "229"
	raise FTPReplyError, resp
      end
      left = resp.index("(")
      right = resp.index(")")
      if left == nil or right == nil
	raise FTPProtoError, resp
      end
      numbers = resp[left + 1 .. right - 1].split(resp[left + 1, 1])
      if numbers.length != 4
	raise FTPProtoError, resp
      end
      port = numbers[3].to_i
      host = (@sock.peeraddr())[3]
      return host, port
    end
    private :parse229
    
    def parse257(resp)
      if resp[0, 3] != "257"
	raise FTPReplyError, resp
      end
      if resp[3, 2] != ' "'
	return ""
      end
      dirname = ""
      i = 5
      n = resp.length
      while i < n
	c = resp[i, 1]
	i = i + 1
	if c == '"'
	  if i > n or resp[i, 1] != '"'
	    break
	  end
	  i = i + 1
	end
	dirname = dirname + c
      end
      return dirname
    end
    private :parse257
  end

end


# Documentation comments:
#  - sourced from pickaxe and nutshell, with improvements (hopefully)
#  - three methods should be private (search WRITEME)
#  - two methods need more information (search TODO)
PK     UZ\C~  ~    net/telnet.rbnu [        # = net/telnet.rb - Simple Telnet Client Library
# 
# Author:: Wakou Aoyama <wakou@ruby-lang.org>
# Documentation:: William Webber and Wakou Aoyama 
#
# This file holds the class Net::Telnet, which provides client-side
# telnet functionality.
#
# For documentation, see Net::Telnet.
#

require "socket"
require "delegate"
require "timeout"
require "English"
 
module Net

  #
  # == Net::Telnet
  #
  # Provides telnet client functionality.
  #
  # This class also has, through delegation, all the methods of a
  # socket object (by default, a +TCPSocket+, but can be set by the
  # +Proxy+ option to <tt>new()</tt>).  This provides methods such as
  # <tt>close()</tt> to end the session and <tt>sysread()</tt> to read
  # data directly from the host, instead of via the <tt>waitfor()</tt>
  # mechanism.  Note that if you do use <tt>sysread()</tt> directly
  # when in telnet mode, you should probably pass the output through
  # <tt>preprocess()</tt> to extract telnet command sequences.
  #
  # == Overview
  #
  # The telnet protocol allows a client to login remotely to a user
  # account on a server and execute commands via a shell.  The equivalent
  # is done by creating a Net::Telnet class with the +Host+ option
  # set to your host, calling #login() with your user and password,
  # issuing one or more #cmd() calls, and then calling #close()
  # to end the session.  The #waitfor(), #print(), #puts(), and
  # #write() methods, which #cmd() is implemented on top of, are
  # only needed if you are doing something more complicated.
  #
  # A Net::Telnet object can also be used to connect to non-telnet
  # services, such as SMTP or HTTP.  In this case, you normally
  # want to provide the +Port+ option to specify the port to
  # connect to, and set the +Telnetmode+ option to false to prevent
  # the client from attempting to interpret telnet command sequences.
  # Generally, #login() will not work with other protocols, and you
  # have to handle authentication yourself.
  #
  # For some protocols, it will be possible to specify the +Prompt+
  # option once when you create the Telnet object and use #cmd() calls; 
  # for others, you will have to specify the response sequence to
  # look for as the Match option to every #cmd() call, or call
  # #puts() and #waitfor() directly; for yet others, you will have 
  # to use #sysread() instead of #waitfor() and parse server 
  # responses yourself.
  #
  # It is worth noting that when you create a new Net::Telnet object,
  # you can supply a proxy IO channel via the Proxy option.  This
  # can be used to attach the Telnet object to other Telnet objects,
  # to already open sockets, or to any read-write IO object.  This
  # can be useful, for instance, for setting up a test fixture for
  # unit testing.
  # 
  # == Examples
  # 
  # === Log in and send a command, echoing all output to stdout
  # 
  #   localhost = Net::Telnet::new("Host" => "localhost",
  #                                "Timeout" => 10,
  #                                "Prompt" => /[$%#>] \z/n)
  #   localhost.login("username", "password") { |c| print c }
  #   localhost.cmd("command") { |c| print c }
  #   localhost.close
  # 
  # 
  # === Check a POP server to see if you have mail
  # 
  #   pop = Net::Telnet::new("Host" => "your_destination_host_here",
  #                          "Port" => 110,
  #                          "Telnetmode" => false,
  #                          "Prompt" => /^\+OK/n)
  #   pop.cmd("user " + "your_username_here") { |c| print c }
  #   pop.cmd("pass " + "your_password_here") { |c| print c }
  #   pop.cmd("list") { |c| print c }
  #
  # == References
  #
  # There are a large number of RFCs relevant to the Telnet protocol.
  # RFCs 854-861 define the base protocol.  For a complete listing
  # of relevant RFCs, see
  # http://www.omnifarious.org/~hopper/technical/telnet-rfc.html
  #
  class Telnet < SimpleDelegator

    # :stopdoc:
    IAC   = 255.chr # "\377" # "\xff" # interpret as command
    DONT  = 254.chr # "\376" # "\xfe" # you are not to use option 
    DO    = 253.chr # "\375" # "\xfd" # please, you use option 
    WONT  = 252.chr # "\374" # "\xfc" # I won't use option 
    WILL  = 251.chr # "\373" # "\xfb" # I will use option 
    SB    = 250.chr # "\372" # "\xfa" # interpret as subnegotiation 
    GA    = 249.chr # "\371" # "\xf9" # you may reverse the line 
    EL    = 248.chr # "\370" # "\xf8" # erase the current line 
    EC    = 247.chr # "\367" # "\xf7" # erase the current character 
    AYT   = 246.chr # "\366" # "\xf6" # are you there 
    AO    = 245.chr # "\365" # "\xf5" # abort output--but let prog finish 
    IP    = 244.chr # "\364" # "\xf4" # interrupt process--permanently 
    BREAK = 243.chr # "\363" # "\xf3" # break 
    DM    = 242.chr # "\362" # "\xf2" # data mark--for connect. cleaning 
    NOP   = 241.chr # "\361" # "\xf1" # nop 
    SE    = 240.chr # "\360" # "\xf0" # end sub negotiation 
    EOR   = 239.chr # "\357" # "\xef" # end of record (transparent mode) 
    ABORT = 238.chr # "\356" # "\xee" # Abort process 
    SUSP  = 237.chr # "\355" # "\xed" # Suspend process 
    EOF   = 236.chr # "\354" # "\xec" # End of file 
    SYNCH = 242.chr # "\362" # "\xf2" # for telfunc calls 

    OPT_BINARY         =   0.chr # "\000" # "\x00" # Binary Transmission 
    OPT_ECHO           =   1.chr # "\001" # "\x01" # Echo 
    OPT_RCP            =   2.chr # "\002" # "\x02" # Reconnection 
    OPT_SGA            =   3.chr # "\003" # "\x03" # Suppress Go Ahead 
    OPT_NAMS           =   4.chr # "\004" # "\x04" # Approx Message Size Negotiation 
    OPT_STATUS         =   5.chr # "\005" # "\x05" # Status 
    OPT_TM             =   6.chr # "\006" # "\x06" # Timing Mark 
    OPT_RCTE           =   7.chr # "\a"   # "\x07" # Remote Controlled Trans and Echo 
    OPT_NAOL           =   8.chr # "\010" # "\x08" # Output Line Width 
    OPT_NAOP           =   9.chr # "\t"   # "\x09" # Output Page Size 
    OPT_NAOCRD         =  10.chr # "\n"   # "\x0a" # Output Carriage-Return Disposition 
    OPT_NAOHTS         =  11.chr # "\v"   # "\x0b" # Output Horizontal Tab Stops 
    OPT_NAOHTD         =  12.chr # "\f"   # "\x0c" # Output Horizontal Tab Disposition 
    OPT_NAOFFD         =  13.chr # "\r"   # "\x0d" # Output Formfeed Disposition 
    OPT_NAOVTS         =  14.chr # "\016" # "\x0e" # Output Vertical Tabstops 
    OPT_NAOVTD         =  15.chr # "\017" # "\x0f" # Output Vertical Tab Disposition 
    OPT_NAOLFD         =  16.chr # "\020" # "\x10" # Output Linefeed Disposition 
    OPT_XASCII         =  17.chr # "\021" # "\x11" # Extended ASCII 
    OPT_LOGOUT         =  18.chr # "\022" # "\x12" # Logout 
    OPT_BM             =  19.chr # "\023" # "\x13" # Byte Macro 
    OPT_DET            =  20.chr # "\024" # "\x14" # Data Entry Terminal 
    OPT_SUPDUP         =  21.chr # "\025" # "\x15" # SUPDUP 
    OPT_SUPDUPOUTPUT   =  22.chr # "\026" # "\x16" # SUPDUP Output 
    OPT_SNDLOC         =  23.chr # "\027" # "\x17" # Send Location 
    OPT_TTYPE          =  24.chr # "\030" # "\x18" # Terminal Type 
    OPT_EOR            =  25.chr # "\031" # "\x19" # End of Record 
    OPT_TUID           =  26.chr # "\032" # "\x1a" # TACACS User Identification 
    OPT_OUTMRK         =  27.chr # "\e"   # "\x1b" # Output Marking 
    OPT_TTYLOC         =  28.chr # "\034" # "\x1c" # Terminal Location Number 
    OPT_3270REGIME     =  29.chr # "\035" # "\x1d" # Telnet 3270 Regime 
    OPT_X3PAD          =  30.chr # "\036" # "\x1e" # X.3 PAD 
    OPT_NAWS           =  31.chr # "\037" # "\x1f" # Negotiate About Window Size 
    OPT_TSPEED         =  32.chr # " "    # "\x20" # Terminal Speed 
    OPT_LFLOW          =  33.chr # "!"    # "\x21" # Remote Flow Control 
    OPT_LINEMODE       =  34.chr # "\""   # "\x22" # Linemode 
    OPT_XDISPLOC       =  35.chr # "#"    # "\x23" # X Display Location 
    OPT_OLD_ENVIRON    =  36.chr # "$"    # "\x24" # Environment Option 
    OPT_AUTHENTICATION =  37.chr # "%"    # "\x25" # Authentication Option 
    OPT_ENCRYPT        =  38.chr # "&"    # "\x26" # Encryption Option 
    OPT_NEW_ENVIRON    =  39.chr # "'"    # "\x27" # New Environment Option 
    OPT_EXOPL          = 255.chr # "\377" # "\xff" # Extended-Options-List 

    NULL = "\000" 
    CR   = "\015"   
    LF   = "\012" 
    EOL  = CR + LF 
    REVISION = '$Id: telnet.rb 16458 2008-05-18 15:02:36Z knu $'
    # :startdoc:

    #
    # Creates a new Net::Telnet object.
    #
    # Attempts to connect to the host (unless the Proxy option is
    # provided: see below).  If a block is provided, it is yielded
    # status messages on the attempt to connect to the server, of
    # the form:
    # 
    #   Trying localhost...
    #   Connected to localhost.
    #
    # +options+ is a hash of options.  The following example lists
    # all options and their default values.
    # 
    #   host = Net::Telnet::new(
    #            "Host"       => "localhost",  # default: "localhost"
    #            "Port"       => 23,           # default: 23
    #            "Binmode"    => false,        # default: false
    #            "Output_log" => "output_log", # default: nil (no output)
    #            "Dump_log"   => "dump_log",   # default: nil (no output)
    #            "Prompt"     => /[$%#>] \z/n, # default: /[$%#>] \z/n
    #            "Telnetmode" => true,         # default: true
    #            "Timeout"    => 10,           # default: 10
    #              # if ignore timeout then set "Timeout" to false.
    #            "Waittime"   => 0,            # default: 0
    #            "Proxy"      => proxy         # default: nil
    #                            # proxy is Net::Telnet or IO object
    #          )
    #
    # The options have the following meanings:
    #
    # Host:: the hostname or IP address of the host to connect to, as a String. 
    #        Defaults to "localhost".
    #
    # Port:: the port to connect to.  Defaults to 23.
    #
    # Binmode:: if false (the default), newline substitution is performed.  
    #           Outgoing LF is
    #           converted to CRLF, and incoming CRLF is converted to LF.  If
    #           true, this substitution is not performed.  This value can
    #           also be set with the #binmode() method.  The 
    #           outgoing conversion only applies to the #puts() and #print()
    #           methods, not the #write() method.  The precise nature of
    #           the newline conversion is also affected by the telnet options
    #           SGA and BIN.
    #
    # Output_log:: the name of the file to write connection status messages
    #              and all received traffic to.  In the case of a proper
    #              Telnet session, this will include the client input as
    #              echoed by the host; otherwise, it only includes server
    #              responses.  Output is appended verbatim to this file.  
    #              By default, no output log is kept.
    #
    # Dump_log:: as for Output_log, except that output is written in hexdump
    #            format (16 bytes per line as hex pairs, followed by their
    #            printable equivalent), with connection status messages
    #            preceded by '#', sent traffic preceded by '>', and 
    #            received traffic preceded by '<'.  By default, not dump log
    #            is kept.
    #
    # Prompt:: a regular expression matching the host's command-line prompt
    #          sequence.  This is needed by the Telnet class to determine
    #          when the output from a command has finished and the host is
    #          ready to receive a new command.  By default, this regular
    #          expression is /[$%#>] \z/n.
    #
    # Telnetmode:: a boolean value, true by default.  In telnet mode, 
    #              traffic received from the host is parsed for special
    #              command sequences, and these sequences are escaped
    #              in outgoing traffic sent using #puts() or #print()
    #              (but not #write()).  If you are using the Net::Telnet
    #              object to connect to a non-telnet service (such as
    #              SMTP or POP), this should be set to "false" to prevent
    #              undesired data corruption.  This value can also be set
    #              by the #telnetmode() method.
    #
    # Timeout:: the number of seconds to wait before timing out both the
    #           initial attempt to connect to host (in this constructor),
    #           and all attempts to read data from the host (in #waitfor(),
    #           #cmd(), and #login()).  Exceeding this timeout causes a
    #           TimeoutError to be raised.  The default value is 10 seconds.
    #           You can disable the timeout by setting this value to false.
    #           In this case, the connect attempt will eventually timeout
    #           on the underlying connect(2) socket call with an
    #           Errno::ETIMEDOUT error (but generally only after a few
    #           minutes), but other attempts to read data from the host
    #           will hand indefinitely if no data is forthcoming.
    #
    # Waittime:: the amount of time to wait after seeing what looks like a 
    #            prompt (that is, received data that matches the Prompt
    #            option regular expression) to see if more data arrives.
    #            If more data does arrive in this time, Net::Telnet assumes
    #            that what it saw was not really a prompt.  This is to try to 
    #            avoid false matches, but it can also lead to missing real
    #            prompts (if, for instance, a background process writes to
    #            the terminal soon after the prompt is displayed).  By
    #            default, set to 0, meaning not to wait for more data.
    #
    # Proxy:: a proxy object to used instead of opening a direct connection
    #         to the host.  Must be either another Net::Telnet object or
    #         an IO object.  If it is another Net::Telnet object, this 
    #         instance will use that one's socket for communication.  If an
    #         IO object, it is used directly for communication.  Any other
    #         kind of object will cause an error to be raised.
    #
    def initialize(options) # :yield: mesg 
      @options = options
      @options["Host"]       = "localhost"   unless @options.has_key?("Host")
      @options["Port"]       = 23            unless @options.has_key?("Port")
      @options["Prompt"]     = /[$%#>] \z/n  unless @options.has_key?("Prompt")
      @options["Timeout"]    = 10            unless @options.has_key?("Timeout")
      @options["Waittime"]   = 0             unless @options.has_key?("Waittime")
      unless @options.has_key?("Binmode")
        @options["Binmode"]    = false         
      else
        unless (true == @options["Binmode"] or false == @options["Binmode"])
          raise ArgumentError, "Binmode option must be true or false"
        end
      end

      unless @options.has_key?("Telnetmode")
        @options["Telnetmode"] = true          
      else
        unless (true == @options["Telnetmode"] or false == @options["Telnetmode"])
          raise ArgumentError, "Telnetmode option must be true or false"
        end
      end

      @telnet_option = { "SGA" => false, "BINARY" => false }

      if @options.has_key?("Output_log")
        @log = File.open(@options["Output_log"], 'a+')
        @log.sync = true
        @log.binmode
      end

      if @options.has_key?("Dump_log")
        @dumplog = File.open(@options["Dump_log"], 'a+')
        @dumplog.sync = true
        @dumplog.binmode
        def @dumplog.log_dump(dir, x)  # :nodoc:
          len = x.length
          addr = 0
          offset = 0
          while 0 < len
            if len < 16
              line = x[offset, len]
            else
              line = x[offset, 16]
            end
            hexvals = line.unpack('H*')[0]
            hexvals += ' ' * (32 - hexvals.length)
            hexvals = format("%s %s %s %s  " * 4, *hexvals.unpack('a2' * 16))
            line = line.gsub(/[\000-\037\177-\377]/n, '.')
            printf "%s 0x%5.5x: %s%s\n", dir, addr, hexvals, line
            addr += 16
            offset += 16
            len -= 16
          end
          print "\n"
        end
      end

      if @options.has_key?("Proxy")
        if @options["Proxy"].kind_of?(Net::Telnet)
          @sock = @options["Proxy"].sock
        elsif @options["Proxy"].kind_of?(IO)
          @sock = @options["Proxy"]
        else
          raise "Error: Proxy must be an instance of Net::Telnet or IO."
        end
      else
        message = "Trying " + @options["Host"] + "...\n"
        yield(message) if block_given?
        @log.write(message) if @options.has_key?("Output_log")
        @dumplog.log_dump('#', message) if @options.has_key?("Dump_log")

        begin
          if @options["Timeout"] == false
            @sock = TCPSocket.open(@options["Host"], @options["Port"])
          else
            timeout(@options["Timeout"]) do
              @sock = TCPSocket.open(@options["Host"], @options["Port"])
            end
          end
        rescue TimeoutError
          raise TimeoutError, "timed out while opening a connection to the host"
        rescue
          @log.write($ERROR_INFO.to_s + "\n") if @options.has_key?("Output_log")
          @dumplog.log_dump('#', $ERROR_INFO.to_s + "\n") if @options.has_key?("Dump_log")
          raise
        end
        @sock.sync = true
        @sock.binmode

        message = "Connected to " + @options["Host"] + ".\n"
        yield(message) if block_given?
        @log.write(message) if @options.has_key?("Output_log")
        @dumplog.log_dump('#', message) if @options.has_key?("Dump_log")
      end

      super(@sock)
    end # initialize

    # The socket the Telnet object is using.  Note that this object becomes
    # a delegate of the Telnet object, so normally you invoke its methods
    # directly on the Telnet object.
    attr :sock 

    # Set telnet command interpretation on (+mode+ == true) or off
    # (+mode+ == false), or return the current value (+mode+ not
    # provided).  It should be on for true telnet sessions, off if
    # using Net::Telnet to connect to a non-telnet service such
    # as SMTP.
    def telnetmode(mode = nil)
      case mode
      when nil
        @options["Telnetmode"]
      when true, false
        @options["Telnetmode"] = mode
      else
        raise ArgumentError, "argument must be true or false, or missing"
      end
    end

    # Turn telnet command interpretation on (true) or off (false).  It
    # should be on for true telnet sessions, off if using Net::Telnet
    # to connect to a non-telnet service such as SMTP.
    def telnetmode=(mode)
      if (true == mode or false == mode)
        @options["Telnetmode"] = mode
      else
        raise ArgumentError, "argument must be true or false"
      end
    end

    # Turn newline conversion on (+mode+ == false) or off (+mode+ == true),
    # or return the current value (+mode+ is not specified).
    def binmode(mode = nil)
      case mode
      when nil
        @options["Binmode"] 
      when true, false
        @options["Binmode"] = mode
      else
        raise ArgumentError, "argument must be true or false"
      end
    end

    # Turn newline conversion on (false) or off (true).
    def binmode=(mode)
      if (true == mode or false == mode)
        @options["Binmode"] = mode
      else
        raise ArgumentError, "argument must be true or false"
      end
    end

    # Preprocess received data from the host.
    #
    # Performs newline conversion and detects telnet command sequences.
    # Called automatically by #waitfor().  You should only use this 
    # method yourself if you have read input directly using sysread()
    # or similar, and even then only if in telnet mode.
    def preprocess(string)
      # combine CR+NULL into CR
      string = string.gsub(/#{CR}#{NULL}/no, CR) if @options["Telnetmode"]

      # combine EOL into "\n"
      string = string.gsub(/#{EOL}/no, "\n") unless @options["Binmode"]

      string.gsub(/#{IAC}(
                   [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]|
                   [#{DO}#{DONT}#{WILL}#{WONT}]
                     [#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]|
                   #{SB}[^#{IAC}]*#{IAC}#{SE}
                 )/xno) do
        if    IAC == $1  # handle escaped IAC characters
          IAC
        elsif AYT == $1  # respond to "IAC AYT" (are you there)
          self.write("nobody here but us pigeons" + EOL)
          ''
        elsif DO[0] == $1[0]  # respond to "IAC DO x"
          if OPT_BINARY[0] == $1[1]
            @telnet_option["BINARY"] = true
            self.write(IAC + WILL + OPT_BINARY)
          else
            self.write(IAC + WONT + $1[1..1])
          end
          ''
        elsif DONT[0] == $1[0]  # respond to "IAC DON'T x" with "IAC WON'T x"
          self.write(IAC + WONT + $1[1..1])
          ''
        elsif WILL[0] == $1[0]  # respond to "IAC WILL x"
          if    OPT_BINARY[0] == $1[1]
            self.write(IAC + DO + OPT_BINARY)
          elsif OPT_ECHO[0] == $1[1]
            self.write(IAC + DO + OPT_ECHO)
          elsif OPT_SGA[0]  == $1[1]
            @telnet_option["SGA"] = true
            self.write(IAC + DO + OPT_SGA)
          else
            self.write(IAC + DONT + $1[1..1])
          end
          ''
        elsif WONT[0] == $1[0]  # respond to "IAC WON'T x"
          if    OPT_ECHO[0] == $1[1]
            self.write(IAC + DONT + OPT_ECHO)
          elsif OPT_SGA[0]  == $1[1]
            @telnet_option["SGA"] = false
            self.write(IAC + DONT + OPT_SGA)
          else
            self.write(IAC + DONT + $1[1..1])
          end
          ''
        else
          ''
        end
      end
    end # preprocess

    # Read data from the host until a certain sequence is matched.
    #
    # If a block is given, the received data will be yielded as it
    # is read in (not necessarily all in one go), or nil if EOF 
    # occurs before any data is received.  Whether a block is given
    # or not, all data read will be returned in a single string, or again 
    # nil if EOF occurs before any data is received.  Note that
    # received data includes the matched sequence we were looking for.
    #
    # +options+ can be either a regular expression or a hash of options.
    # If a regular expression, this specifies the data to wait for.
    # If a hash, this can specify the following options:
    #
    # Match:: a regular expression, specifying the data to wait for.
    # Prompt:: as for Match; used only if Match is not specified.
    # String:: as for Match, except a string that will be converted
    #          into a regular expression.  Used only if Match and
    #          Prompt are not specified.
    # Timeout:: the number of seconds to wait for data from the host
    #           before raising a TimeoutError.  If set to false, 
    #           no timeout will occur.  If not specified, the
    #           Timeout option value specified when this instance
    #           was created will be used, or, failing that, the
    #           default value of 10 seconds.
    # Waittime:: the number of seconds to wait after matching against
    #            the input data to see if more data arrives.  If more
    #            data arrives within this time, we will judge ourselves
    #            not to have matched successfully, and will continue
    #            trying to match.  If not specified, the Waittime option
    #            value specified when this instance was created will be
    #            used, or, failing that, the default value of 0 seconds,
    #            which means not to wait for more input.
    # FailEOF:: if true, when the remote end closes the connection then an
    #           EOFError will be raised. Otherwise, defaults to the old
    #           behaviour that the function will return whatever data
    #           has been received already, or nil if nothing was received.
    #           
    def waitfor(options) # :yield: recvdata
      time_out = @options["Timeout"]
      waittime = @options["Waittime"]
      fail_eof = @options["FailEOF"]

      if options.kind_of?(Hash)
        prompt   = if options.has_key?("Match")
                     options["Match"]
                   elsif options.has_key?("Prompt")
                     options["Prompt"]
                   elsif options.has_key?("String")
                     Regexp.new( Regexp.quote(options["String"]) )
                   end
        time_out = options["Timeout"]  if options.has_key?("Timeout")
        waittime = options["Waittime"] if options.has_key?("Waittime")
        fail_eof = options["FailEOF"]  if options.has_key?("FailEOF")
      else
        prompt = options
      end

      if time_out == false
        time_out = nil
      end

      line = ''
      buf = ''
      rest = ''
      until(prompt === line and not IO::select([@sock], nil, nil, waittime))
        unless IO::select([@sock], nil, nil, time_out)
          raise TimeoutError, "timed out while waiting for more data"
        end
        begin
          c = @sock.readpartial(1024 * 1024)
          @dumplog.log_dump('<', c) if @options.has_key?("Dump_log")
          if @options["Telnetmode"]
            c = rest + c
            if Integer(c.rindex(/#{IAC}#{SE}/no)) <
               Integer(c.rindex(/#{IAC}#{SB}/no))
              buf = preprocess(c[0 ... c.rindex(/#{IAC}#{SB}/no)])
              rest = c[c.rindex(/#{IAC}#{SB}/no) .. -1]
            elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no) ||
                       c.rindex(/\r\z/no)
              buf = preprocess(c[0 ... pt])
              rest = c[pt .. -1]
            else
              buf = preprocess(c)
              rest = ''
            end
         else
           # Not Telnetmode.
           #
           # We cannot use preprocess() on this data, because that
           # method makes some Telnetmode-specific assumptions.
           buf = rest + c
           rest = ''
           unless @options["Binmode"]
             if pt = buf.rindex(/\r\z/no)
               buf = buf[0 ... pt]
               rest = buf[pt .. -1]
             end
             buf.gsub!(/#{EOL}/no, "\n")
           end
          end
          @log.print(buf) if @options.has_key?("Output_log")
          line += buf
          yield buf if block_given?
        rescue EOFError # End of file reached
          raise if fail_eof
          if line == ''
            line = nil
            yield nil if block_given?
          end
          break
        end
      end
      line
    end

    # Write +string+ to the host.
    #
    # Does not perform any conversions on +string+.  Will log +string+ to the
    # dumplog, if the Dump_log option is set.
    def write(string)
      length = string.length
      while 0 < length
        IO::select(nil, [@sock])
        @dumplog.log_dump('>', string[-length..-1]) if @options.has_key?("Dump_log")
        length -= @sock.syswrite(string[-length..-1])
      end
    end

    # Sends a string to the host.
    #
    # This does _not_ automatically append a newline to the string.  Embedded
    # newlines may be converted and telnet command sequences escaped 
    # depending upon the values of telnetmode, binmode, and telnet options
    # set by the host.
    def print(string)
      string = string.gsub(/#{IAC}/no, IAC + IAC) if @options["Telnetmode"]

      if @options["Binmode"]
        self.write(string)
      else
        if @telnet_option["BINARY"] and @telnet_option["SGA"]
          # IAC WILL SGA IAC DO BIN send EOL --> CR
          self.write(string.gsub(/\n/n, CR))
        elsif @telnet_option["SGA"]
          # IAC WILL SGA send EOL --> CR+NULL
          self.write(string.gsub(/\n/n, CR + NULL))
        else
          # NONE send EOL --> CR+LF
          self.write(string.gsub(/\n/n, EOL))
        end
      end
    end

    # Sends a string to the host.
    #
    # Same as #print(), but appends a newline to the string.
    def puts(string)
      self.print(string + "\n")
    end

    # Send a command to the host.
    #
    # More exactly, sends a string to the host, and reads in all received
    # data until is sees the prompt or other matched sequence.
    #
    # If a block is given, the received data will be yielded to it as
    # it is read in.  Whether a block is given or not, the received data 
    # will be return as a string.  Note that the received data includes
    # the prompt and in most cases the host's echo of our command.
    #
    # +options+ is either a String, specified the string or command to
    # send to the host; or it is a hash of options.  If a hash, the
    # following options can be specified:
    #
    # String:: the command or other string to send to the host.
    # Match:: a regular expression, the sequence to look for in
    #         the received data before returning.  If not specified,
    #         the Prompt option value specified when this instance
    #         was created will be used, or, failing that, the default
    #         prompt of /[$%#>] \z/n.
    # Timeout:: the seconds to wait for data from the host before raising
    #           a Timeout error.  If not specified, the Timeout option
    #           value specified when this instance was created will be
    #           used, or, failing that, the default value of 10 seconds.
    #
    # The command or other string will have the newline sequence appended
    # to it.
    def cmd(options) # :yield: recvdata
      match    = @options["Prompt"]
      time_out = @options["Timeout"]

      if options.kind_of?(Hash)
        string   = options["String"]
        match    = options["Match"]   if options.has_key?("Match")
        time_out = options["Timeout"] if options.has_key?("Timeout")
      else
        string = options
      end

      self.puts(string)
      if block_given?
        waitfor({"Prompt" => match, "Timeout" => time_out}){|c| yield c }
      else
        waitfor({"Prompt" => match, "Timeout" => time_out})
      end
    end

    # Login to the host with a given username and password.
    #
    # The username and password can either be provided as two string
    # arguments in that order, or as a hash with keys "Name" and
    # "Password".    
    #
    # This method looks for the strings "login" and "Password" from the
    # host to determine when to send the username and password.  If the
    # login sequence does not follow this pattern (for instance, you
    # are connecting to a service other than telnet), you will need
    # to handle login yourself.
    #
    # The password can be omitted, either by only
    # provided one String argument, which will be used as the username,
    # or by providing a has that has no "Password" key.  In this case,
    # the method will not look for the "Password:" prompt; if it is
    # sent, it will have to be dealt with by later calls.
    #
    # The method returns all data received during the login process from
    # the host, including the echoed username but not the password (which
    # the host should not echo).  If a block is passed in, this received
    # data is also yielded to the block as it is received.
    def login(options, password = nil) # :yield: recvdata
      login_prompt = /[Ll]ogin[: ]*\z/n
      password_prompt = /[Pp]ass(?:word|phrase)[: ]*\z/n
      if options.kind_of?(Hash)
        username = options["Name"]
        password = options["Password"]
	login_prompt = options["LoginPrompt"] if options["LoginPrompt"]
	password_prompt = options["PasswordPrompt"] if options["PasswordPrompt"]
      else
        username = options
      end

      if block_given?
        line = waitfor(login_prompt){|c| yield c }
        if password
          line += cmd({"String" => username,
                       "Match" => password_prompt}){|c| yield c }
          line += cmd(password){|c| yield c }
        else
          line += cmd(username){|c| yield c }
        end
      else
        line = waitfor(login_prompt)
        if password
          line += cmd({"String" => username,
                       "Match" => password_prompt})
          line += cmd(password)
        else
          line += cmd(username)
        end
      end
      line
    end

  end  # class Telnet
end  # module Net

PK     UZ\\·      irb/ruby-token.rbnu [        #
#   irb/ruby-token.rb - ruby tokens 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
module RubyToken
  EXPR_BEG = :EXPR_BEG
  EXPR_MID = :EXPR_MID
  EXPR_END = :EXPR_END
  EXPR_ARG = :EXPR_ARG
  EXPR_FNAME = :EXPR_FNAME
  EXPR_DOT = :EXPR_DOT
  EXPR_CLASS = :EXPR_CLASS

  # for ruby 1.4X
  if !defined?(Symbol)
    Symbol = Integer
  end
  
  class Token
    def initialize(seek, line_no, char_no)
      @seek = seek
      @line_no = line_no
      @char_no = char_no
    end
    attr :seek
    attr :line_no
    attr :char_no
  end

  class TkNode < Token
    def initialize(seek, line_no, char_no)
      super
    end
    attr :node
  end

  class TkId < Token
    def initialize(seek, line_no, char_no, name)
      super(seek, line_no, char_no)
      @name = name
    end
    attr :name
  end

  class TkVal < Token
    def initialize(seek, line_no, char_no, value = nil)
      super(seek, line_no, char_no)
      @value = value
    end
    attr :value
  end

  class TkOp < Token
    attr :name, true
  end

  class TkOPASGN < TkOp
    def initialize(seek, line_no, char_no, op)
      super(seek, line_no, char_no)
      op = TkReading2Token[op][0] unless op.kind_of?(Symbol)
      @op = op
    end
    attr :op
  end

  class TkUnknownChar < Token
    def initialize(seek, line_no, char_no, id)
      super(seek, line_no, char_no)
      @name = name
    end
    attr :name
  end

  class TkError < Token
  end

  def Token(token, value = nil)
    case token
    when String
      if (tk = TkReading2Token[token]).nil?
	IRB.fail TkReading2TokenNoKey, token
      end
      tk = Token(tk[0], value) 
      if tk.kind_of?(TkOp)
	tk.name = token
      end
      return tk
    when Symbol
      if (tk = TkSymbol2Token[token]).nil?
	IRB.fail TkSymbol2TokenNoKey, token
      end
      return Token(tk[0], value) 
    else 
      if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty?
	token.new(@prev_seek, @prev_line_no, @prev_char_no)
      else
	token.new(@prev_seek, @prev_line_no, @prev_char_no, value)
      end
    end
  end

  TokenDefinitions = [
    [:TkCLASS,      TkId,  "class",  EXPR_CLASS],
    [:TkMODULE,     TkId,  "module", EXPR_BEG],
    [:TkDEF,	    TkId,  "def",    EXPR_FNAME],
    [:TkUNDEF,      TkId,  "undef",  EXPR_FNAME],
    [:TkBEGIN,      TkId,  "begin",  EXPR_BEG],
    [:TkRESCUE,     TkId,  "rescue", EXPR_MID],
    [:TkENSURE,     TkId,  "ensure", EXPR_BEG],
    [:TkEND,	    TkId,  "end",    EXPR_END],
    [:TkIF,         TkId,  "if",     EXPR_BEG, :TkIF_MOD],
    [:TkUNLESS,     TkId,  "unless", EXPR_BEG, :TkUNLESS_MOD],
    [:TkTHEN,	    TkId,  "then",   EXPR_BEG],
    [:TkELSIF,      TkId,  "elsif",  EXPR_BEG],
    [:TkELSE,	    TkId,  "else",   EXPR_BEG],
    [:TkCASE,	    TkId,  "case",   EXPR_BEG],
    [:TkWHEN,	    TkId,  "when",   EXPR_BEG],
    [:TkWHILE,      TkId,  "while",  EXPR_BEG, :TkWHILE_MOD],
    [:TkUNTIL,      TkId,  "until",  EXPR_BEG, :TkUNTIL_MOD],
    [:TkFOR,	    TkId,  "for",    EXPR_BEG],
    [:TkBREAK,      TkId,  "break",  EXPR_END],
    [:TkNEXT,	    TkId,  "next",   EXPR_END],
    [:TkREDO,	    TkId,  "redo",   EXPR_END],
    [:TkRETRY,      TkId,  "retry",  EXPR_END],
    [:TkIN,	    TkId,  "in",     EXPR_BEG],
    [:TkDO,	    TkId,  "do",     EXPR_BEG],
    [:TkRETURN,     TkId,  "return", EXPR_MID],
    [:TkYIELD,      TkId,  "yield",  EXPR_END],
    [:TkSUPER,      TkId,  "super",  EXPR_END],
    [:TkSELF,	    TkId,  "self",   EXPR_END],
    [:TkNIL, 	    TkId,  "nil",    EXPR_END],
    [:TkTRUE,	    TkId,  "true",   EXPR_END],
    [:TkFALSE,      TkId,  "false",  EXPR_END],
    [:TkAND,	    TkId,  "and",    EXPR_BEG],
    [:TkOR, 	    TkId,  "or",     EXPR_BEG],
    [:TkNOT,	    TkId,  "not",    EXPR_BEG],
    [:TkIF_MOD,     TkId],
    [:TkUNLESS_MOD, TkId],
    [:TkWHILE_MOD,  TkId],
    [:TkUNTIL_MOD,  TkId],
    [:TkALIAS,      TkId,  "alias",    EXPR_FNAME],
    [:TkDEFINED,    TkId,  "defined?", EXPR_END],
    [:TklBEGIN,     TkId,  "BEGIN",    EXPR_END],
    [:TklEND,	    TkId,  "END",      EXPR_END],
    [:Tk__LINE__,   TkId,  "__LINE__", EXPR_END],
    [:Tk__FILE__,   TkId,  "__FILE__", EXPR_END],

    [:TkIDENTIFIER, TkId],
    [:TkFID,	    TkId],
    [:TkGVAR,	    TkId],
    [:TkCVAR,	    TkId],
    [:TkIVAR,	    TkId],
    [:TkCONSTANT,   TkId],

    [:TkINTEGER,    TkVal],
    [:TkFLOAT,      TkVal],
    [:TkSTRING,     TkVal],
    [:TkXSTRING,    TkVal],
    [:TkREGEXP,     TkVal],
    [:TkSYMBOL,     TkVal],

    [:TkDSTRING,    TkNode],
    [:TkDXSTRING,   TkNode],
    [:TkDREGEXP,    TkNode],
    [:TkNTH_REF,    TkNode],
    [:TkBACK_REF,   TkNode],

    [:TkUPLUS,      TkOp,   "+@"],
    [:TkUMINUS,     TkOp,   "-@"],
    [:TkPOW,	    TkOp,   "**"],
    [:TkCMP,	    TkOp,   "<=>"],
    [:TkEQ,	    TkOp,   "=="],
    [:TkEQQ,	    TkOp,   "==="],
    [:TkNEQ,	    TkOp,   "!="],
    [:TkGEQ,	    TkOp,   ">="],
    [:TkLEQ,	    TkOp,   "<="],
    [:TkANDOP,      TkOp,   "&&"],
    [:TkOROP,	    TkOp,   "||"],
    [:TkMATCH,      TkOp,   "=~"],
    [:TkNMATCH,     TkOp,   "!~"],
    [:TkDOT2,	    TkOp,   ".."],
    [:TkDOT3,	    TkOp,   "..."],
    [:TkAREF,	    TkOp,   "[]"],
    [:TkASET,	    TkOp,   "[]="],
    [:TkLSHFT,      TkOp,   "<<"],
    [:TkRSHFT,      TkOp,   ">>"],
    [:TkCOLON2,     TkOp],
    [:TkCOLON3,     TkOp],
#   [:OPASGN,	    TkOp],               # +=, -=  etc. #
    [:TkASSOC,      TkOp,   "=>"],
    [:TkQUESTION,   TkOp,   "?"],	 #?
    [:TkCOLON,      TkOp,   ":"],        #:
    
    [:TkfLPAREN],         # func( #
    [:TkfLBRACK],         # func[ #
    [:TkfLBRACE],         # func{ #
    [:TkSTAR],            # *arg
    [:TkAMPER],           # &arg #
    [:TkSYMBEG],          # :SYMBOL

    [:TkGT,	    TkOp,   ">"],
    [:TkLT,	    TkOp,   "<"],
    [:TkPLUS,	    TkOp,   "+"],
    [:TkMINUS,      TkOp,   "-"],
    [:TkMULT,	    TkOp,   "*"],
    [:TkDIV,	    TkOp,   "/"],
    [:TkMOD,	    TkOp,   "%"],
    [:TkBITOR,      TkOp,   "|"],
    [:TkBITXOR,     TkOp,   "^"],
    [:TkBITAND,     TkOp,   "&"],
    [:TkBITNOT,     TkOp,   "~"],
    [:TkNOTOP,      TkOp,   "!"],

    [:TkBACKQUOTE,  TkOp,   "`"],

    [:TkASSIGN,     Token,  "="],
    [:TkDOT,	    Token,  "."],
    [:TkLPAREN,     Token,  "("],  #(exp)
    [:TkLBRACK,     Token,  "["],  #[arry]
    [:TkLBRACE,     Token,  "{"],  #{hash}
    [:TkRPAREN,     Token,  ")"],
    [:TkRBRACK,     Token,  "]"],
    [:TkRBRACE,     Token,  "}"],
    [:TkCOMMA,      Token,  ","],
    [:TkSEMICOLON,  Token,  ";"],

    [:TkCOMMENT],
    [:TkRD_COMMENT],
    [:TkSPACE],
    [:TkNL],
    [:TkEND_OF_SCRIPT],

    [:TkBACKSLASH,  TkUnknownChar,  "\\"],
    [:TkAT,	    TkUnknownChar,  "@"],
    [:TkDOLLAR,     TkUnknownChar,  "$"],
  ]

  # {reading => token_class}
  # {reading => [token_class, *opt]}
  TkReading2Token = {}
  TkSymbol2Token = {}

  def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts)
    token_n = token_n.id2name if token_n.kind_of?(Symbol)
    if RubyToken.const_defined?(token_n)
      IRB.fail AlreadyDefinedToken, token_n
    end
    token_c = eval("class #{token_n} < #{super_token}; end; #{token_n}")
    
    if reading
      if TkReading2Token[reading]
	IRB.fail TkReading2TokenDuplicateError, token_n, reading
      end
      if opts.empty?
	TkReading2Token[reading] = [token_c]
      else
	TkReading2Token[reading] = [token_c].concat(opts)
      end
    end
    TkSymbol2Token[token_n.intern] = token_c
  end

  for defs in TokenDefinitions
    def_token(*defs)
  end
end
PK     VZ\SW  W    irb/init.rbnu [        #
#   irb/init.rb - irb initialize module
#   	$Release Version: 0.9.5$
#   	$Revision: 24483 $
#   	$Date: 2009-08-09 17:44:15 +0900 (Sun, 09 Aug 2009) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

module IRB

  # initialize config
  def IRB.setup(ap_path)
    IRB.init_config(ap_path)
    IRB.init_error
    IRB.parse_opts
    IRB.run_config
    IRB.load_modules

    unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]]
      IRB.fail(UndefinedPromptMode, @CONF[:PROMPT_MODE]) 
    end
  end

  # @CONF default setting
  def IRB.init_config(ap_path)
    # class instance variables
    @TRACER_INITIALIZED = false

    # default configurations
    unless ap_path and @CONF[:AP_NAME]
      ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb")
    end
    @CONF[:AP_NAME] = File::basename(ap_path, ".rb")

    @CONF[:IRB_NAME] = "irb"
    @CONF[:IRB_LIB_PATH] = File.dirname(__FILE__)

    @CONF[:RC] = true
    @CONF[:LOAD_MODULES] = []
    @CONF[:IRB_RC] = nil

    @CONF[:MATH_MODE] = false
    @CONF[:USE_READLINE] = false unless defined?(ReadlineInputMethod)
    @CONF[:INSPECT_MODE] = nil
    @CONF[:USE_TRACER] = false
    @CONF[:USE_LOADER] = false
    @CONF[:IGNORE_SIGINT] = true
    @CONF[:IGNORE_EOF] = false
    @CONF[:ECHO] = nil
    @CONF[:VERBOSE] = nil

    @CONF[:EVAL_HISTORY] = nil
    @CONF[:SAVE_HISTORY] = nil

    @CONF[:BACK_TRACE_LIMIT] = 16

    @CONF[:PROMPT] = {
      :NULL => {
	:PROMPT_I => nil,
	:PROMPT_N => nil,
	:PROMPT_S => nil,
	:PROMPT_C => nil,
	:RETURN => "%s\n"
      },
      :DEFAULT => {
	:PROMPT_I => "%N(%m):%03n:%i> ",
	:PROMPT_N => "%N(%m):%03n:%i> ",
	:PROMPT_S => "%N(%m):%03n:%i%l ",
	:PROMPT_C => "%N(%m):%03n:%i* ",
	:RETURN => "=> %s\n"
      },
      :CLASSIC => {
	:PROMPT_I => "%N(%m):%03n:%i> ",
	:PROMPT_N => "%N(%m):%03n:%i> ",
	:PROMPT_S => "%N(%m):%03n:%i%l ",
	:PROMPT_C => "%N(%m):%03n:%i* ",
	:RETURN => "%s\n"
      },
      :SIMPLE => {
	:PROMPT_I => ">> ",
	:PROMPT_N => ">> ",
	:PROMPT_S => nil,
	:PROMPT_C => "?> ",
	:RETURN => "=> %s\n"
      },
      :INF_RUBY => {
	:PROMPT_I => "%N(%m):%03n:%i> ",
#	:PROMPT_N => "%N(%m):%03n:%i> ",
	:PROMPT_N => nil,
	:PROMPT_S => nil,
	:PROMPT_C => nil,
	:RETURN => "%s\n",
	:AUTO_INDENT => true
      },
      :XMP => {
	:PROMPT_I => nil,
	:PROMPT_N => nil,
	:PROMPT_S => nil,
	:PROMPT_C => nil,
	:RETURN => "    ==>%s\n"
      }
    }

    @CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL)
    @CONF[:AUTO_INDENT] = false

    @CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING
    @CONF[:SINGLE_IRB] = false

#    @CONF[:LC_MESSAGES] = "en"
    @CONF[:LC_MESSAGES] = Locale.new
    
    @CONF[:AT_EXIT] = []
    
    @CONF[:DEBUG_LEVEL] = 1
  end

  def IRB.init_error
    @CONF[:LC_MESSAGES].load("irb/error.rb")
  end

  FEATURE_IOPT_CHANGE_VERSION = "1.9.0"

  # option analyzing
  def IRB.parse_opts
    load_path = []
    while opt = ARGV.shift
      case opt
      when "-f"
	@CONF[:RC] = false
      when "-m"
	@CONF[:MATH_MODE] = true
      when "-d"
	$DEBUG = true
      when /^-r(.+)?/
	opt = $1 || ARGV.shift
	@CONF[:LOAD_MODULES].push opt if opt
      when /^-I(.+)?/
        opt = $1 || ARGV.shift
	load_path.concat(opt.split(File::PATH_SEPARATOR)) if opt
      when /^-K(.)/
	$KCODE = $1
      when "--inspect"
	@CONF[:INSPECT_MODE] = true
      when "--noinspect"
	@CONF[:INSPECT_MODE] = false
      when "--readline"
	@CONF[:USE_READLINE] = true
      when "--noreadline"
	@CONF[:USE_READLINE] = false
      when "--echo"
	@CONF[:ECHO] = true
      when "--noecho"
	@CONF[:ECHO] = false
      when "--verbose"
	@CONF[:VERBOSE] = true
      when "--noverbose"
	@CONF[:VERBOSE] = false
      when "--prompt-mode", "--prompt"
	prompt_mode = ARGV.shift.upcase.tr("-", "_").intern
	@CONF[:PROMPT_MODE] = prompt_mode
      when "--noprompt"
	@CONF[:PROMPT_MODE] = :NULL
      when "--inf-ruby-mode"
	@CONF[:PROMPT_MODE] = :INF_RUBY
      when "--sample-book-mode", "--simple-prompt"
	@CONF[:PROMPT_MODE] = :SIMPLE
      when "--tracer"
	@CONF[:USE_TRACER] = true
      when "--back-trace-limit"
	@CONF[:BACK_TRACE_LIMIT] = ARGV.shift.to_i
      when "--context-mode"
	@CONF[:CONTEXT_MODE] = ARGV.shift.to_i
      when "--single-irb"
	@CONF[:SINGLE_IRB] = true
      when "--irb_debug"
	@CONF[:DEBUG_LEVEL] = ARGV.shift.to_i
      when "-v", "--version"
	print IRB.version, "\n"
	exit 0
      when "-h", "--help"
	require "irb/help"
	IRB.print_usage
	exit 0
      when /^-/
	IRB.fail UnrecognizedSwitch, opt
      else
	@CONF[:SCRIPT] = opt
	$0 = opt
	break
      end
    end
    if RUBY_VERSION >= FEATURE_IOPT_CHANGE_VERSION
      load_path.collect! do |path|
	/\A\.\// =~ path ? path : File.expand_path(path)
      end
    end
    $LOAD_PATH.unshift(*load_path)
  end

  # running config
  def IRB.run_config
    if @CONF[:RC]
      begin
	load rc_file
      rescue LoadError, Errno::ENOENT
      rescue
	print "load error: #{rc_file}\n"
	print $!.class, ": ", $!, "\n"
	for err in $@[0, $@.size - 2]
	  print "\t", err, "\n"
	end
      end
    end
  end

  IRBRC_EXT = "rc"
  def IRB.rc_file(ext = IRBRC_EXT)
    if !@CONF[:RC_NAME_GENERATOR]
      rc_file_generators do |rcgen|
	@CONF[:RC_NAME_GENERATOR] ||= rcgen
	if File.exist?(rcgen.call(IRBRC_EXT))
	  @CONF[:RC_NAME_GENERATOR] = rcgen
	  break
	end
      end
    end
    @CONF[:RC_NAME_GENERATOR].call ext
  end

  # enumerate possible rc-file base name generators
  def IRB.rc_file_generators
    if irbrc = ENV["IRBRC"]
      yield proc{|rc|  rc == "rc" ? irbrc : irbrc+rc}
    end
    if home = ENV["HOME"]
      yield proc{|rc| home+"/.irb#{rc}"} 
    end
    home = Dir.pwd
    yield proc{|rc| home+"/.irb#{rc}"}
    yield proc{|rc| home+"/irb#{rc.sub(/\A_?/, '.')}"}
    yield proc{|rc| home+"/_irb#{rc}"}
    yield proc{|rc| home+"/$irb#{rc}"}
  end

  # loading modules
  def IRB.load_modules
    for m in @CONF[:LOAD_MODULES]
      begin
	require m
      rescue
	print $@[0], ":", $!.class, ": ", $!, "\n"
      end
    end
  end

end
PK     VZ\r)X  X    irb/cmd/nop.rbnu [        #
#   nop.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
module IRB
  module ExtendCommand
    class Nop
      
      @RCS_ID='-$Id: nop.rb 11708 2007-02-12 23:01:19Z shyouhei $-'

      def self.execute(conf, *opts)
	command = new(conf)
	command.execute(*opts)
      end

      def initialize(conf)
	@irb_context = conf
      end

      attr_reader :irb_context

      def irb
	@irb_context.irb
      end

      def execute(*opts)
	#nop
      end
    end
  end
end

PK     VZ\o  o    irb/cmd/fork.rbnu [        #
#   fork.rb - 
#   	$Release Version: 0.9.5 $
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

@RCS_ID='-$Id: fork.rb 11708 2007-02-12 23:01:19Z shyouhei $-'


module IRB
  module ExtendCommand
    class Fork<Nop
      def execute(&block)
	pid = send ExtendCommand.irb_original_method_name("fork")
	unless pid 
	  class<<self
	    alias_method :exit, ExtendCommand.irb_original_method_name('exit')
	  end
	  if iterator?
	    begin
	      yield
	    ensure
	      exit
	    end
	  end
	end
	pid
      end
    end
  end
end


PK     WZ\$b       irb/cmd/subirb.rbnu [        #!/usr/local/bin/ruby
#
#   multi.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

require "irb/cmd/nop.rb"
require "irb/ext/multi-irb"

module IRB
  module ExtendCommand
    class IrbCommand<Nop
      def execute(*obj)
	IRB.irb(nil, *obj)
      end
    end

    class Jobs<Nop
      def execute
	IRB.JobManager
      end
    end

    class Foreground<Nop
      def execute(key)
	IRB.JobManager.switch(key)
      end
    end

    class Kill<Nop
      def execute(*keys)
	IRB.JobManager.kill(*keys)
      end
    end
  end
end
PK     WZ\k=      irb/cmd/chws.rbnu [        #
#   change-ws.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

require "irb/cmd/nop.rb"
require "irb/ext/change-ws.rb"

module IRB
  module ExtendCommand

    class CurrentWorkingWorkspace<Nop
      def execute(*obj)
	irb_context.main
      end
    end

    class ChangeWorkspace<Nop
      def execute(*obj)
	irb_context.change_workspace(*obj)
	irb_context.main
      end
    end
  end
end

PK     WZ\L M  M    irb/cmd/help.rbnu [        #
#   help.rb - helper using ri
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#
# --
#
#   
#

require 'rdoc/ri/ri_driver'

module IRB
  module ExtendCommand
    module Help
      begin
        @ri = RiDriver.new
      rescue SystemExit
      else
        def self.execute(context, *names)
          names.each do |name|
            begin
              @ri.get_info_for(name.to_s)
            rescue RiError
              puts $!.message
            end
          end
          nil
        end
      end
    end
  end
end
PK     XZ\E1      irb/cmd/pushws.rbnu [        #
#   change-ws.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

require "irb/cmd/nop.rb"
require "irb/ext/workspaces.rb"

module IRB
  module ExtendCommand
    class Workspaces<Nop
      def execute(*obj)
	irb_context.workspaces.collect{|ws| ws.main}
      end
    end

    class PushWorkspace<Workspaces
      def execute(*obj)
	irb_context.push_workspace(*obj)
	super
      end
    end

    class PopWorkspace<Workspaces
      def execute(*obj)
	irb_context.pop_workspace(*obj)
	super
      end
    end
  end
end

PK     XZ\ิ      irb/cmd/load.rbnu [        #
#   load.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

require "irb/cmd/nop.rb"
require "irb/ext/loader"

module IRB
  module ExtendCommand
    class Load<Nop
      include IrbLoader

      def execute(file_name, priv = nil)
#	return ruby_load(file_name) unless IRB.conf[:USE_LOADER]
	return irb_load(file_name, priv)
      end
    end

    class Require<Nop
      include IrbLoader
      
      def execute(file_name)
#	return ruby_require(file_name) unless IRB.conf[:USE_LOADER]

	rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
	return false if $".find{|f| f =~ rex}

	case file_name
	when /\.rb$/
	  begin
	    if irb_load(file_name)
	      $".push file_name
	      return true
	    end
	  rescue LoadError
	  end
	when /\.(so|o|sl)$/
	  return ruby_require(file_name)
	end
	
	begin
	  irb_load(f = file_name + ".rb")
	  $".push f
	  return true
	rescue LoadError
	  return ruby_require(file_name)
	end
      end
    end

    class Source<Nop
      include IrbLoader
      def execute(file_name)
	source_file(file_name)
      end
    end
  end

end
PK     YZ\|Ӑ~y  y    irb/ext/history.rbnu [        #
#   history.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

module IRB

  class Context

    NOPRINTING_IVARS.push "@eval_history_values"

    alias _set_last_value set_last_value

    def set_last_value(value)
      _set_last_value(value)

#      @workspace.evaluate self, "_ = IRB.CurrentContext.last_value"
      if @eval_history #and !@eval_history_values.equal?(llv)
 	@eval_history_values.push @line_no, @last_value
 	@workspace.evaluate self, "__ = IRB.CurrentContext.instance_eval{@eval_history_values}"
      end

      @last_value
    end

    attr_reader :eval_history
    def eval_history=(no)
      if no
	if defined?(@eval_history) && @eval_history
	  @eval_history_values.size(no)
	else
	  @eval_history_values = History.new(no)
	  IRB.conf[:__TMP__EHV__] = @eval_history_values
	  @workspace.evaluate(self, "__ = IRB.conf[:__TMP__EHV__]")
	  IRB.conf.delete(:__TMP_EHV__)
	end
      else
	@eval_history_values = nil
      end
      @eval_history = no
    end
  end

  class History
    @RCS_ID='-$Id: history.rb 11708 2007-02-12 23:01:19Z shyouhei $-'

    def initialize(size = 16)
      @size = size
      @contents = []
    end

    def size(size)
      if size != 0 && size < @size 
	@contents = @contents[@size - size .. @size]
      end
      @size = size
    end

    def [](idx)
      begin
	if idx >= 0
	  @contents.find{|no, val| no == idx}[1]
	else
	  @contents[idx][1]
	end
      rescue NameError
	nil
      end
    end

    def push(no, val)
      @contents.push [no, val]
      @contents.shift if @size != 0 && @contents.size > @size
    end
    
    alias real_inspect inspect

    def inspect
      if @contents.empty?
	return real_inspect
      end

      unless (last = @contents.pop)[1].equal?(self)
	@contents.push last
	last = nil
      end
      str = @contents.collect{|no, val|
	if val.equal?(self)
	  "#{no} ...self-history..."
	else
	  "#{no} #{val.inspect}"
	end
      }.join("\n")
      if str == ""
	str = "Empty."
      end
      @contents.push last if last
      str
    end
  end
end


PK     ZZ\Jx  x    irb/ext/save-history.rbnu [        #!/usr/local/bin/ruby
#
#   save-history.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 24483 $
#   	$Date: 2009-08-09 17:44:15 +0900 (Sun, 09 Aug 2009) $
#   	by Keiju ISHITSUKAkeiju@ruby-lang.org)
#
# --
#
#   
#

require "readline"

module IRB
  module HistorySavingAbility
    @RCS_ID='-$Id: save-history.rb 24483 2009-08-09 08:44:15Z shyouhei $-'
  end

  class Context
    def init_save_history
      unless (class<<@io;self;end).include?(HistorySavingAbility)
	@io.extend(HistorySavingAbility)
      end
    end

    def save_history
      IRB.conf[:SAVE_HISTORY]
    end

    def save_history=(val)
      IRB.conf[:SAVE_HISTORY] = val
      if val
	main_context = IRB.conf[:MAIN_CONTEXT]
	main_context = self unless main_context
	main_context.init_save_history
      end
    end

    def history_file
      IRB.conf[:HISTORY_FILE]
    end

    def history_file=(hist)
      IRB.conf[:HISTORY_FILE] = hist
    end
  end

  module HistorySavingAbility
    include Readline

#     def HistorySavingAbility.create_finalizer
#       proc do
# 	if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) > 0
# 	  if hf = IRB.conf[:HISTORY_FILE]
# 	    file = File.expand_path(hf)
# 	  end
# 	  file = IRB.rc_file("_history") unless file
# 	  open(file, 'w' ) do |f|
# 	    hist = HISTORY.to_a
# 	    f.puts(hist[-num..-1] || hist)
# 	  end
# 	end
#       end
#     end

    def HistorySavingAbility.extended(obj)
#      ObjectSpace.define_finalizer(obj, HistorySavingAbility.create_finalizer)
      IRB.conf[:AT_EXIT].push proc{obj.save_history}
      obj.load_history
      obj
    end

    def load_history
      hist = IRB.conf[:HISTORY_FILE]
      hist = IRB.rc_file("_history") unless hist
      if File.exist?(hist)
	open(hist) do |f|
	  f.each {|l| HISTORY << l.chomp}
	end
      end
    end

    def save_history
      if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) > 0
	if history_file = IRB.conf[:HISTORY_FILE]
	  history_file = File.expand_path(history_file)
	end
	history_file = IRB.rc_file("_history") unless history_file
	open(history_file, 'w' ) do |f|
	  hist = HISTORY.to_a
	  f.puts(hist[-num..-1] || hist)
	end
      end
    end
  end
end

PK     [Z\	  	    irb/ext/loader.rbnu [        #
#   loader.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#


module IRB
  class LoadAbort < Exception;end

  module IrbLoader
    @RCS_ID='-$Id: loader.rb 11708 2007-02-12 23:01:19Z shyouhei $-'

    alias ruby_load load
    alias ruby_require require

    def irb_load(fn, priv = nil)
      path = search_file_from_ruby_path(fn)
      raise LoadError, "No such file to load -- #{fn}" unless path

      load_file(path, priv)
    end

    def search_file_from_ruby_path(fn)
      if /^#{Regexp.quote(File::Separator)}/ =~ fn
	return fn if File.exist?(fn)
	return nil
      end

      for path in $:
	if File.exist?(f = File.join(path, fn))
	  return f
	end
      end
      return nil
    end

    def source_file(path)
      irb.suspend_name(path, File.basename(path)) do
	irb.suspend_input_method(FileInputMethod.new(path)) do
	  |back_io|
	  irb.signal_status(:IN_LOAD) do 
	    if back_io.kind_of?(FileInputMethod)
	      irb.eval_input
	    else
	      begin
		irb.eval_input
	      rescue LoadAbort
		print "load abort!!\n"
	      end
	    end
	  end
	end
      end
    end

    def load_file(path, priv = nil)
      irb.suspend_name(path, File.basename(path)) do
	
	if priv
	  ws = WorkSpace.new(Module.new)
	else
	  ws = WorkSpace.new
	end
	irb.suspend_workspace(ws) do
	  irb.suspend_input_method(FileInputMethod.new(path)) do
	    |back_io|
	    irb.signal_status(:IN_LOAD) do 
#	      p irb.conf
	      if back_io.kind_of?(FileInputMethod)
		irb.eval_input
	      else
		begin
		  irb.eval_input
		rescue LoadAbort
		  print "load abort!!\n"
		end
	      end
	    end
	  end
	end
      end
    end

    def old
      back_io = @io
      back_path = @irb_path
      back_name = @irb_name
      back_scanner = @irb.scanner
      begin
 	@io = FileInputMethod.new(path)
 	@irb_name = File.basename(path)
	@irb_path = path
	@irb.signal_status(:IN_LOAD) do
	  if back_io.kind_of?(FileInputMethod)
	    @irb.eval_input
	  else
	    begin
	      @irb.eval_input
	    rescue LoadAbort
	      print "load abort!!\n"
	    end
	  end
	end
      ensure
 	@io = back_io
 	@irb_name = back_name
 	@irb_path = back_path
	@irb.scanner = back_scanner
      end
    end
  end
end

PK     \Z\cq  q    irb/ext/math-mode.rbnu [        #
#   math-mode.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
require "mathn"

module IRB
  class Context
    attr_reader :math_mode
    alias math? math_mode

    def math_mode=(opt)
      if @math_mode == true && opt == false
	IRB.fail CantReturnToNormalMode
	return
      end

      @math_mode = opt
      if math_mode
	main.extend Math
	print "start math mode\n" if verbose?
      end
    end

    def inspect?
      @inspect_mode.nil? && !@math_mode or @inspect_mode
    end
  end
end

PK     \Z\      irb/ext/workspaces.rbnu [        #
#   push-ws.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

module IRB
  class Context

    def irb_level
      workspace_stack.size
    end

    def workspaces
      if defined? @workspaces
	@workspaces
      else
	@workspaces = []
      end
    end

    def push_workspace(*_main)
      if _main.empty?
	if workspaces.empty?
	  print "No other workspace\n"
	  return nil
	end
	ws = workspaces.pop
	workspaces.push @workspace
	@workspace = ws
	return workspaces
      end

      workspaces.push @workspace
      @workspace = WorkSpace.new(@workspace.binding, _main[0])
      if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
	main.extend ExtendCommandBundle
      end
    end

    def pop_workspace
      if workspaces.empty?
	print "workspace stack empty\n"
	return
      end
      @workspace = workspaces.pop
    end
  end
end

PK     ]Z\G      irb/ext/change-ws.rbnu [        #
#   irb/ext/cb.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

module IRB
  class Context

    def home_workspace
      if defined? @home_workspace
	@home_workspace
      else
	@home_workspace = @workspace
      end
    end

    def change_workspace(*_main)
      if _main.empty?
	@workspace = home_workspace 
	return main
      end
      
      @workspace = WorkSpace.new(_main[0])
      
      if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
	main.extend ExtendCommandBundle
      end
    end

#     def change_binding(*_main)
#       back = @workspace
#       @workspace = WorkSpace.new(*_main)
#       unless _main.empty?
# 	begin
# 	  main.extend ExtendCommandBundle
# 	rescue
# 	  print "can't change binding to: ", main.inspect, "\n"
# 	  @workspace = back
# 	  return nil
# 	end
#       end
#       @irb_level += 1
#       begin
# 	catch(:SU_EXIT) do
# 	  @irb.eval_input
# 	end
#       ensure
# 	@irb_level -= 1
#  	@workspace = back
#       end
#     end
#     alias change_workspace change_binding
   end
end

PK     `Z\I|S  S    irb/ext/use-loader.rbnu [        #
#   use-loader.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

require "irb/cmd/load"
require "irb/ext/loader"

class Object
  alias __original__load__IRB_use_loader__ load
  alias __original__require__IRB_use_loader__ require
end

module IRB
  module ExtendCommandBundle
    def irb_load(*opts, &b)
      ExtendCommand::Load.execute(irb_context, *opts, &b)
    end
    def irb_require(*opts, &b)
      ExtendCommand::Require.execute(irb_context, *opts, &b)
    end
  end

  class Context

    IRB.conf[:USE_LOADER] = false
    
    def use_loader
      IRB.conf[:USE_LOADER]
    end

    alias use_loader? use_loader

    def use_loader=(opt)

      if IRB.conf[:USE_LOADER] != opt
	IRB.conf[:USE_LOADER] = opt
	if opt
	  if !$".include?("irb/cmd/load")
	  end
	  (class<<@workspace.main;self;end).instance_eval {
	    alias_method :load, :irb_load
	    alias_method :require, :irb_require
	  }
	else
	  (class<<@workspace.main;self;end).instance_eval {
	    alias_method :load, :__original__load__IRB_use_loader__
	    alias_method :require, :__original__require__IRB_use_loader__
	  }
	end
      end
      print "Switch to load/require#{unless use_loader; ' non';end} trace mode.\n" if verbose?
      opt
    end
  end
end


PK     bZ\>      irb/ext/tracer.rbnu [        #
#   irb/lib/tracer.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
require "tracer"

module IRB

  # initialize tracing function
  def IRB.initialize_tracer
    Tracer.verbose = false
    Tracer.add_filter {
      |event, file, line, id, binding, *rests|
      /^#{Regexp.quote(@CONF[:IRB_LIB_PATH])}/ !~ file and
	File::basename(file) != "irb.rb"
    }
  end

  class Context
    attr_reader :use_tracer
    alias use_tracer? use_tracer

    def use_tracer=(opt)
      if opt
	Tracer.set_get_line_procs(@irb_path) {
	  |line_no, *rests|
	  @io.line(line_no)
	}
      elsif !opt && @use_tracer
	Tracer.off
      end
      @use_tracer=opt
    end
  end

  class WorkSpace
    alias __evaluate__ evaluate
    def evaluate(context, statements, file = nil, line = nil)
      if context.use_tracer? && file != nil && line != nil
	Tracer.on 
	begin
	  __evaluate__(context, statements, file, line)
	ensure
	  Tracer.off
	end
      else
	__evaluate__(context, statements, file || __FILE__, line || __LINE__)
      end
    end
  end

  IRB.initialize_tracer
end
	
PK     dZ\+        irb/ext/multi-irb.rbnu [        #
#   irb/multi-irb.rb - multiple irb module
#   	$Release Version: 0.9.5$
#   	$Revision: 25814 $
#   	$Date: 2009-11-17 15:51:29 +0900 (Tue, 17 Nov 2009) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
IRB.fail CantShiftToMultiIrbMode unless defined?(Thread)
require "thread"

module IRB
  # job management class
  class JobManager
    @RCS_ID='-$Id: multi-irb.rb 25814 2009-11-17 06:51:29Z shyouhei $-'

    def initialize
      # @jobs = [[thread, irb],...]
      @jobs = []
      @current_job = nil
    end

    attr_accessor :current_job

    def n_jobs
      @jobs.size
    end

    def thread(key)
      th, irb = search(key)
      th
    end

    def irb(key)
      th, irb = search(key)
      irb
    end

    def main_thread
      @jobs[0][0]
    end

    def main_irb
      @jobs[0][1]
    end

    def insert(irb)
      @jobs.push [Thread.current, irb]
    end

    def switch(key)
      th, irb = search(key)
      IRB.fail IrbAlreadyDead unless th.alive?
      IRB.fail IrbSwitchedToCurrentThread if th == Thread.current
      @current_job = irb
      th.run
      Thread.stop
      @current_job = irb(Thread.current)
    end

    def kill(*keys)
      for key in keys
	th, irb = search(key)
	IRB.fail IrbAlreadyDead unless th.alive?
	th.exit
      end
    end    

    def search(key)
      job = case key
      when Integer
	@jobs[key]
      when Irb
	@jobs.find{|k, v| v.equal?(key)}
      when Thread
	@jobs.assoc(key)
      else
	@jobs.find{|k, v| v.context.main.equal?(key)}
      end
      IRB.fail NoSuchJob, key if job.nil?
      job
    end

    def delete(key)
      case key
      when Integer
	IRB.fail NoSuchJob, key unless @jobs[key]
	@jobs[key] = nil
      else
	catch(:EXISTS) do
	  @jobs.each_index do
	    |i|
	    if @jobs[i] and (@jobs[i][0] == key ||
			     @jobs[i][1] == key ||
			     @jobs[i][1].context.main.equal?(key))
	      @jobs[i] = nil
	      throw :EXISTS
	    end
	  end
	  IRB.fail NoSuchJob, key
	end
      end
      until assoc = @jobs.pop; end unless @jobs.empty?
      @jobs.push assoc
    end

    def inspect
      ary = []
      @jobs.each_index do
	|i|
	th, irb = @jobs[i]
	next if th.nil?

	if th.alive?
	  if th.stop?
	    t_status = "stop"
	  else
	    t_status = "running"
	  end
	else
	  t_status = "exited"
	end
	ary.push format("#%d->%s on %s (%s: %s)",
			i, 
			irb.context.irb_name, 
			irb.context.main,
			th,
			t_status)
      end
      ary.join("\n")
    end
  end

  @JobManager = JobManager.new

  def IRB.JobManager
    @JobManager
  end

  def IRB.CurrentContext
    IRB.JobManager.irb(Thread.current).context
  end

  # invoke multi-irb 
  def IRB.irb(file = nil, *main)
    workspace = WorkSpace.new(*main)
    parent_thread = Thread.current
    Thread.start do
      begin
	irb = Irb.new(workspace, file)
      rescue 
	print "Subirb can't start with context(self): ", workspace.main.inspect, "\n"
	print "return to main irb\n"
	Thread.pass
	Thread.main.wakeup
	Thread.exit
      end
      @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
      @JobManager.insert(irb)
      @JobManager.current_job = irb
      begin
	system_exit = false
	catch(:IRB_EXIT) do
	  irb.eval_input
	end
      rescue SystemExit
	system_exit = true
	raise
	#fail
      ensure
	unless system_exit
	  @JobManager.delete(irb)
	  if parent_thread.alive?
	    @JobManager.current_job = @JobManager.irb(parent_thread)
	    parent_thread.run
	  else
	    @JobManager.current_job = @JobManager.main_irb
	    @JobManager.main_thread.run
	  end
	end
      end
    end
    Thread.stop
    @JobManager.current_job = @JobManager.irb(Thread.current)
  end

#   class Context
#     def set_last_value(value)
#       @last_value = value
#       @workspace.evaluate "_ = IRB.JobManager.irb(Thread.current).context.last_value"
#       if @eval_history #and !@__.equal?(@last_value)
# 	@eval_history_values.push @line_no, @last_value
# 	@workspace.evaluate "__ = IRB.JobManager.irb(Thread.current).context.instance_eval{@eval_history_values}"
#       end
#       @last_value
#     end
#   end

#  module ExtendCommand
#     def irb_context
#       IRB.JobManager.irb(Thread.current).context
#     end
# #    alias conf irb_context
#   end

  @CONF[:SINGLE_IRB_MODE] = false
  @JobManager.insert(@CONF[:MAIN_CONTEXT].irb)
  @JobManager.current_job = @CONF[:MAIN_CONTEXT].irb

  class Irb
    def signal_handle
      unless @context.ignore_sigint?
	print "\nabort!!\n" if @context.verbose?
	exit
      end

      case @signal_status
      when :IN_INPUT
	print "^C\n"
	IRB.JobManager.thread(self).raise RubyLex::TerminateLineInput
      when :IN_EVAL
	IRB.irb_abort(self)
      when :IN_LOAD
	IRB.irb_abort(self, LoadAbort)
      when :IN_IRB
	# ignore
      else
	# ignore other cases as well
      end
    end
  end

  trap("SIGINT") do
    @JobManager.current_job.signal_handle
    Thread.stop
  end

end
PK     eZ\.    
  irb/xmp.rbnu [        #
#   xmp.rb - irb version of gotoken xmp
#   	$Release Version: 0.9$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(Nippon Rational Inc.)
#
# --
#
#   
#

require "irb"
require "irb/frame"

class XMP
  @RCS_ID='-$Id: xmp.rb 11708 2007-02-12 23:01:19Z shyouhei $-'

  def initialize(bind = nil)
    IRB.init_config(nil)
    #IRB.parse_opts
    #IRB.load_modules

    IRB.conf[:PROMPT_MODE] = :XMP

    bind = IRB::Frame.top(1) unless bind
    ws = IRB::WorkSpace.new(bind)
    @io = StringInputMethod.new
    @irb = IRB::Irb.new(ws, @io)
    @irb.context.ignore_sigint = false

#    IRB.conf[:IRB_RC].call(@irb.context) if IRB.conf[:IRB_RC]
    IRB.conf[:MAIN_CONTEXT] = @irb.context
  end

  def puts(exps)
    @io.puts exps

    if @irb.context.ignore_sigint
      begin
	trap_proc_b = trap("SIGINT"){@irb.signal_handle}
	catch(:IRB_EXIT) do
	  @irb.eval_input
	end
      ensure
	trap("SIGINT", trap_proc_b)
      end
    else
      catch(:IRB_EXIT) do
	@irb.eval_input
      end
    end
  end

  class StringInputMethod < IRB::InputMethod
    def initialize
      super
      @exps = []
    end

    def eof?
      @exps.empty?
    end

    def gets
      while l = @exps.shift
	next if /^\s+$/ =~ l
	l.concat "\n"
	print @prompt, l
	break
      end
      l
    end

    def puts(exps)
      @exps.concat exps.split(/\n/)
    end
  end
end

def xmp(exps, bind = nil)
  bind = IRB::Frame.top(1) unless bind
  xmp = XMP.new(bind)
  xmp.puts exps
  xmp
end
PK     fZ\sh  h    irb/completion.rbnu [        #
#   irb/completor.rb - 
#   	$Release Version: 0.9$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ishitsuka.com)
#       From Original Idea of shugo@ruby-lang.org
#

require "readline"

module IRB
  module InputCompletor

    @RCS_ID='-$Id: completion.rb 11708 2007-02-12 23:01:19Z shyouhei $-'

    ReservedWords = [
      "BEGIN", "END",
      "alias", "and", 
      "begin", "break", 
      "case", "class",
      "def", "defined", "do",
      "else", "elsif", "end", "ensure",
      "false", "for", 
      "if", "in", 
      "module", 
      "next", "nil", "not",
      "or", 
      "redo", "rescue", "retry", "return",
      "self", "super",
      "then", "true",
      "undef", "unless", "until",
      "when", "while",
      "yield",
    ]
      
    CompletionProc = proc { |input|
      bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
      
#      puts "input: #{input}"

      case input
      when /^(\/[^\/]*\/)\.([^.]*)$/
	# Regexp
	receiver = $1
	message = Regexp.quote($2)

	candidates = Regexp.instance_methods(true)
	select_message(receiver, message, candidates)

      when /^([^\]]*\])\.([^.]*)$/
	# Array
	receiver = $1
	message = Regexp.quote($2)

	candidates = Array.instance_methods(true)
	select_message(receiver, message, candidates)

      when /^([^\}]*\})\.([^.]*)$/
	# Proc or Hash
	receiver = $1
	message = Regexp.quote($2)

	candidates = Proc.instance_methods(true) | Hash.instance_methods(true)
	select_message(receiver, message, candidates)
	
      when /^(:[^:.]*)$/
 	# Symbol
	if Symbol.respond_to?(:all_symbols)
	  sym = $1
	  candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
	  candidates.grep(/^#{sym}/)
	else
	  []
	end

      when /^::([A-Z][^:\.\(]*)$/
	# Absolute Constant or class methods
	receiver = $1
	candidates = Object.constants
	candidates.grep(/^#{receiver}/).collect{|e| "::" + e}

      when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/
	# Constant or class methods
	receiver = $1
	message = Regexp.quote($4)
	begin
	  candidates = eval("#{receiver}.constants | #{receiver}.methods", bind)
	rescue Exception
	  candidates = []
	end
	candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}

      when /^(:[^:.]+)\.([^.]*)$/
	# Symbol
	receiver = $1
	message = Regexp.quote($2)

	candidates = Symbol.instance_methods(true)
	select_message(receiver, message, candidates)

      when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/
	# Numeric
	receiver = $1
	message = Regexp.quote($5)

	begin
	  candidates = eval(receiver, bind).methods
	rescue Exception
	  candidates = []
	end
	select_message(receiver, message, candidates)

      when /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/
	# Numeric(0xFFFF)
	receiver = $1
	message = Regexp.quote($2)

	begin
	  candidates = eval(receiver, bind).methods
	rescue Exception
	  candidates = []
	end
	select_message(receiver, message, candidates)

      when /^(\$[^.]*)$/
	candidates = global_variables.grep(Regexp.new(Regexp.quote($1)))

#      when /^(\$?(\.?[^.]+)+)\.([^.]*)$/
      when /^((\.?[^.]+)+)\.([^.]*)$/
	# variable
	receiver = $1
	message = Regexp.quote($3)

	gv = eval("global_variables", bind)
	lv = eval("local_variables", bind)
	cv = eval("self.class.constants", bind)
	
	if (gv | lv | cv).include?(receiver)
	  # foo.func and foo is local var.
	  candidates = eval("#{receiver}.methods", bind)
	elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
	  # Foo::Bar.func
	  begin
	    candidates = eval("#{receiver}.methods", bind)
	  rescue Exception
	    candidates = []
	  end
	else
	  # func1.func2
	  candidates = []
	  ObjectSpace.each_object(Module){|m|
	    begin
	      name = m.name
	    rescue Exception
	      name = ""
	    end
	    next if name != "IRB::Context" and 
	      /^(IRB|SLex|RubyLex|RubyToken)/ =~ name
	    candidates.concat m.instance_methods(false)
	  }
	  candidates.sort!
	  candidates.uniq!
	end
	select_message(receiver, message, candidates)

      when /^\.([^.]*)$/
	# unknown(maybe String)

	receiver = ""
	message = Regexp.quote($1)

	candidates = String.instance_methods(true)
	select_message(receiver, message, candidates)

      else
	candidates = eval("methods | private_methods | local_variables | self.class.constants", bind)
			  
	(candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
      end
    }

    Operators = ["%", "&", "*", "**", "+",  "-",  "/",
      "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
      "[]", "[]=", "^",]

    def self.select_message(receiver, message, candidates)
      candidates.grep(/^#{message}/).collect do |e|
	case e
	when /^[a-zA-Z_]/
	  receiver + "." + e
	when /^[0-9]/
	when *Operators
	  #receiver + " " + e
	end
      end
    end
  end
end

if Readline.respond_to?("basic_word_break_characters=")
  Readline.basic_word_break_characters= " \t\n\"\\'`><=;|&{("
end
Readline.completion_append_character = nil
Readline.completion_proc = IRB::InputCompletor::CompletionProc
PK     gZ\S0
  0
    irb/workspace.rbnu [        #
#   irb/workspace-binding.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
module IRB
  class WorkSpace
    # create new workspace. set self to main if specified, otherwise
    # inherit main from TOPLEVEL_BINDING.
    def initialize(*main)
      if main[0].kind_of?(Binding)
	@binding = main.shift
      elsif IRB.conf[:SINGLE_IRB]
	@binding = TOPLEVEL_BINDING
      else
	case IRB.conf[:CONTEXT_MODE]
	when 0	# binding in proc on TOPLEVEL_BINDING
	  @binding = eval("proc{binding}.call",
		      TOPLEVEL_BINDING, 
		      __FILE__,
		      __LINE__)
	when 1	# binding in loaded file
	  require "tempfile"
	  f = Tempfile.open("irb-binding")
	  f.print <<EOF
	  $binding = binding
EOF
	  f.close
	  load f.path
	  @binding = $binding

	when 2	# binding in loaded file(thread use)
	  unless defined? BINDING_QUEUE
	    require "thread"
	    
	    IRB.const_set("BINDING_QUEUE", SizedQueue.new(1))
	    Thread.abort_on_exception = true
	    Thread.start do
	      eval "require \"irb/ws-for-case-2\"", TOPLEVEL_BINDING, __FILE__, __LINE__
	    end
	    Thread.pass
	  end
	  @binding = BINDING_QUEUE.pop

	when 3	# binging in function on TOPLEVEL_BINDING(default)
	  @binding = eval("def irb_binding; binding; end; irb_binding",
		      TOPLEVEL_BINDING, 
		      __FILE__,
		      __LINE__ - 3)
	end
      end
      if main.empty?
	@main = eval("self", @binding)
      else
	@main = main[0]
	IRB.conf[:__MAIN__] = @main
	case @main
	when Module
	  @binding = eval("IRB.conf[:__MAIN__].module_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
	else
	  begin 
	    @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
	  rescue TypeError
	    IRB.fail CantChangeBinding, @main.inspect
	  end
	end
      end
      eval("_=nil", @binding)
    end

    attr_reader :binding
    attr_reader :main

    def evaluate(context, statements, file = __FILE__, line = __LINE__)
      eval(statements, @binding, file, line)
    end
  
    # error message manipulator
    def filter_backtrace(bt)
      case IRB.conf[:CONTEXT_MODE]
      when 0
	return nil if bt =~ /\(irb_local_binding\)/
      when 1
	if(bt =~ %r!/tmp/irb-binding! or
	   bt =~ %r!irb/.*\.rb! or
	   bt =~ /irb\.rb/)
	  return nil
	end
      when 2
	return nil if bt =~ /irb\/.*\.rb/
      when 3
	return nil if bt =~ /irb\/.*\.rb/
	bt.sub!(/:\s*in `irb_binding'/){""} 
      end
      bt
    end

    def IRB.delete_caller
    end
  end
end
PK     hZ\1I      irb/ws-for-case-2.rbnu [        #
#   irb/ws-for-case-2.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

while true
  IRB::BINDING_QUEUE.push b = binding
end
PK     iZ\(_;  ;    irb/input-method.rbnu [        #
#   irb/input-method.rb - input methods used irb
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
module IRB
  # 
  # InputMethod
  #	StdioInputMethod
  #	FileInputMethod
  #	(ReadlineInputMethod)
  #
  STDIN_FILE_NAME = "(line)"
  class InputMethod
    @RCS_ID='-$Id: input-method.rb 11708 2007-02-12 23:01:19Z shyouhei $-'

    def initialize(file = STDIN_FILE_NAME)
      @file_name = file
    end
    attr_reader :file_name

    attr_accessor :prompt
    
    def gets
      IRB.fail NotImplementedError, "gets"
    end
    public :gets

    def readable_atfer_eof?
      false
    end
  end
  
  class StdioInputMethod < InputMethod
    def initialize
      super
      @line_no = 0
      @line = []
    end

    def gets
      print @prompt
      @line[@line_no += 1] = $stdin.gets
    end

    def eof?
      $stdin.eof?
    end

    def readable_atfer_eof?
      true
    end

    def line(line_no)
      @line[line_no]
    end
  end
  
  class FileInputMethod < InputMethod
    def initialize(file)
      super
      @io = open(file)
    end
    attr_reader :file_name

    def eof?
      @io.eof?
    end

    def gets
      print @prompt
      l = @io.gets
#      print @prompt, l
      l
    end
  end

  begin
    require "readline"
    class ReadlineInputMethod < InputMethod
      include Readline 
      def initialize
	super

	@line_no = 0
	@line = []
	@eof = false
      end

      def gets
	if l = readline(@prompt, false)
          HISTORY.push(l) if !l.empty?
	  @line[@line_no += 1] = l + "\n"
	else
	  @eof = true
	  l
	end
      end

      def eof?
	@eof
      end

      def readable_atfer_eof?
	true
      end

      def line(line_no)
	@line[line_no]
      end
    end
  rescue LoadError
  end
end
PK     jZ\&F  F    irb/help.rbnu [        #
#   irb/help.rb - print usage module
#   	$Release Version: 0.9.5$
#   	$Revision: 16857 $
#   	$Date: 2008-06-06 17:05:24 +0900 (Fri, 06 Jun 2008) $
#   	by Keiju ISHITSUKA(keiju@ishitsuka.com)
#
# --
#
#   
#

module IRB
  def IRB.print_usage
    lc = IRB.conf[:LC_MESSAGES]
    path = lc.find("irb/help-message")
    space_line = false
    File.foreach(path) do
      |l|
      if /^\s*$/ =~ l
	lc.puts l unless space_line
	space_line = true
	next
      end
      space_line = false
      
      l.sub!(/#.*$/, "")
      next if /^\s*$/ =~ l
      lc.puts l
    end
  end
end

PK     jZ\V      irb/context.rbnu [        #
#   irb/context.rb - irb context
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
require "irb/workspace"

module IRB
  class Context
    #
    # Arguments:
    #   input_method: nil -- stdin or readline
    #		      String -- File
    #		      other -- using this as InputMethod
    #
    def initialize(irb, workspace = nil, input_method = nil, output_method = nil)
      @irb = irb
      if workspace
	@workspace = workspace
      else
	@workspace = WorkSpace.new
      end
      @thread = Thread.current if defined? Thread
#      @irb_level = 0

      # copy of default configuration
      @ap_name = IRB.conf[:AP_NAME]
      @rc = IRB.conf[:RC]
      @load_modules = IRB.conf[:LOAD_MODULES]

      @use_readline = IRB.conf[:USE_READLINE]
      @inspect_mode = IRB.conf[:INSPECT_MODE]

      self.math_mode = IRB.conf[:MATH_MODE] if IRB.conf[:MATH_MODE]
      self.use_tracer = IRB.conf[:USE_TRACER] if IRB.conf[:USE_TRACER]
      self.use_loader = IRB.conf[:USE_LOADER] if IRB.conf[:USE_LOADER]
      self.eval_history = IRB.conf[:EVAL_HISTORY] if IRB.conf[:EVAL_HISTORY]

      @ignore_sigint = IRB.conf[:IGNORE_SIGINT]
      @ignore_eof = IRB.conf[:IGNORE_EOF]

      @back_trace_limit = IRB.conf[:BACK_TRACE_LIMIT]
      
      self.prompt_mode = IRB.conf[:PROMPT_MODE]

      if IRB.conf[:SINGLE_IRB] or !defined?(JobManager)
	@irb_name = IRB.conf[:IRB_NAME]
      else
	@irb_name = "irb#"+IRB.JobManager.n_jobs.to_s
      end
      @irb_path = "(" + @irb_name + ")"

      case input_method
      when nil
	case use_readline?
	when nil
	  if (defined?(ReadlineInputMethod) && STDIN.tty? &&
	      IRB.conf[:PROMPT_MODE] != :INF_RUBY)
	    @io = ReadlineInputMethod.new
	  else
	    @io = StdioInputMethod.new
	  end
	when false
	  @io = StdioInputMethod.new
	when true
	  if defined?(ReadlineInputMethod)
	    @io = ReadlineInputMethod.new
	  else
	    @io = StdioInputMethod.new
	  end
	end

      when String
	@io = FileInputMethod.new(input_method)
	@irb_name = File.basename(input_method)
	@irb_path = input_method
      else
	@io = input_method
      end
      self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY]

      if output_method
	@output_method = output_method
      else
	@output_method = StdioOutputMethod.new
      end

      @verbose = IRB.conf[:VERBOSE] 
      @echo = IRB.conf[:ECHO]
      if @echo.nil?
	@echo = true
      end
      @debug_level = IRB.conf[:DEBUG_LEVEL]
    end

    def main
      @workspace.main
    end

    attr_reader :workspace_home
    attr_accessor :workspace
    attr_reader :thread
    attr_accessor :io
    
    attr_accessor :irb
    attr_accessor :ap_name
    attr_accessor :rc
    attr_accessor :load_modules
    attr_accessor :irb_name
    attr_accessor :irb_path

    attr_reader :use_readline
    attr_reader :inspect_mode

    attr_reader :prompt_mode
    attr_accessor :prompt_i
    attr_accessor :prompt_s
    attr_accessor :prompt_c
    attr_accessor :prompt_n
    attr_accessor :auto_indent_mode
    attr_accessor :return_format

    attr_accessor :ignore_sigint
    attr_accessor :ignore_eof
    attr_accessor :echo
    attr_accessor :verbose
    attr_reader :debug_level

    attr_accessor :back_trace_limit

    alias use_readline? use_readline
    alias rc? rc
    alias ignore_sigint? ignore_sigint
    alias ignore_eof? ignore_eof
    alias echo? echo

    def verbose?
      if @verbose.nil?
	if defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod) 
	  false
	elsif !STDIN.tty? or @io.kind_of?(FileInputMethod)
	  true
	else
	  false
	end
      end
    end

    def prompting?
      verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) ||
		(defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)))
    end

    attr_reader :last_value

    def set_last_value(value)
      @last_value = value
      @workspace.evaluate self, "_ = IRB.CurrentContext.last_value"
    end

    attr_reader :irb_name

    def prompt_mode=(mode)
      @prompt_mode = mode
      pconf = IRB.conf[:PROMPT][mode]
      @prompt_i = pconf[:PROMPT_I]
      @prompt_s = pconf[:PROMPT_S]
      @prompt_c = pconf[:PROMPT_C]
      @prompt_n = pconf[:PROMPT_N]
      @return_format = pconf[:RETURN]
      if ai = pconf.include?(:AUTO_INDENT)
	@auto_indent_mode = ai
      else
	@auto_indent_mode = IRB.conf[:AUTO_INDENT]
      end
    end
    
    def inspect?
      @inspect_mode.nil? or @inspect_mode
    end

    def file_input?
      @io.class == FileInputMethod
    end

    def inspect_mode=(opt)
      if opt
	@inspect_mode = opt
      else
	@inspect_mode = !@inspect_mode
      end
      print "Switch to#{unless @inspect_mode; ' non';end} inspect mode.\n" if verbose?
      @inspect_mode
    end

    def use_readline=(opt)
      @use_readline = opt
      print "use readline module\n" if @use_readline
    end

    def debug_level=(value)
      @debug_level = value
      RubyLex.debug_level = value
      SLex.debug_level = value
    end

    def debug?
      @debug_level > 0
    end

    def evaluate(line, line_no)
      @line_no = line_no
      set_last_value(@workspace.evaluate(self, line, irb_path, line_no))
#      @workspace.evaluate("_ = IRB.conf[:MAIN_CONTEXT]._")
#      @_ = @workspace.evaluate(line, irb_path, line_no)
    end

    alias __exit__ exit
    def exit(ret = 0)
      IRB.irb_exit(@irb, ret)
    end

    NOPRINTING_IVARS = ["@last_value"]
    NO_INSPECTING_IVARS = ["@irb", "@io"]
    IDNAME_IVARS = ["@prompt_mode"]

    alias __inspect__ inspect
    def inspect
      array = []
      for ivar in instance_variables.sort{|e1, e2| e1 <=> e2}
	name = ivar.sub(/^@(.*)$/){$1}
	val = instance_eval(ivar)
	case ivar
	when *NOPRINTING_IVARS
	  array.push format("conf.%s=%s", name, "...")
	when *NO_INSPECTING_IVARS
	  array.push format("conf.%s=%s", name, val.to_s)
	when *IDNAME_IVARS
	  array.push format("conf.%s=:%s", name, val.id2name)
	else
	  array.push format("conf.%s=%s", name, val.inspect)
	end
      end
      array.join("\n")
    end
    alias __to_s__ to_s
    alias to_s inspect
  end
end
PK     jZ\DmU  U    irb/ruby-lex.rbnu [        #
#   irb/ruby-lex.rb - ruby lexcal analyzer
#   	$Release Version: 0.9.5$
#   	$Revision: 16857 $
#   	$Date: 2008-06-06 17:05:24 +0900 (Fri, 06 Jun 2008) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

require "e2mmap"
require "irb/slex"
require "irb/ruby-token"

class RubyLex
  @RCS_ID='-$Id: ruby-lex.rb 16857 2008-06-06 08:05:24Z knu $-'

  extend Exception2MessageMapper
  def_exception(:AlreadyDefinedToken, "Already defined token(%s)")
  def_exception(:TkReading2TokenNoKey, "key nothing(key='%s')")
  def_exception(:TkSymbol2TokenNoKey, "key nothing(key='%s')")
  def_exception(:TkReading2TokenDuplicateError, 
		"key duplicate(token_n='%s', key='%s')")
  def_exception(:SyntaxError, "%s")

  def_exception(:TerminateLineInput, "Terminate Line Input")
  
  include RubyToken

  class << self
    attr_accessor :debug_level
    def debug?
      @debug_level > 0
    end
  end
  @debug_level = 0

  def initialize
    lex_init
    set_input(STDIN)

    @seek = 0
    @exp_line_no = @line_no = 1
    @base_char_no = 0
    @char_no = 0
    @rests = []
    @readed = []
    @here_readed = []

    @indent = 0
    @indent_stack = []
    @lex_state = EXPR_BEG
    @space_seen = false
    @here_header = false
    
    @continue = false
    @line = ""

    @skip_space = false
    @readed_auto_clean_up = false
    @exception_on_syntax_error = true

    @prompt = nil
  end

  attr_accessor :skip_space
  attr_accessor :readed_auto_clean_up
  attr_accessor :exception_on_syntax_error

  attr_reader :seek
  attr_reader :char_no
  attr_reader :line_no
  attr_reader :indent

  # io functions
  def set_input(io, p = nil, &block)
    @io = io
    if p.respond_to?(:call)
      @input = p
    elsif block_given?
      @input = block
    else
      @input = Proc.new{@io.gets}
    end
  end

  def get_readed
    if idx = @readed.reverse.index("\n")
      @base_char_no = idx
    else
      @base_char_no += @readed.size
    end
    
    readed = @readed.join("")
    @readed = []
    readed
  end

  def getc
    while @rests.empty?
#      return nil unless buf_input
      @rests.push nil unless buf_input
    end
    c = @rests.shift
    if @here_header
      @here_readed.push c
    else
      @readed.push c
    end
    @seek += 1
    if c == "\n"
      @line_no += 1 
      @char_no = 0
    else
      @char_no += 1
    end
    c
  end

  def gets
    l = ""
    while c = getc
      l.concat(c)
      break if c == "\n"
    end
    return nil if l == "" and c.nil?
    l
  end

  def eof?
    @io.eof?
  end

  def getc_of_rests
    if @rests.empty?
      nil
    else
      getc
    end
  end

  def ungetc(c = nil)
    if @here_readed.empty?
      c2 = @readed.pop
    else
      c2 = @here_readed.pop
    end
    c = c2 unless c
    @rests.unshift c #c = 
      @seek -= 1
    if c == "\n"
      @line_no -= 1 
      if idx = @readed.reverse.index("\n")
	@char_no = @readed.size - idx
      else
	@char_no = @base_char_no + @readed.size
      end
    else
      @char_no -= 1
    end
  end

  def peek_equal?(str)
    chrs = str.split(//)
    until @rests.size >= chrs.size
      return false unless buf_input
    end
    @rests[0, chrs.size] == chrs
  end

  def peek_match?(regexp)
    while @rests.empty?
      return false unless buf_input
    end
    regexp =~ @rests.join("")
  end

  def peek(i = 0)
    while @rests.size <= i
      return nil unless buf_input
    end
    @rests[i]
  end

  def buf_input
    prompt
    line = @input.call
    return nil unless line
    @rests.concat line.split(//)
    true
  end
  private :buf_input

  def set_prompt(p = nil, &block)
    p = block if block_given?
    if p.respond_to?(:call)
      @prompt = p
    else
      @prompt = Proc.new{print p}
    end
  end

  def prompt
    if @prompt
      @prompt.call(@ltype, @indent, @continue, @line_no)
    end
  end

  def initialize_input
    @ltype = nil
    @quoted = nil
    @indent = 0
    @indent_stack = []
    @lex_state = EXPR_BEG
    @space_seen = false
    @here_header = false
    
    @continue = false
    prompt

    @line = ""
    @exp_line_no = @line_no
  end
  
  def each_top_level_statement
    initialize_input
    catch(:TERM_INPUT) do
      loop do
	begin
	  @continue = false
	  prompt
	  unless l = lex
	    throw :TERM_INPUT if @line == ''
	  else
	    #p l
	    @line.concat l
	    if @ltype or @continue or @indent > 0
	      next
	    end
	  end
	  if @line != "\n"
	    yield @line, @exp_line_no
	  end
	  break unless l
	  @line = ''
	  @exp_line_no = @line_no

	  @indent = 0
	  @indent_stack = []
	  prompt
	rescue TerminateLineInput
	  initialize_input
	  prompt
	  get_readed
	end
      end
    end
  end

  def lex
    until (((tk = token).kind_of?(TkNL) || tk.kind_of?(TkEND_OF_SCRIPT)) &&
	     !@continue or
	     tk.nil?)
      #p tk
      #p @lex_state
      #p self
    end
    line = get_readed
    #      print self.inspect
    if line == "" and tk.kind_of?(TkEND_OF_SCRIPT) || tk.nil?
      nil
    else
      line
    end
  end

  def token
    #      require "tracer"
    #      Tracer.on
    @prev_seek = @seek
    @prev_line_no = @line_no
    @prev_char_no = @char_no
    begin
      begin
	tk = @OP.match(self)
	@space_seen = tk.kind_of?(TkSPACE)
      rescue SyntaxError
	raise if @exception_on_syntax_error
	tk = TkError.new(@seek, @line_no, @char_no)
      end
    end while @skip_space and tk.kind_of?(TkSPACE)
    if @readed_auto_clean_up
      get_readed
    end
    #      Tracer.off
    tk
  end
  
  ENINDENT_CLAUSE = [
    "case", "class", "def", "do", "for", "if",
    "module", "unless", "until", "while", "begin" #, "when"
  ]
  DEINDENT_CLAUSE = ["end" #, "when"
  ]

  PERCENT_LTYPE = {
    "q" => "\'",
    "Q" => "\"",
    "x" => "\`",
    "r" => "/",
    "w" => "]",
    "W" => "]",
    "s" => ":"
  }
  
  PERCENT_PAREN = {
    "{" => "}",
    "[" => "]",
    "<" => ">",
    "(" => ")"
  }

  Ltype2Token = {
    "\'" => TkSTRING,
    "\"" => TkSTRING,
    "\`" => TkXSTRING,
    "/" => TkREGEXP,
    "]" => TkDSTRING,
    ":" => TkSYMBOL
  }
  DLtype2Token = {
    "\"" => TkDSTRING,
    "\`" => TkDXSTRING,
    "/" => TkDREGEXP,
  }

  def lex_init()
    @OP = IRB::SLex.new
    @OP.def_rules("\0", "\004", "\032") do |op, io|
      Token(TkEND_OF_SCRIPT)
    end

    @OP.def_rules(" ", "\t", "\f", "\r", "\13") do |op, io|
      @space_seen = true
      while getc =~ /[ \t\f\r\13]/; end
      ungetc
      Token(TkSPACE)
    end

    @OP.def_rule("#") do |op, io|
      identify_comment
    end

    @OP.def_rule("=begin",
		 proc{|op, io| @prev_char_no == 0 && peek(0) =~ /\s/}) do 
      |op, io|
      @ltype = "="
      until getc == "\n"; end
      until peek_equal?("=end") && peek(4) =~ /\s/
	until getc == "\n"; end
      end
      gets
      @ltype = nil
      Token(TkRD_COMMENT)
    end

    @OP.def_rule("\n") do |op, io|
      print "\\n\n" if RubyLex.debug?
      case @lex_state
      when EXPR_BEG, EXPR_FNAME, EXPR_DOT
	@continue = true
      else
	@continue = false
	@lex_state = EXPR_BEG
	until (@indent_stack.empty? || 
	       [TkLPAREN, TkLBRACK, TkLBRACE, 
		 TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last))
	  @indent_stack.pop
	end
      end
      @here_header = false
      @here_readed = []
      Token(TkNL)
    end

    @OP.def_rules("*", "**",	
		  "=", "==", "===", 
		  "=~", "<=>",	
		  "<", "<=",
		  ">", ">=", ">>") do
      |op, io|
      case @lex_state
      when EXPR_FNAME, EXPR_DOT
	@lex_state = EXPR_ARG
      else
	@lex_state = EXPR_BEG
      end
      Token(op)
    end

    @OP.def_rules("!", "!=", "!~") do
      |op, io|
      @lex_state = EXPR_BEG
      Token(op)
    end

    @OP.def_rules("<<") do
      |op, io|
      tk = nil
      if @lex_state != EXPR_END && @lex_state != EXPR_CLASS &&
	  (@lex_state != EXPR_ARG || @space_seen)
	c = peek(0)
	if /\S/ =~ c && (/["'`]/ =~ c || /[\w_]/ =~ c || c == "-")
	  tk = identify_here_document
	end
      end
      unless tk
	tk = Token(op)
	case @lex_state
	when EXPR_FNAME, EXPR_DOT
	  @lex_state = EXPR_ARG
	else
	  @lex_state = EXPR_BEG
	end
      end
      tk
    end

    @OP.def_rules("'", '"') do
      |op, io|
      identify_string(op)
    end

    @OP.def_rules("`") do
      |op, io|
      if @lex_state == EXPR_FNAME
	@lex_state = EXPR_END
	Token(op)
      else
	identify_string(op)
      end
    end

    @OP.def_rules('?') do
      |op, io|
      if @lex_state == EXPR_END
	@lex_state = EXPR_BEG
	Token(TkQUESTION)
      else
	ch = getc
	if @lex_state == EXPR_ARG && ch =~ /\s/
	  ungetc
	  @lex_state = EXPR_BEG;
	  Token(TkQUESTION)
	else
	  if (ch == '\\') 
	    read_escape
	  end
	  @lex_state = EXPR_END
	  Token(TkINTEGER)
	end
      end
    end

    @OP.def_rules("&", "&&", "|", "||") do
      |op, io|
      @lex_state = EXPR_BEG
      Token(op)
    end
    
    @OP.def_rules("+=", "-=", "*=", "**=", 
		  "&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do
      |op, io|
      @lex_state = EXPR_BEG
      op =~ /^(.*)=$/
      Token(TkOPASGN, $1)
    end

    @OP.def_rule("+@", proc{|op, io| @lex_state == EXPR_FNAME}) do
      |op, io|
      @lex_state = EXPR_ARG
      Token(op)
    end

    @OP.def_rule("-@", proc{|op, io| @lex_state == EXPR_FNAME}) do
      |op, io|
      @lex_state = EXPR_ARG
      Token(op)
    end

    @OP.def_rules("+", "-") do
      |op, io|
      catch(:RET) do
	if @lex_state == EXPR_ARG
	  if @space_seen and peek(0) =~ /[0-9]/
	    throw :RET, identify_number
	  else
	    @lex_state = EXPR_BEG
	  end
	elsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/
	  throw :RET, identify_number
	else
	  @lex_state = EXPR_BEG
	end
	Token(op)
      end
    end

    @OP.def_rule(".") do
      |op, io|
      @lex_state = EXPR_BEG
      if peek(0) =~ /[0-9]/
	ungetc
	identify_number
      else
	# for "obj.if" etc.
	@lex_state = EXPR_DOT
	Token(TkDOT)
      end
    end

    @OP.def_rules("..", "...") do
      |op, io|
      @lex_state = EXPR_BEG
      Token(op)
    end

    lex_int2
  end
  
  def lex_int2
    @OP.def_rules("]", "}", ")") do
      |op, io|
      @lex_state = EXPR_END
      @indent -= 1
      @indent_stack.pop
      Token(op)
    end

    @OP.def_rule(":") do
      |op, io|
      if @lex_state == EXPR_END || peek(0) =~ /\s/
	@lex_state = EXPR_BEG
	Token(TkCOLON)
      else
	@lex_state = EXPR_FNAME;
	Token(TkSYMBEG)
      end
    end

    @OP.def_rule("::") do
       |op, io|
#      p @lex_state.id2name, @space_seen
      if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen
	@lex_state = EXPR_BEG
	Token(TkCOLON3)
      else
	@lex_state = EXPR_DOT
	Token(TkCOLON2)
      end
    end

    @OP.def_rule("/") do
      |op, io|
      if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
	identify_string(op)
      elsif peek(0) == '='
	getc
	@lex_state = EXPR_BEG
	Token(TkOPASGN, "/") #/)
      elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
	identify_string(op)
      else 
	@lex_state = EXPR_BEG
	Token("/") #/)
      end
    end

    @OP.def_rules("^") do
      |op, io|
      @lex_state = EXPR_BEG
      Token("^")
    end

    #       @OP.def_rules("^=") do
    # 	@lex_state = EXPR_BEG
    # 	Token(OP_ASGN, :^)
    #       end
    
    @OP.def_rules(",") do
      |op, io|
      @lex_state = EXPR_BEG
      Token(op)
    end

    @OP.def_rules(";") do
      |op, io|
      @lex_state = EXPR_BEG
      until (@indent_stack.empty? || 
	     [TkLPAREN, TkLBRACK, TkLBRACE, 
	       TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last))
	@indent_stack.pop
      end
      Token(op)
    end

    @OP.def_rule("~") do
      |op, io|
      @lex_state = EXPR_BEG
      Token("~")
    end

    @OP.def_rule("~@", proc{|op, io| @lex_state == EXPR_FNAME}) do
      |op, io|
      @lex_state = EXPR_BEG
      Token("~")
    end
    
    @OP.def_rule("(") do
      |op, io|
      @indent += 1
      if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
	@lex_state = EXPR_BEG
	tk_c = TkfLPAREN
      else
	@lex_state = EXPR_BEG
	tk_c = TkLPAREN
      end
      @indent_stack.push tk_c
      tk = Token(tk_c)
    end

    @OP.def_rule("[]", proc{|op, io| @lex_state == EXPR_FNAME}) do
      |op, io|
      @lex_state = EXPR_ARG
      Token("[]")
    end

    @OP.def_rule("[]=", proc{|op, io| @lex_state == EXPR_FNAME}) do
      |op, io|
      @lex_state = EXPR_ARG
      Token("[]=")
    end

    @OP.def_rule("[") do
      |op, io|
      @indent += 1
      if @lex_state == EXPR_FNAME
	tk_c = TkfLBRACK
      else
	if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
	  tk_c = TkLBRACK
	elsif @lex_state == EXPR_ARG && @space_seen
	  tk_c = TkLBRACK
	else
	  tk_c = TkfLBRACK
	end
	@lex_state = EXPR_BEG
      end
      @indent_stack.push tk_c
      Token(tk_c)
    end

    @OP.def_rule("{") do
      |op, io|
      @indent += 1
      if @lex_state != EXPR_END && @lex_state != EXPR_ARG
	tk_c = TkLBRACE
      else
	tk_c = TkfLBRACE
      end
      @lex_state = EXPR_BEG
      @indent_stack.push tk_c
      Token(tk_c)
    end

    @OP.def_rule('\\') do
      |op, io|
      if getc == "\n"
	@space_seen = true
	@continue = true
	Token(TkSPACE)
      else
	ungetc
	Token("\\")
      end
    end

    @OP.def_rule('%') do
      |op, io|
      if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
	identify_quotation
      elsif peek(0) == '='
	getc
	Token(TkOPASGN, :%)
      elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
	identify_quotation
      else
	@lex_state = EXPR_BEG
	Token("%") #))
      end
    end

    @OP.def_rule('$') do
      |op, io|
      identify_gvar
    end

    @OP.def_rule('@') do
      |op, io|
      if peek(0) =~ /[\w_@]/
	ungetc
	identify_identifier
      else
	Token("@")
      end
    end

    #       @OP.def_rule("def", proc{|op, io| /\s/ =~ io.peek(0)}) do 
    # 	|op, io|
    # 	@indent += 1
    # 	@lex_state = EXPR_FNAME
    # #	@lex_state = EXPR_END
    # #	until @rests[0] == "\n" or @rests[0] == ";"
    # #	  rests.shift
    # #	end
    #       end

    @OP.def_rule("") do
      |op, io|
      printf "MATCH: start %s: %s\n", op, io.inspect if RubyLex.debug?
      if peek(0) =~ /[0-9]/
	t = identify_number
      elsif peek(0) =~ /[\w_]/
	t = identify_identifier
      end
      printf "MATCH: end %s: %s\n", op, io.inspect if RubyLex.debug?
      t
    end
    
    p @OP if RubyLex.debug?
  end
  
  def identify_gvar
    @lex_state = EXPR_END
    
    case ch = getc
    when /[~_*$?!@\/\\;,=:<>".]/   #"
      Token(TkGVAR, "$" + ch)
    when "-"
      Token(TkGVAR, "$-" + getc)
    when "&", "`", "'", "+"
      Token(TkBACK_REF, "$"+ch)
    when /[1-9]/
      while getc =~ /[0-9]/; end
      ungetc
      Token(TkNTH_REF)
    when /\w/
      ungetc
      ungetc
      identify_identifier
    else 
      ungetc
      Token("$")
    end
  end
  
  def identify_identifier
    token = ""
    if peek(0) =~ /[$@]/
      token.concat(c = getc)
      if c == "@" and peek(0) == "@"
	token.concat getc
      end
    end

    while (ch = getc) =~ /\w|_/
      print ":", ch, ":" if RubyLex.debug?
      token.concat ch
    end
    ungetc
    
    if (ch == "!" || ch == "?") && token[0,1] =~ /\w/ && peek(0) != "="
      token.concat getc
    end

    # almost fix token

    case token
    when /^\$/
      return Token(TkGVAR, token)
    when /^\@\@/
      @lex_state = EXPR_END
      # p Token(TkCVAR, token)
      return Token(TkCVAR, token)
    when /^\@/
      @lex_state = EXPR_END
      return Token(TkIVAR, token)
    end
    
    if @lex_state != EXPR_DOT
      print token, "\n" if RubyLex.debug?

      token_c, *trans = TkReading2Token[token]
      if token_c
	# reserved word?

	if (@lex_state != EXPR_BEG &&
	    @lex_state != EXPR_FNAME &&
	    trans[1])
	  # modifiers
	  token_c = TkSymbol2Token[trans[1]]
	  @lex_state = trans[0]
	else
	  if @lex_state != EXPR_FNAME
	    if ENINDENT_CLAUSE.include?(token)
	      # check for ``class = val'' etc.
	      valid = true
	      case token
	      when "class"
		valid = false unless peek_match?(/^\s*(<<|\w|::)/)
	      when "def"
		valid = false if peek_match?(/^\s*(([+-\/*&\|^]|<<|>>|\|\||\&\&)=|\&\&|\|\|)/)
	      when "do"
		valid = false if peek_match?(/^\s*([+-\/*]?=|\*|<|>|\&)/)
	      when *ENINDENT_CLAUSE
		valid = false if peek_match?(/^\s*([+-\/*]?=|\*|<|>|\&|\|)/)
	      else
		# no nothing
	      end
	      if valid
		if token == "do"
		  if ![TkFOR, TkWHILE, TkUNTIL].include?(@indent_stack.last)
		    @indent += 1
		    @indent_stack.push token_c
		  end
		else
		  @indent += 1
		  @indent_stack.push token_c
		end
#		p @indent_stack
	      end

	    elsif DEINDENT_CLAUSE.include?(token)
	      @indent -= 1
	      @indent_stack.pop
	    end
	    @lex_state = trans[0]
	  else
	    @lex_state = EXPR_END
	  end
	end
	return Token(token_c, token)
      end
    end

    if @lex_state == EXPR_FNAME
      @lex_state = EXPR_END
      if peek(0) == '='
	token.concat getc
      end
    elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT
      @lex_state = EXPR_ARG
    else
      @lex_state = EXPR_END
    end

    if token[0, 1] =~ /[A-Z]/
      return Token(TkCONSTANT, token)
    elsif token[token.size - 1, 1] =~ /[!?]/
      return Token(TkFID, token)
    else
      return Token(TkIDENTIFIER, token)
    end
  end

  def identify_here_document
    ch = getc
#    if lt = PERCENT_LTYPE[ch]
    if ch == "-"
      ch = getc
      indent = true
    end
    if /['"`]/ =~ ch
      lt = ch
      quoted = ""
      while (c = getc) && c != lt
	quoted.concat c
      end
    else
      lt = '"'
      quoted = ch.dup
      while (c = getc) && c =~ /\w/
	quoted.concat c
      end
      ungetc
    end

    ltback, @ltype = @ltype, lt
    reserve = []
    while ch = getc
      reserve.push ch
      if ch == "\\"
	reserve.push ch = getc
      elsif ch == "\n"
	break
      end
    end

    @here_header = false
    while l = gets
      l = l.sub(/(:?\r)?\n\z/, '')
      if (indent ? l.strip : l) == quoted
 	break
      end
    end

    @here_header = true
    @here_readed.concat reserve
    while ch = reserve.pop
      ungetc ch
    end

    @ltype = ltback
    @lex_state = EXPR_END
    Token(Ltype2Token[lt])
  end
  
  def identify_quotation
    ch = getc
    if lt = PERCENT_LTYPE[ch]
      ch = getc
    elsif ch =~ /\W/
      lt = "\""
    else
      RubyLex.fail SyntaxError, "unknown type of %string"
    end
#     if ch !~ /\W/
#       ungetc
#       next
#     end
    #@ltype = lt
    @quoted = ch unless @quoted = PERCENT_PAREN[ch]
    identify_string(lt, @quoted)
  end

  def identify_number
    @lex_state = EXPR_END

    if peek(0) == "0" && peek(1) !~ /[.eE]/
      getc
      case peek(0)
      when /[xX]/
	ch = getc
	match = /[0-9a-fA-F_]/
      when /[bB]/
	ch = getc
	match = /[01_]/
      when /[oO]/
	ch = getc
	match = /[0-7_]/
      when /[dD]/
	ch = getc
	match = /[0-9_]/
      when /[0-7]/
	match = /[0-7_]/
      when /[89]/
	RubyLex.fail SyntaxError, "Illegal octal digit"
      else 
	return Token(TkINTEGER)
      end
      
      len0 = true
      non_digit = false
      while ch = getc
	if match =~ ch
	  if ch == "_"
	    if non_digit
	      RubyLex.fail SyntaxError, "trailing `#{ch}' in number"
	    else
	      non_digit = ch
	    end
	  else
	    non_digit = false
	    len0 = false
	  end
	else
	  ungetc
	  if len0
	    RubyLex.fail SyntaxError, "numeric literal without digits"
	  end
	  if non_digit
	    RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number"
	  end
	  break
	end
      end
      return Token(TkINTEGER)
    end
    
    type = TkINTEGER
    allow_point = true
    allow_e = true
    non_digit = false
    while ch = getc
      case ch
      when /[0-9]/
	non_digit = false
      when "_"
	non_digit = ch
      when allow_point && "."
	if non_digit
	  RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number"
	end
	type = TkFLOAT
	if peek(0) !~ /[0-9]/
	  type = TkINTEGER
	  ungetc
	  break
	end
	allow_point = false
      when allow_e && "e", allow_e && "E"
	if non_digit
	  RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number"
	end
	type = TkFLOAT
	if peek(0) =~ /[+-]/
	  getc
	end
	allow_e = false
	allow_point = false
	non_digit = ch
      else
	if non_digit
	  RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number"
	end
	ungetc
	break
      end
    end
    Token(type)
  end
  
  def identify_string(ltype, quoted = ltype)
    @ltype = ltype
    @quoted = quoted
    subtype = nil
    begin
      nest = 0
      while ch = getc
	if @quoted == ch and nest == 0
	  break
	elsif @ltype != "'" && @ltype != "]" && @ltype != ":" and ch == "#"
	  subtype = true
	elsif ch == '\\' #'
	  read_escape
	end
	if PERCENT_PAREN.values.include?(@quoted) 
	  if PERCENT_PAREN[ch] == @quoted
	    nest += 1
	  elsif ch == @quoted
	    nest -= 1
	  end
	end
      end
      if @ltype == "/"
	if peek(0) =~ /i|m|x|o|e|s|u|n/
	  getc
	end
      end
      if subtype
	Token(DLtype2Token[ltype])
      else
	Token(Ltype2Token[ltype])
      end
    ensure
      @ltype = nil
      @quoted = nil
      @lex_state = EXPR_END
    end
  end
  
  def identify_comment
    @ltype = "#"

    while ch = getc
#      if ch == "\\" #"
#	read_escape
#      end
      if ch == "\n"
	@ltype = nil
	ungetc
	break
      end
    end
    return Token(TkCOMMENT)
  end
  
  def read_escape
    case ch = getc
    when "\n", "\r", "\f"
    when "\\", "n", "t", "r", "f", "v", "a", "e", "b", "s" #"
    when /[0-7]/
      ungetc ch
      3.times do
	case ch = getc
	when /[0-7]/
	when nil
	  break
	else
	  ungetc
	  break
	end
      end
      
    when "x"
      2.times do
	case ch = getc
	when /[0-9a-fA-F]/
	when nil
	  break
	else
	  ungetc
	  break
	end
      end

    when "M"
      if (ch = getc) != '-'
	ungetc
      else
	if (ch = getc) == "\\" #"
	  read_escape
	end
      end

    when "C", "c" #, "^"
      if ch == "C" and (ch = getc) != "-"
	ungetc
      elsif (ch = getc) == "\\" #"
	read_escape
      end
    else
      # other characters 
    end
  end
end
PK     kZ\6|  |    irb/locale.rbnu [        #
#   irb/locale.rb - internationalization module
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

autoload :Kconv, "kconv"

module IRB
  class Locale
    @RCS_ID='-$Id: locale.rb 11708 2007-02-12 23:01:19Z shyouhei $-'

    JPDefaultLocale = "ja"
    LOCALE_DIR = "/lc/"

    def initialize(locale = nil)
      @lang = locale || ENV["IRB_LANG"] || ENV["LC_MESSAGES"] || ENV["LC_ALL"] || ENV["LANG"] || "C" 
    end

    attr_reader :lang

    def lc2kconv(lang)
      case lang
      when "ja_JP.ujis", "ja_JP.euc", "ja_JP.eucJP"
        Kconv::EUC
      when "ja_JP.sjis", "ja_JP.SJIS"
        Kconv::SJIS
      when /ja_JP.utf-?8/i
	Kconv::UTF8
      end
    end
    private :lc2kconv

    def String(mes)
      mes = super(mes)
      case @lang
      when /^ja/
	mes = Kconv::kconv(mes, lc2kconv(@lang))
      else
	mes
      end
      mes
    end

    def format(*opts)
      String(super(*opts))
    end

    def gets(*rs)
      String(super(*rs))
    end

    def readline(*rs)
      String(super(*rs))
    end

    def print(*opts)
      ary = opts.collect{|opt| String(opt)}
      super(*ary)
    end

    def printf(*opts)
      s = format(*opts)
      print s
    end

    def puts(*opts)
      ary = opts.collect{|opt| String(opt)}
      super(*ary)
    end

    def require(file, priv = nil)
      rex = Regexp.new("lc/#{Regexp.quote(file)}\.(so|o|sl|rb)?")
      return false if $".find{|f| f =~ rex}

      case file
      when /\.rb$/
	begin
	  load(file, priv)
	  $".push file
	  return true
	rescue LoadError
	end
      when /\.(so|o|sl)$/
	return super
      end

      begin
	load(f = file + ".rb")
	$".push f  #"
	return true
      rescue LoadError
	return ruby_require(file)
      end
    end

    alias toplevel_load load
    
    def load(file, priv=nil)
      dir = File.dirname(file)
      dir = "" if dir == "."
      base = File.basename(file)

      if /^ja(_JP)?$/ =~ @lang
 	back, @lang = @lang, "C"
      end
      begin
	if dir[0] == ?/ #/
	  lc_path = search_file(dir, base)
	  return real_load(lc_path, priv) if lc_path
	end
	
	for path in $:
	  lc_path = search_file(path + "/" + dir, base)
	  return real_load(lc_path, priv) if lc_path
	end
      ensure
	@lang = back if back
      end
      raise LoadError, "No such file to load -- #{file}"
    end 

    def real_load(path, priv)
      src = self.String(File.read(path))
      if priv
	eval("self", TOPLEVEL_BINDING).extend(Module.new {eval(src, nil, path)})
      else
	eval(src, TOPLEVEL_BINDING, path)
      end
    end
    private :real_load

    def find(file , paths = $:)
      dir = File.dirname(file)
      dir = "" if dir == "."
      base = File.basename(file)
      if dir[0] == ?/ #/
	  return lc_path = search_file(dir, base)
      else
	for path in $:
	  if lc_path = search_file(path + "/" + dir, base)
	    return lc_path
	  end
	end
      end
      nil
    end

    def search_file(path, file)
      if File.exist?(p1 = path + lc_path(file, "C"))
	if File.exist?(p2 = path + lc_path(file))
	  return p2
	else
	end
	return p1
      else
      end
      nil
    end
    private :search_file

    def lc_path(file = "", lc = @lang)
      case lc
      when "C"
	LOCALE_DIR + file
      when /^ja/
	LOCALE_DIR + "ja/" + file
      else
	LOCALE_DIR + @lang + "/" + file
      end
    end
    private :lc_path
  end
end




PK     kZ\-  -    irb/output-method.rbnu [        #
#   output-method.rb - optput methods used by irb 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

require "e2mmap"

module IRB
  # OutputMethod
  #   StdioOutputMethod

  class OutputMethod
    @RCS_ID='-$Id: output-method.rb 11708 2007-02-12 23:01:19Z shyouhei $-'

    def print(*opts)
      IRB.fail NotImplementError, "print"
    end

    def printn(*opts)
      print opts.join(" "), "\n"
    end

    # extend printf
    def printf(format, *opts)
      if /(%*)%I/ =~ format
	format, opts = parse_printf_format(format, opts)
      end
      print sprintf(format, *opts)
    end

    # %
    # <ե饰>  [#0- +]
    # <Ǿե> (\*|\*[1-9][0-9]*\$|[1-9][0-9]*)
    # <>.(\*|\*[1-9][0-9]*\$|[1-9][0-9]*|)?
    # #<Ĺʸ>(hh|h|l|ll|L|q|j|z|t)
    # <Ѵʸ>[diouxXeEfgGcsb%] 
    def parse_printf_format(format, opts)
      return format, opts if $1.size % 2 == 1
    end

    def foo(format)
      pos = 0
      inspects = []
      format.scan(/%[#0\-+ ]?(\*(?=[^0-9])|\*[1-9][0-9]*\$|[1-9][0-9]*(?=[^0-9]))?(\.(\*(?=[^0-9])|\*[1-9][0-9]*\$|[1-9][0-9]*(?=[^0-9])))?(([1-9][0-9]*\$)*)([diouxXeEfgGcsb%])/) {|f, p, pp, pos, new_pos, c|
	puts [f, p, pp, pos, new_pos, c].join("!")
	pos = new_pos if new_pos
	if c == "I"
	  inspects.push pos.to_i 
	  (f||"")+(p||"")+(pp||"")+(pos||"")+"s"
	else
	  $&
	end
      }
    end

    def puts(*objs)
      for obj in objs
	print(*obj)
	print "\n"
      end
    end

    def pp(*objs)
      puts(*objs.collect{|obj| obj.inspect})
    end

    def ppx(prefix, *objs)
      puts(*objs.collect{|obj| prefix+obj.inspect})
    end

  end

  class StdioOutputMethod<OutputMethod
    def print(*opts)
      STDOUT.print(*opts)
    end
  end
end
PK     lZ\~W      irb/extend-command.rbnu [        #
#   irb/extend-command.rb - irb extend command 
#   	$Release Version: 0.9.5$
#   	$Revision: 25814 $
#   	$Date: 2009-11-17 15:51:29 +0900 (Tue, 17 Nov 2009) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
module IRB
  #
  # IRB extended command
  #
  module ExtendCommandBundle
    EXCB = ExtendCommandBundle

    NO_OVERRIDE = 0
    OVERRIDE_PRIVATE_ONLY = 0x01
    OVERRIDE_ALL = 0x02

    def irb_exit(ret = 0)
      irb_context.exit(ret)
    end

    def irb_context
      IRB.CurrentContext
    end

    @ALIASES = [
      [:context, :irb_context, NO_OVERRIDE],
      [:conf, :irb_context, NO_OVERRIDE],
      [:irb_quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
      [:exit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
      [:quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
    ]

    @EXTEND_COMMANDS = [
      [:irb_current_working_workspace, :CurrentWorkingWorkspace, "irb/cmd/chws",
	[:irb_print_working_workspace, OVERRIDE_ALL],
	[:irb_cwws, OVERRIDE_ALL],
	[:irb_pwws, OVERRIDE_ALL],
#	[:irb_cww, OVERRIDE_ALL],
#	[:irb_pww, OVERRIDE_ALL],
	[:cwws, NO_OVERRIDE],
	[:pwws, NO_OVERRIDE],
#	[:cww, NO_OVERRIDE],
#	[:pww, NO_OVERRIDE],
	[:irb_current_working_binding, OVERRIDE_ALL],
	[:irb_print_working_binding, OVERRIDE_ALL],
	[:irb_cwb, OVERRIDE_ALL],
	[:irb_pwb, OVERRIDE_ALL],
#	[:cwb, NO_OVERRIDE],
#	[:pwb, NO_OVERRIDE]
      ],
      [:irb_change_workspace, :ChangeWorkspace, "irb/cmd/chws",
	[:irb_chws, OVERRIDE_ALL],
#	[:irb_chw, OVERRIDE_ALL],
	[:irb_cws, OVERRIDE_ALL],
#	[:irb_cw, OVERRIDE_ALL],
	[:chws, NO_OVERRIDE],
#	[:chw, NO_OVERRIDE],
	[:cws, NO_OVERRIDE],
#	[:cw, NO_OVERRIDE],
	[:irb_change_binding, OVERRIDE_ALL],
	[:irb_cb, OVERRIDE_ALL],
	[:cb, NO_OVERRIDE]],

      [:irb_workspaces, :Workspaces, "irb/cmd/pushws",
	[:workspaces, NO_OVERRIDE],
	[:irb_bindings, OVERRIDE_ALL],
	[:bindings, NO_OVERRIDE]],
      [:irb_push_workspace, :PushWorkspace, "irb/cmd/pushws",
	[:irb_pushws, OVERRIDE_ALL],
#	[:irb_pushw, OVERRIDE_ALL],
	[:pushws, NO_OVERRIDE],
#	[:pushw, NO_OVERRIDE],
	[:irb_push_binding, OVERRIDE_ALL],
	[:irb_pushb, OVERRIDE_ALL],
	[:pushb, NO_OVERRIDE]],
      [:irb_pop_workspace, :PopWorkspace, "irb/cmd/pushws",
	[:irb_popws, OVERRIDE_ALL],
#	[:irb_popw, OVERRIDE_ALL],
	[:popws, NO_OVERRIDE],
#	[:popw, NO_OVERRIDE],
	[:irb_pop_binding, OVERRIDE_ALL],
	[:irb_popb, OVERRIDE_ALL],
	[:popb, NO_OVERRIDE]],

      [:irb_load, :Load, "irb/cmd/load"],
      [:irb_require, :Require, "irb/cmd/load"],
      [:irb_source, :Source, "irb/cmd/load", 
	[:source, NO_OVERRIDE]],

      [:irb, :IrbCommand, "irb/cmd/subirb"],
      [:irb_jobs, :Jobs, "irb/cmd/subirb", 
	[:jobs, NO_OVERRIDE]],
      [:irb_fg, :Foreground, "irb/cmd/subirb", 
	[:fg, NO_OVERRIDE]],
      [:irb_kill, :Kill, "irb/cmd/subirb", 
	[:kill, OVERRIDE_PRIVATE_ONLY]],

      [:irb_help, :Help, "irb/cmd/help",
        [:help, NO_OVERRIDE]],

    ]

    def self.install_extend_commands
      for args in @EXTEND_COMMANDS
	def_extend_command(*args)
      end
    end

    # aliases = [commands_alias, flag], ...
    def self.def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases)
      case cmd_class
      when Symbol
	cmd_class = cmd_class.id2name
      when String
      when Class
	cmd_class = cmd_class.name
      end

      if load_file
	eval %[
	  def #{cmd_name}(*opts, &b)
	    require "#{load_file}"
	    arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
	    args = (1..arity.abs).map {|i| "arg" + i.to_s }
	    args << "*opts" if arity < 0
	    args << "&block"
	    args = args.join(", ")
	    eval %[
	      def #{cmd_name}(\#{args})
		ExtendCommand::#{cmd_class}.execute(irb_context, \#{args})
	      end
	    ]
	    send :#{cmd_name}, *opts, &b
	  end
	]
      else
	eval %[
	  def #{cmd_name}(*opts, &b)
	    ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b)
	  end
	]
      end

      for ali, flag in aliases
	@ALIASES.push [ali, cmd_name, flag]
      end
    end

    # override = {NO_OVERRIDE, OVERRIDE_PRIVATE_ONLY, OVERRIDE_ALL}
    def install_alias_method(to, from, override = NO_OVERRIDE)
      to = to.id2name unless to.kind_of?(String)
      from = from.id2name unless from.kind_of?(String)

      if override == OVERRIDE_ALL or
	  (override == OVERRIDE_PRIVATE_ONLY) && !respond_to?(to) or
	  (override == NO_OVERRIDE) &&  !respond_to?(to, true)
	target = self
	(class<<self;self;end).instance_eval{
	  if target.respond_to?(to, true) && 
	      !target.respond_to?(EXCB.irb_original_method_name(to), true)
	    alias_method(EXCB.irb_original_method_name(to), to) 
	  end
	  alias_method to, from
	}
      else
	print "irb: warn: can't alias #{to} from #{from}.\n"
      end
    end

    def self.irb_original_method_name(method_name)
      "irb_" + method_name + "_org"
    end

    def self.extend_object(obj)
      unless (class<<obj;ancestors;end).include?(EXCB)
	super
	for ali, com, flg in @ALIASES
	  obj.install_alias_method(ali, com, flg)
	end
      end
    end

    install_extend_commands
  end

  # extension support for Context
  module ContextExtender
    CE = ContextExtender

    @EXTEND_COMMANDS = [
      [:eval_history=, "irb/ext/history.rb"],
      [:use_tracer=, "irb/ext/tracer.rb"],
      [:math_mode=, "irb/ext/math-mode.rb"],
      [:use_loader=, "irb/ext/use-loader.rb"],
      [:save_history=, "irb/ext/save-history.rb"],
    ]

    def self.install_extend_commands
      for args in @EXTEND_COMMANDS
	def_extend_command(*args)
      end
    end

    def self.def_extend_command(cmd_name, load_file, *aliases)
      Context.module_eval %[
        def #{cmd_name}(*opts, &b)
	  Context.module_eval {remove_method(:#{cmd_name})}
	  require "#{load_file}"
	  send :#{cmd_name}, *opts, &b
	end
	for ali in aliases
	  alias_method ali, cmd_name
	end
      ]
    end

    CE.install_extend_commands
  end

  module MethodExtender
    def def_pre_proc(base_method, extend_method)
      base_method = base_method.to_s
      extend_method = extend_method.to_s

      alias_name = new_alias_name(base_method)
      module_eval %[
        alias_method alias_name, base_method
        def #{base_method}(*opts)
	  send :#{extend_method}, *opts
	  send :#{alias_name}, *opts
	end
      ]
    end

    def def_post_proc(base_method, extend_method)
      base_method = base_method.to_s
      extend_method = extend_method.to_s

      alias_name = new_alias_name(base_method)
      module_eval %[
        alias_method alias_name, base_method
        def #{base_method}(*opts)
	  send :#{alias_name}, *opts
	  send :#{extend_method}, *opts
	end
      ]
    end

    # return #{prefix}#{name}#{postfix}<num>
    def new_alias_name(name, prefix = "__alias_of__", postfix = "__")
      base_name = "#{prefix}#{name}#{postfix}"
      all_methods = instance_methods(true) + private_instance_methods(true)
      same_methods = all_methods.grep(/^#{Regexp.quote(base_name)}[0-9]*$/)
      return base_name if same_methods.empty?
      no = same_methods.size
      while !same_methods.include?(alias_name = base_name + no)
	no += 1
      end
      alias_name
    end
  end
end

PK     mZ\L(E  E    irb/slex.rbnu [        #
#   irb/slex.rb - simple lex analyzer
#   	$Release Version: 0.9.5$
#   	$Revision: 16857 $
#   	$Date: 2008-06-06 17:05:24 +0900 (Fri, 06 Jun 2008) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

require "e2mmap"
require "irb/notifier"

module IRB
  class SLex
    @RCS_ID='-$Id: slex.rb 16857 2008-06-06 08:05:24Z knu $-'

    extend Exception2MessageMapper
    def_exception :ErrNodeNothing, "node nothing"
    def_exception :ErrNodeAlreadyExists, "node already exists"

    DOUT = Notifier::def_notifier("SLex::")
    D_WARN = DOUT::def_notifier(1, "Warn: ")
    D_DEBUG = DOUT::def_notifier(2, "Debug: ")
    D_DETAIL = DOUT::def_notifier(4, "Detail: ")
    
    DOUT.level = Notifier::D_NOMSG

    def initialize
      @head = Node.new("")
    end
    
    def def_rule(token, preproc = nil, postproc = nil, &block)
      D_DETAIL.pp token

      postproc = block if block_given?
      node = create(token, preproc, postproc)
    end
    
    def def_rules(*tokens, &block)
      if block_given?
	p = block
      end
      for token in tokens
	def_rule(token, nil, p)
      end
    end
    
    def preproc(token, proc)
      node = search(token)
      node.preproc=proc
    end
    
    #$BMW%A%'%C%/(B? 
    def postproc(token)
      node = search(token, proc)
      node.postproc=proc
    end
    
    def search(token)
      @head.search(token.split(//))
    end

    def create(token, preproc = nil, postproc = nil)
      @head.create_subnode(token.split(//), preproc, postproc)
    end
    
    def match(token)
      case token
      when Array
      when String
	return match(token.split(//))
      else
	return @head.match_io(token)
      end
      ret = @head.match(token)
      D_DETAIL.exec_if{D_DEATIL.printf "match end: %s:%s\n", ret, token.inspect}
      ret
    end
    
    def inspect
      format("<SLex: @head = %s>", @head.inspect)
    end

    #----------------------------------------------------------------------
    #
    #   class Node - 
    #
    #----------------------------------------------------------------------
    class Node
      # if postproc is nil, this node is an abstract node.
      # if postproc is non-nil, this node is a real node.
      def initialize(preproc = nil, postproc = nil)
	@Tree = {}
	@preproc = preproc
	@postproc = postproc
      end

      attr_accessor :preproc
      attr_accessor :postproc
      
      def search(chrs, opt = nil)
	return self if chrs.empty?
	ch = chrs.shift
	if node = @Tree[ch]
	  node.search(chrs, opt)
	else
	  if opt
	    chrs.unshift ch
	    self.create_subnode(chrs)
	  else
	    SLex.fail ErrNodeNothing
	  end
	end
      end
      
      def create_subnode(chrs, preproc = nil, postproc = nil)
	if chrs.empty?
	  if @postproc
	    D_DETAIL.pp node
	    SLex.fail ErrNodeAlreadyExists
	  else
	    D_DEBUG.puts "change abstract node to real node."
	    @preproc = preproc
	    @postproc = postproc
	  end
	  return self
	end
	
	ch = chrs.shift
	if node = @Tree[ch]
	  if chrs.empty?
	    if node.postproc
	      DebugLogger.pp node
	      DebugLogger.pp self
	      DebugLogger.pp ch
	      DebugLogger.pp chrs
	      SLex.fail ErrNodeAlreadyExists
	    else
	      D_WARN.puts "change abstract node to real node"
	      node.preproc = preproc
	      node.postproc = postproc
	    end
	  else
	    node.create_subnode(chrs, preproc, postproc)
	  end
	else
	  if chrs.empty?
	    node = Node.new(preproc, postproc)
	  else
	    node = Node.new
	    node.create_subnode(chrs, preproc, postproc)
	  end
	  @Tree[ch] = node
	end
	node
      end

      #
      # chrs: String
      #       character array
      #       io must have getc()/ungetc(); and ungetc() must be
      #       able to be called arbitrary number of times. 
      #
      def match(chrs, op = "")
	D_DETAIL.print "match>: ", chrs, "op:", op, "\n"
	if chrs.empty?
	  if @preproc.nil? || @preproc.call(op, chrs)
	    DOUT.printf(D_DETAIL, "op1: %s\n", op)
	    @postproc.call(op, chrs)
	  else
	    nil
	  end
	else
	  ch = chrs.shift
	  if node = @Tree[ch]
	    if ret = node.match(chrs, op+ch)
	      return ret
	    else
	      chrs.unshift ch
	      if @postproc and @preproc.nil? || @preproc.call(op, chrs)
		DOUT.printf(D_DETAIL, "op2: %s\n", op.inspect)
		ret = @postproc.call(op, chrs)
		return ret
	      else
		return nil
	      end
	    end
	  else
	    chrs.unshift ch
	    if @postproc and @preproc.nil? || @preproc.call(op, chrs)
	      DOUT.printf(D_DETAIL, "op3: %s\n", op)
	      @postproc.call(op, chrs)
	      return ""
	    else
	      return nil
	    end
	  end
	end
      end

      def match_io(io, op = "")
	if op == ""
	  ch = io.getc
	  if ch == nil
	    return nil
	  end
	else
	  ch = io.getc_of_rests
	end
	if ch.nil?
	  if @preproc.nil? || @preproc.call(op, io)
	    D_DETAIL.printf("op1: %s\n", op)
	    @postproc.call(op, io)
	  else
	    nil
	  end
	else
	  if node = @Tree[ch]
	    if ret = node.match_io(io, op+ch)
	      ret
	    else
	      io.ungetc ch
	      if @postproc and @preproc.nil? || @preproc.call(op, io)
		DOUT.exec_if{D_DETAIL.printf "op2: %s\n", op.inspect}
		@postproc.call(op, io)
	      else
		nil
	      end
	    end
	  else
	    io.ungetc ch
	    if @postproc and @preproc.nil? || @preproc.call(op, io)
	      D_DETAIL.printf("op3: %s\n", op)
	      @postproc.call(op, io)
	    else
	      nil
	    end
	  end
	end
      end
    end
  end
end

SLex=IRB::SLex

if $0 == __FILE__
  #    Tracer.on
  case $1
  when "1"
    tr = SLex.new
    print "0: ", tr.inspect, "\n"
    tr.def_rule("=") {print "=\n"}
    print "1: ", tr.inspect, "\n"
    tr.def_rule("==") {print "==\n"}
    print "2: ", tr.inspect, "\n"
    
    print "case 1:\n"
    print tr.match("="), "\n"
    print "case 2:\n"
    print tr.match("=="), "\n"
    print "case 3:\n"
    print tr.match("=>"), "\n"
    
  when "2"
    tr = SLex.new
    print "0: ", tr.inspect, "\n"
    tr.def_rule("=") {print "=\n"}
    print "1: ", tr.inspect, "\n"
    tr.def_rule("==", proc{false}) {print "==\n"}
    print "2: ", tr.inspect, "\n"
    
    print "case 1:\n"
    print tr.match("="), "\n"
    print "case 2:\n"
    print tr.match("=="), "\n"
    print "case 3:\n"
    print tr.match("=>"), "\n"
  end
  exit
end

PK     nZ\.  .    irb/lc/help-messagenu [        #
#   irb/lc/help-message.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
Usage:  irb.rb [options] [programfile] [arguments]
  -f		    Suppress read of ~/.irbrc 
  -m		    Bc mode (load mathn, fraction or matrix are available)
  -d                Set $DEBUG to true (same as `ruby -d')
  -r load-module    Same as `ruby -r'
  -I path           Specify $LOAD_PATH directory
  --inspect	    Use `inspect' for output (default except for bc mode)
  --noinspect	    Don't use inspect for output
  --readline	    Use Readline extension module
  --noreadline	    Don't use Readline extension module
  --prompt prompt-mode
  --prompt-mode prompt-mode
		    Switch prompt mode. Pre-defined prompt modes are
		    `default', `simple', `xmp' and `inf-ruby'
  --inf-ruby-mode   Use prompt appropriate for inf-ruby-mode on emacs. 
		    Suppresses --readline. 
  --simple-prompt   Simple prompt mode
  --noprompt	    No prompt mode
  --tracer	    Display trace for each execution of commands.
  --back-trace-limit n
		    Display backtrace top n and tail n. The default
		    value is 16. 
  --irb_debug n	    Set internal debug level to n (not for popular use)
  -v, --version	    Print the version of irb
PK     nZ\      irb/lc/ja/help-messagenu [        #
#   irb/lc/ja/help-message.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
Usage:  irb.rb [options] [programfile] [arguments]
  -f		    ~/.irbrc $B$rFI$_9~$^$J$$(B.
  -m		    bc$B%b!<%I(B($BJ,?t(B, $B9TNs$N7W;;$,$G$-$k(B)
  -d                $DEBUG $B$r(Btrue$B$K$9$k(B(ruby -d $B$HF1$8(B)
  -r load-module    ruby -r $B$HF1$8(B.
  -I path           $LOAD_PATH $B$K(B path $B$rDI2C$9$k(B.
  --inspect	    $B7k2L=PNO$K(Binspect$B$rMQ$$$k(B(bc$B%b!<%I0J30$O%G%U%)%k%H(B). 
  --noinspect	    $B7k2L=PNO$K(Binspect$B$rMQ$$$J$$(B.
  --readline	    readline$B%i%$%V%i%j$rMxMQ$9$k(B.
  --noreadline	    readline$B%i%$%V%i%j$rMxMQ$7$J$$(B. 
  --prompt prompt-mode/--prompt-mode prompt-mode
		    $B%W%m%s%W%H%b!<%I$r@ZBX$($^$9(B. $B8=:_Dj5A$5$l$F$$$k%W(B
		    $B%m%s%W%H%b!<%I$O(B, default, simple, xmp, inf-ruby$B$,(B
		    $BMQ0U$5$l$F$$$^$9(B. 
  --inf-ruby-mode   emacs$B$N(Binf-ruby-mode$BMQ$N%W%m%s%W%HI=<($r9T$J$&(B. $BFC(B
		    $B$K;XDj$,$J$$8B$j(B, readline$B%i%$%V%i%j$O;H$o$J$/$J$k(B.
  --simple-prompt   $BHs>o$K%7%s%W%k$J%W%m%s%W%H$rMQ$$$k%b!<%I$G$9(B.
  --noprompt	    $B%W%m%s%W%HI=<($r9T$J$o$J$$(B.
  --tracer	    $B%3%^%s%I<B9T;~$K%H%l!<%9$r9T$J$&(B.
  --back-trace-limit n
		    $B%P%C%/%H%l!<%9I=<($r%P%C%/%H%l!<%9$NF,$+$i(B n, $B8e$m(B
		    $B$+$i(Bn$B$@$19T$J$&(B. $B%G%U%)%k%H$O(B16 
  --irb_debug n	    irb$B$N%G%P%C%0%G%P%C%0%l%Y%k$r(Bn$B$K@_Dj$9$k(B($BMxMQ$7$J(B
		    $B$$J}$,L5Fq$G$7$g$&(B).
  -v, --version	    irb$B$N%P!<%8%g%s$rI=<($9$k(B
PK     oZ\*O.  .    irb/lc/ja/error.rbnu [        #
#   irb/lc/ja/error.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
require "e2mmap"

module IRB
  # exceptions
  extend Exception2MessageMapper
  def_exception :UnrecognizedSwitch, '$B%9%$%C%A(B(%s)$B$,J,$j$^$;$s(B'
  def_exception :NotImplementedError, '`%s\'$B$NDj5A$,I,MW$G$9(B'
  def_exception :CantReturnToNormalMode, 'Normal$B%b!<%I$KLa$l$^$;$s(B.'
  def_exception :IllegalParameter, '$B%Q%i%a!<%?(B(%s)$B$,4V0c$C$F$$$^$9(B.'
  def_exception :IrbAlreadyDead, 'Irb$B$O4{$K;`$s$G$$$^$9(B.'
  def_exception :IrbSwitchedToCurrentThread, '$B%+%l%s%H%9%l%C%I$K@Z$jBX$o$j$^$7$?(B.'
  def_exception :NoSuchJob, '$B$=$N$h$&$J%8%g%V(B(%s)$B$O$"$j$^$;$s(B.'
  def_exception :CantShiftToMultiIrbMode, 'multi-irb mode$B$K0\$l$^$;$s(B.'
  def_exception :CantChangeBinding, '$B%P%$%s%G%#%s%0(B(%s)$B$KJQ99$G$-$^$;$s(B.'
  def_exception :UndefinedPromptMode, '$B%W%m%s%W%H%b!<%I(B(%s)$B$ODj5A$5$l$F$$$^$;$s(B.'
end
PK     oZ\nX      irb/lc/error.rbnu [        #
#   irb/lc/error.rb - 
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#
require "e2mmap"

module IRB

  # exceptions
  extend Exception2MessageMapper
  def_exception :UnrecognizedSwitch, "Unrecognized switch: %s"
  def_exception :NotImplementedError, "Need to define `%s'"
  def_exception :CantReturnToNormalMode, "Can't return to normal mode."
  def_exception :IllegalParameter, "Illegal parameter(%s)."
  def_exception :IrbAlreadyDead, "Irb is already dead."
  def_exception :IrbSwitchedToCurrentThread, "Switched to current thread."
  def_exception :NoSuchJob, "No such job(%s)."
  def_exception :CantShiftToMultiIrbMode, "Can't shift to multi irb mode."
  def_exception :CantChangeBinding, "Can't change binding to (%s)."
  def_exception :UndefinedPromptMode, "Undefined prompt mode(%s)."

end

PK     qZ\z/  /    irb/version.rbnu [        #
#   irb/version.rb - irb version definition file
#   	$Release Version: 0.9.5$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(keiju@ishitsuka.com)
#
# --
#
#   
#

module IRB
  @RELEASE_VERSION = "0.9.5"
  @LAST_UPDATE_DATE = "05/04/13"
end
PK     rZ\B      irb/frame.rbnu [        #
#   frame.rb - 
#   	$Release Version: 0.9$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#   
#

require "e2mmap"

module IRB
  class Frame
    extend Exception2MessageMapper
    def_exception :FrameOverflow, "frame overflow"
    def_exception :FrameUnderflow, "frame underflow"

    INIT_STACK_TIMES = 3
    CALL_STACK_OFFSET = 3

    def initialize
      @frames = [TOPLEVEL_BINDING] * INIT_STACK_TIMES
    end

    def trace_func(event, file, line, id, binding)
      case event
      when 'call', 'class'
	@frames.push binding
      when 'return', 'end'
	@frames.pop
      end
    end

    def top(n = 0)
      bind = @frames[-(n + CALL_STACK_OFFSET)]
      Fail FrameUnderflow unless bind
      bind
    end

    def bottom(n = 0)
      bind = @frames[n]
      Fail FrameOverflow unless bind
      bind
    end

    # singleton functions
    def Frame.bottom(n = 0)
      @backtrace.bottom(n)
    end

    def Frame.top(n = 0)
      @backtrace.top(n)
    end

    def Frame.sender
      eval "self", @backtrace.top
    end

    @backtrace = Frame.new
    set_trace_func proc{|event, file, line, id, binding, klass|
      @backtrace.trace_func(event, file, line, id, binding)
    }
  end
end
PK     rZ\fC U
  
    irb/notifier.rbnu [        #
#   notifier.rb - output methods used by irb 
#   	$Release Version: 0.9.5$
#   	$Revision: 16857 $
#   	$Date: 2008-06-06 17:05:24 +0900 (Fri, 06 Jun 2008) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#   
#

require "e2mmap"
require "irb/output-method"

module IRB
  module Notifier
    extend Exception2MessageMapper
    def_exception :ErrUndefinedNotifier, 
      "undefined notifier level: %d is specified"
    def_exception :ErrUnrecognizedLevel, 
      "unrecognized notifier level: %s is specified"

    def def_notifier(prefix = "", output_method = StdioOutputMethod.new)
      CompositeNotifier.new(prefix, output_method)
    end
    module_function :def_notifier
  
    class AbstructNotifier
      def initialize(prefix, base_notifier)
	@prefix = prefix
	@base_notifier = base_notifier
      end

      attr_reader :prefix

      def notify?
	true
      end

      def print(*opts)
	@base_notifier.print prefix, *opts if notify?
      end

      def printn(*opts)
	@base_notifier.printn prefix, *opts if notify?
      end

      def printf(format, *opts)
	@base_notifier.printf(prefix + format, *opts) if notify?
      end

      def puts(*objs)
	if notify?
	  @base_notifier.puts(*objs.collect{|obj| prefix + obj.to_s})
	end
      end

      def pp(*objs)
	if notify?
	  @base_notifier.ppx @prefix, *objs
	end
      end

      def ppx(prefix, *objs)
	if notify?
	  @base_notifier.ppx @prefix+prefix, *objs
	end
      end

      def exec_if
	yield(@base_notifier) if notify?
      end
    end

    class CompositeNotifier<AbstructNotifier
      def initialize(prefix, base_notifier)
	super

	@notifiers = [D_NOMSG]
	@level_notifier = D_NOMSG
      end

      attr_reader :notifiers

      def def_notifier(level, prefix = "")
	notifier = LeveledNotifier.new(self, level, prefix)
	@notifiers[level] = notifier
	notifier
      end

      attr_reader :level_notifier
      alias level level_notifier

      def level_notifier=(value)
	case value
	when AbstructNotifier
	  @level_notifier = value
	when Integer
	  l = @notifiers[value]
	  Notifier.Raise ErrUndefinedNotifer, value unless l
	  @level_notifier = l
	else
	  Notifier.Raise ErrUnrecognizedLevel, value unless l
	end
      end

      alias level= level_notifier=
    end

    class LeveledNotifier<AbstructNotifier
      include Comparable

      def initialize(base, level, prefix)
	super(prefix, base)
	
	@level = level
      end

      attr_reader :level

      def <=>(other)
	@level <=> other.level
      end
      
      def notify?
	@base_notifier.level >= self
      end
    end

    class NoMsgNotifier<LeveledNotifier
      def initialize
	@base_notifier = nil
	@level = 0
	@prefix = ""
      end

      def notify?
	false
      end
    end

    D_NOMSG = NoMsgNotifier.new
  end
end
PK     sZ\4q      shellwords.rbnu [        #
# shellwords.rb: Manipulates strings a la UNIX Bourne shell
#

#
# This module manipulates strings according to the word parsing rules
# of the UNIX Bourne shell.
#
# The shellwords() function was originally a port of shellwords.pl,
# but modified to conform to POSIX / SUSv3 (IEEE Std 1003.1-2001).
#
# Authors:
#   - Wakou Aoyama
#   - Akinori MUSHA <knu@iDaemons.org>
#
# Contact:
#   - Akinori MUSHA <knu@iDaemons.org> (current maintainer)
#
module Shellwords
  #
  # Splits a string into an array of tokens in the same way the UNIX
  # Bourne shell does.
  #
  #   argv = Shellwords.split('here are "two words"')
  #   argv #=> ["here", "are", "two words"]
  #
  # +String#shellsplit+ is a shorthand for this function.
  #
  #   argv = 'here are "two words"'.shellsplit
  #   argv #=> ["here", "are", "two words"]
  #
  def shellsplit(line)
    line = String.new(line) rescue
      raise(ArgumentError, "Argument must be a string")
    line.lstrip!
    words = []
    until line.empty?
      field = ''
      loop do
	if line.sub!(/\A"(([^"\\]|\\.)*)"/, '') then
	  snippet = $1.gsub(/\\(.)/, '\1')
	elsif line =~ /\A"/ then
	  raise ArgumentError, "Unmatched double quote: #{line}"
	elsif line.sub!(/\A'([^']*)'/, '') then
	  snippet = $1
	elsif line =~ /\A'/ then
	  raise ArgumentError, "Unmatched single quote: #{line}"
	elsif line.sub!(/\A\\(.)?/, '') then
	  snippet = $1 || '\\'
	elsif line.sub!(/\A([^\s\\'"]+)/, '') then
	  snippet = $1
	else
	  line.lstrip!
	  break
	end
	field.concat(snippet)
      end
      words.push(field)
    end
    words
  end

  alias shellwords shellsplit

  module_function :shellsplit, :shellwords

  class << self
    alias split shellsplit
  end

  #
  # Escapes a string so that it can be safely used in a Bourne shell
  # command line.
  #
  # Note that a resulted string should be used unquoted and is not
  # intended for use in double quotes nor in single quotes.
  #
  #   open("| grep #{Shellwords.escape(pattern)} file") { |pipe|
  #     # ...
  #   }
  #
  # +String#shellescape+ is a shorthand for this function.
  #
  #   open("| grep #{pattern.shellescape} file") { |pipe|
  #     # ...
  #   }
  #
  def shellescape(str)
    # An empty argument will be skipped, so return empty quotes.
    return "''" if str.empty?

    str = str.dup

    # Process as a single byte sequence because not all shell
    # implementations are multibyte aware.
    str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")

    # A LF cannot be escaped with a backslash because a backslash + LF
    # combo is regarded as line continuation and simply ignored.
    str.gsub!(/\n/, "'\n'")

    return str
  end

  module_function :shellescape

  class << self
    alias escape shellescape
  end

  #
  # Builds a command line string from an argument list +array+ joining
  # all elements escaped for Bourne shell and separated by a space.
  #
  #   open('|' + Shellwords.join(['grep', pattern, *files])) { |pipe|
  #     # ...
  #   }
  #
  # +Array#shelljoin+ is a shorthand for this function.
  #
  #   open('|' + ['grep', pattern, *files].shelljoin) { |pipe|
  #     # ...
  #   }
  #
  def shelljoin(array)
    array.map { |arg| shellescape(arg) }.join(' ')
  end

  module_function :shelljoin

  class << self
    alias join shelljoin
  end
end

class String
  #
  # call-seq:
  #   str.shellsplit => array
  #
  # Splits +str+ into an array of tokens in the same way the UNIX
  # Bourne shell does.  See +Shellwords::shellsplit+ for details.
  #
  def shellsplit
    Shellwords.split(self)
  end

  #
  # call-seq:
  #   str.shellescape => string
  #
  # Escapes +str+ so that it can be safely used in a Bourne shell
  # command line.  See +Shellwords::shellescape+ for details.
  #
  def shellescape
    Shellwords.escape(self)
  end
end

class Array
  #
  # call-seq:
  #   array.shelljoin => string
  #
  # Builds a command line string from an argument list +array+ joining
  # all elements escaped for Bourne shell and separated by a space.
  # See +Shellwords::shelljoin+ for details.
  #
  def shelljoin
    Shellwords.join(self)
  end
end
PK     sZ\KC̼
  
  
  weakref.rbnu [        require "delegate"

# WeakRef is a class to represent a reference to an object that is not seen by
# the tracing phase of the garbage collector.  This allows the referenced
# object to be garbage collected as if nothing is referring to it. Because
# WeakRef delegates method calls to the referenced object, it may be used in
# place of that object, i.e. it is of the same duck type.
#
# Usage:
#
#   foo = Object.new
#   foo = Object.new
#   p foo.to_s			# original's class
#   foo = WeakRef.new(foo)
#   p foo.to_s			# should be same class
#   ObjectSpace.garbage_collect
#   p foo.to_s			# should raise exception (recycled)
class WeakRef<Delegator

  # RefError is raised if an object cannot be referenced by a WeakRef.
  class RefError<StandardError
  end

  @@id_map =  {}                # obj -> [ref,...]
  @@id_rev_map =  {}            # ref -> obj
  @@final = lambda{|id|
    __old_status = Thread.critical
    Thread.critical = true
    begin
      rids = @@id_map[id]
      if rids
	for rid in rids
	  @@id_rev_map.delete(rid)
	end
	@@id_map.delete(id)
      end
      rid = @@id_rev_map[id]
      if rid
	@@id_rev_map.delete(id)
	@@id_map[rid].delete(id)
	@@id_map.delete(rid) if @@id_map[rid].empty?
      end
    ensure
      Thread.critical = __old_status
    end
  }

  # Create a new WeakRef from +orig+.
  def initialize(orig)
    super
    __setobj__(orig)
  end

  # Return the object this WeakRef references. Raises RefError if the object
  # has been garbage collected.  The object returned is the object to which
  # method calls are delegated (see Delegator).
  def __getobj__
    unless @@id_rev_map[self.__id__] == @__id
      raise RefError, "Illegal Reference - probably recycled", caller(2)
    end
    begin
      ObjectSpace._id2ref(@__id)
    rescue RangeError
      raise RefError, "Illegal Reference - probably recycled", caller(2)
    end
  end

  def __setobj__(obj)
    @__id = obj.__id__
    __old_status = Thread.critical
    begin
      Thread.critical = true
      unless @@id_rev_map.key?(self)
        ObjectSpace.define_finalizer obj, @@final
        ObjectSpace.define_finalizer self, @@final
      end
      @@id_map[@__id] = [] unless @@id_map[@__id]
    ensure
      Thread.critical = __old_status
    end
    @@id_map[@__id].push self.__id__
    @@id_rev_map[self.__id__] = @__id
  end

  # Returns true if the referenced object still exists, and false if it has
  # been garbage collected.
  def weakref_alive?
    @@id_rev_map[self.__id__] == @__id
  end
end

if __FILE__ == $0
  require 'thread'
  foo = Object.new
  p foo.to_s			# original's class
  foo = WeakRef.new(foo)
  p foo.to_s			# should be same class
  ObjectSpace.garbage_collect
  p foo.to_s			# should raise exception (recycled)
end
PK     tZ\{aC  C    readbytes.rbnu [        # TruncatedDataError is raised when IO#readbytes fails to read enough data.

class TruncatedDataError<IOError
  def initialize(mesg, data) # :nodoc:
    @data = data
    super(mesg)
  end

  # The read portion of an IO#readbytes attempt.
  attr_reader :data
end

class IO
  # Reads exactly +n+ bytes.
  #
  # If the data read is nil an EOFError is raised.
  #
  # If the data read is too short a TruncatedDataError is raised and the read
  # data is obtainable via its #data method.
  def readbytes(n)
    str = read(n)
    if str == nil
      raise EOFError, "End of file reached"
    end
    if str.size < n
      raise TruncatedDataError.new("data truncated", str) 
    end
    str
  end
end

if __FILE__ == $0
  begin
    loop do
      print STDIN.readbytes(6)
    end
  rescue TruncatedDataError
    p $!.data
    raise
  end
end
PK     tZ\}y4
  
  	  tracer.rbnu [        #
#   tracer.rb - 
#   	$Release Version: 0.2$
#   	$Revision: 1.8 $
#   	$Date: 1998/05/19 03:42:49 $
#   	by Keiju ISHITSUKA(Nippon Rational Inc.)
#
# --
#
#   
#

#
# tracer main class
#
class Tracer
  @RCS_ID='-$Id: tracer.rb,v 1.8 1998/05/19 03:42:49 keiju Exp keiju $-'

  @stdout = STDOUT
  @verbose = false
  class << self
    attr :verbose, true
    alias verbose? verbose
    attr :stdout, true
  end
  
  EVENT_SYMBOL = {
    "line" => "-",
    "call" => ">",
    "return" => "<",
    "class" => "C",
    "end" => "E",
    "c-call" => ">",
    "c-return" => "<",
  }
  
  def initialize
    @threads = Hash.new
    if defined? Thread.main
      @threads[Thread.main.object_id] = 0
    else
      @threads[Thread.current.object_id] = 0
    end

    @get_line_procs = {}

    @filters = []
  end
  
  def stdout
    Tracer.stdout
  end

  def on
    if block_given?
      on
      begin
	yield
      ensure
	off
      end
    else
      set_trace_func method(:trace_func).to_proc
      stdout.print "Trace on\n" if Tracer.verbose?
    end
  end
  
  def off
    set_trace_func nil
    stdout.print "Trace off\n" if Tracer.verbose?
  end

  def add_filter(p = proc)
    @filters.push p
  end

  def set_get_line_procs(file, p = proc)
    @get_line_procs[file] = p
  end
  
  def get_line(file, line)
    if p = @get_line_procs[file]
      return p.call(line)
    end

    unless list = SCRIPT_LINES__[file]
      begin
	f = open(file)
	begin 
	  SCRIPT_LINES__[file] = list = f.readlines
	ensure
	  f.close
	end
      rescue
	SCRIPT_LINES__[file] = list = []
      end
    end

    if l = list[line - 1]
      l
    else
      "-\n"
    end
  end
  
  def get_thread_no
    if no = @threads[Thread.current.object_id]
      no
    else
      @threads[Thread.current.object_id] = @threads.size
    end
  end
  
  def trace_func(event, file, line, id, binding, klass, *)
    return if file == __FILE__
    
    for p in @filters
      return unless p.call event, file, line, id, binding, klass
    end
    
    saved_crit = Thread.critical
    Thread.critical = true
    stdout.printf("#%d:%s:%d:%s:%s: %s",
      get_thread_no,
      file,
      line,
      klass || '',
      EVENT_SYMBOL[event],
      get_line(file, line))
    Thread.critical = saved_crit
  end

  Single = new
  def Tracer.on
    if block_given?
      Single.on{yield}
    else
      Single.on
    end
  end
  
  def Tracer.off
    Single.off
  end
  
  def Tracer.set_get_line_procs(file_name, p = proc)
    Single.set_get_line_procs(file_name, p)
  end

  def Tracer.add_filter(p = proc)
    Single.add_filter(p)
  end
  
end

SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__

if $0 == __FILE__
  # direct call
    
  $0 = ARGV[0]
  ARGV.shift
  Tracer.on
  require $0
elsif caller(0).size == 1
  Tracer.on
end
PK     uZ\u-  -    racc/parser.rbnu [        #
# $originalId: parser.rb,v 1.8 2006/07/06 11:42:07 aamine Exp $
#
# Copyright (c) 1999-2006 Minero Aoki
#
# This program is free software.
# You can distribute/modify this program under the same terms of ruby.
#
# As a special exception, when this code is copied by Racc
# into a Racc output file, you may use that output file
# without restriction.
#

unless defined?(NotImplementedError)
  NotImplementedError = NotImplementError
end

module Racc
  class ParseError < StandardError; end
end
unless defined?(::ParseError)
  ParseError = Racc::ParseError
end

module Racc

  unless defined?(Racc_No_Extentions)
    Racc_No_Extentions = false
  end

  class Parser

    Racc_Runtime_Version = '1.4.5'
    Racc_Runtime_Revision = '$originalRevision: 1.8 $'.split[1]

    Racc_Runtime_Core_Version_R = '1.4.5'
    Racc_Runtime_Core_Revision_R = '$originalRevision: 1.8 $'.split[1]
    begin
      require 'racc/cparse'
    # Racc_Runtime_Core_Version_C  = (defined in extention)
      Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split[2]
      unless new.respond_to?(:_racc_do_parse_c, true)
        raise LoadError, 'old cparse.so'
      end
      if Racc_No_Extentions
        raise LoadError, 'selecting ruby version of racc runtime core'
      end

      Racc_Main_Parsing_Routine    = :_racc_do_parse_c
      Racc_YY_Parse_Method         = :_racc_yyparse_c
      Racc_Runtime_Core_Version    = Racc_Runtime_Core_Version_C
      Racc_Runtime_Core_Revision   = Racc_Runtime_Core_Revision_C
      Racc_Runtime_Type            = 'c'
    rescue LoadError
      Racc_Main_Parsing_Routine    = :_racc_do_parse_rb
      Racc_YY_Parse_Method         = :_racc_yyparse_rb
      Racc_Runtime_Core_Version    = Racc_Runtime_Core_Version_R
      Racc_Runtime_Core_Revision   = Racc_Runtime_Core_Revision_R
      Racc_Runtime_Type            = 'ruby'
    end

    def Parser.racc_runtime_type
      Racc_Runtime_Type
    end

    private

    def _racc_setup
      @yydebug = false unless self.class::Racc_debug_parser
      @yydebug = false unless defined?(@yydebug)
      if @yydebug
        @racc_debug_out = $stderr unless defined?(@racc_debug_out)
        @racc_debug_out ||= $stderr
      end
      arg = self.class::Racc_arg
      arg[13] = true if arg.size < 14
      arg
    end

    def _racc_init_sysvars
      @racc_state  = [0]
      @racc_tstack = []
      @racc_vstack = []

      @racc_t = nil
      @racc_val = nil

      @racc_read_next = true

      @racc_user_yyerror = false
      @racc_error_status = 0
    end

    ###
    ### do_parse
    ###

    def do_parse
      __send__(Racc_Main_Parsing_Routine, _racc_setup(), false)
    end

    def next_token
      raise NotImplementedError, "#{self.class}\#next_token is not defined"
    end

    def _racc_do_parse_rb(arg, in_debug)
      action_table, action_check, action_default, action_pointer,
      goto_table,   goto_check,   goto_default,   goto_pointer,
      nt_base,      reduce_table, token_table,    shift_n,
      reduce_n,     use_result,   * = arg

      _racc_init_sysvars
      tok = act = i = nil
      nerr = 0

      catch(:racc_end_parse) {
        while true
          if i = action_pointer[@racc_state[-1]]
            if @racc_read_next
              if @racc_t != 0   # not EOF
                tok, @racc_val = next_token()
                unless tok      # EOF
                  @racc_t = 0
                else
                  @racc_t = (token_table[tok] or 1)   # error token
                end
                racc_read_token(@racc_t, tok, @racc_val) if @yydebug
                @racc_read_next = false
              end
            end
            i += @racc_t
            unless i >= 0 and
                   act = action_table[i] and
                   action_check[i] == @racc_state[-1]
              act = action_default[@racc_state[-1]]
            end
          else
            act = action_default[@racc_state[-1]]
          end
          while act = _racc_evalact(act, arg)
            ;
          end
        end
      }
    end

    ###
    ### yyparse
    ###

    def yyparse(recv, mid)
      __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), true)
    end

    def _racc_yyparse_rb(recv, mid, arg, c_debug)
      action_table, action_check, action_default, action_pointer,
      goto_table,   goto_check,   goto_default,   goto_pointer,
      nt_base,      reduce_table, token_table,    shift_n,
      reduce_n,     use_result,   * = arg

      _racc_init_sysvars
      tok = nil
      act = nil
      i = nil
      nerr = 0

      catch(:racc_end_parse) {
        until i = action_pointer[@racc_state[-1]]
          while act = _racc_evalact(action_default[@racc_state[-1]], arg)
            ;
          end
        end
        recv.__send__(mid) do |tok, val|
          unless tok
            @racc_t = 0
          else
            @racc_t = (token_table[tok] or 1)   # error token
          end
          @racc_val = val
          @racc_read_next = false

          i += @racc_t
          unless i >= 0 and
                 act = action_table[i] and
                 action_check[i] == @racc_state[-1]
            act = action_default[@racc_state[-1]]
          end
          while act = _racc_evalact(act, arg)
            ;
          end

          while not (i = action_pointer[@racc_state[-1]]) or
                not @racc_read_next or
                @racc_t == 0   # $
            unless i and i += @racc_t and
                   i >= 0 and
                   act = action_table[i] and
                   action_check[i] == @racc_state[-1]
              act = action_default[@racc_state[-1]]
            end
            while act = _racc_evalact(act, arg)
              ;
            end
          end
        end
      }
    end

    ###
    ### common
    ###

    def _racc_evalact(act, arg)
      action_table, action_check, action_default, action_pointer,
      goto_table,   goto_check,   goto_default,   goto_pointer,
      nt_base,      reduce_table, token_table,    shift_n,
      reduce_n,     use_result,   * = arg
      nerr = 0   # tmp

      if act > 0 and act < shift_n
        #
        # shift
        #
        if @racc_error_status > 0
          @racc_error_status -= 1 unless @racc_t == 1   # error token
        end
        @racc_vstack.push @racc_val
        @racc_state.push act
        @racc_read_next = true
        if @yydebug
          @racc_tstack.push @racc_t
          racc_shift @racc_t, @racc_tstack, @racc_vstack
        end

      elsif act < 0 and act > -reduce_n
        #
        # reduce
        #
        code = catch(:racc_jump) {
          @racc_state.push _racc_do_reduce(arg, act)
          false
        }
        if code
          case code
          when 1 # yyerror
            @racc_user_yyerror = true   # user_yyerror
            return -reduce_n
          when 2 # yyaccept
            return shift_n
          else
            raise '[Racc Bug] unknown jump code'
          end
        end

      elsif act == shift_n
        #
        # accept
        #
        racc_accept if @yydebug
        throw :racc_end_parse, @racc_vstack[0]

      elsif act == -reduce_n
        #
        # error
        #
        case @racc_error_status
        when 0
          unless arg[21]    # user_yyerror
            nerr += 1
            on_error @racc_t, @racc_val, @racc_vstack
          end
        when 3
          if @racc_t == 0   # is $
            throw :racc_end_parse, nil
          end
          @racc_read_next = true
        end
        @racc_user_yyerror = false
        @racc_error_status = 3
        while true
          if i = action_pointer[@racc_state[-1]]
            i += 1   # error token
            if  i >= 0 and
                (act = action_table[i]) and
                action_check[i] == @racc_state[-1]
              break
            end
          end
          throw :racc_end_parse, nil if @racc_state.size <= 1
          @racc_state.pop
          @racc_vstack.pop
          if @yydebug
            @racc_tstack.pop
            racc_e_pop @racc_state, @racc_tstack, @racc_vstack
          end
        end
        return act

      else
        raise "[Racc Bug] unknown action #{act.inspect}"
      end

      racc_next_state(@racc_state[-1], @racc_state) if @yydebug

      nil
    end

    def _racc_do_reduce(arg, act)
      action_table, action_check, action_default, action_pointer,
      goto_table,   goto_check,   goto_default,   goto_pointer,
      nt_base,      reduce_table, token_table,    shift_n,
      reduce_n,     use_result,   * = arg
      state = @racc_state
      vstack = @racc_vstack
      tstack = @racc_tstack

      i = act * -3
      len       = reduce_table[i]
      reduce_to = reduce_table[i+1]
      method_id = reduce_table[i+2]
      void_array = []

      tmp_t = tstack[-len, len] if @yydebug
      tmp_v = vstack[-len, len]
      tstack[-len, len] = void_array if @yydebug
      vstack[-len, len] = void_array
      state[-len, len]  = void_array

      # tstack must be updated AFTER method call
      if use_result
        vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
      else
        vstack.push __send__(method_id, tmp_v, vstack)
      end
      tstack.push reduce_to

      racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug

      k1 = reduce_to - nt_base
      if i = goto_pointer[k1]
        i += state[-1]
        if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
          return curstate
        end
      end
      goto_default[k1]
    end

    def on_error(t, val, vstack)
      raise ParseError, sprintf("\nparse error on value %s (%s)",
                                val.inspect, token_to_str(t) || '?')
    end

    def yyerror
      throw :racc_jump, 1
    end

    def yyaccept
      throw :racc_jump, 2
    end

    def yyerrok
      @racc_error_status = 0
    end

    #
    # for debugging output
    #

    def racc_read_token(t, tok, val)
      @racc_debug_out.print 'read    '
      @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
      @racc_debug_out.puts val.inspect
      @racc_debug_out.puts
    end

    def racc_shift(tok, tstack, vstack)
      @racc_debug_out.puts "shift   #{racc_token2str tok}"
      racc_print_stacks tstack, vstack
      @racc_debug_out.puts
    end

    def racc_reduce(toks, sim, tstack, vstack)
      out = @racc_debug_out
      out.print 'reduce '
      if toks.empty?
        out.print ' <none>'
      else
        toks.each {|t| out.print ' ', racc_token2str(t) }
      end
      out.puts " --> #{racc_token2str(sim)}"
          
      racc_print_stacks tstack, vstack
      @racc_debug_out.puts
    end

    def racc_accept
      @racc_debug_out.puts 'accept'
      @racc_debug_out.puts
    end

    def racc_e_pop(state, tstack, vstack)
      @racc_debug_out.puts 'error recovering mode: pop token'
      racc_print_states state
      racc_print_stacks tstack, vstack
      @racc_debug_out.puts
    end

    def racc_next_state(curstate, state)
      @racc_debug_out.puts  "goto    #{curstate}"
      racc_print_states state
      @racc_debug_out.puts
    end

    def racc_print_stacks(t, v)
      out = @racc_debug_out
      out.print '        ['
      t.each_index do |i|
        out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
      end
      out.puts ' ]'
    end

    def racc_print_states(s)
      out = @racc_debug_out
      out.print '        ['
      s.each {|st| out.print ' ', st }
      out.puts ' ]'
    end

    def racc_token2str(tok)
      self.class::Racc_token_to_s_table[tok] or
          raise "[Racc Bug] can't convert token #{tok} to string"
    end

    def token_to_str(t)
      self.class::Racc_token_to_s_table[t]
    end

  end

end
PK     uZ\>,  ,  	  pstore.rbnu [        # = PStore -- Transactional File Storage for Ruby Objects
#
# pstore.rb -
#   originally by matz
#   documentation by Kev Jackson and James Edward Gray II
#
# See PStore for documentation.


require "fileutils"
require "digest/md5"

#
# PStore implements a file based persistence mechanism based on a Hash.  User
# code can store hierarchies of Ruby objects (values) into the data store file
# by name (keys).  An object hierarchy may be just a single object.  User code 
# may later read values back from the data store or even update data, as needed.
# 
# The transactional behavior ensures that any changes succeed or fail together.
# This can be used to ensure that the data store is not left in a transitory
# state, where some values were updated but others were not.
# 
# Behind the scenes, Ruby objects are stored to the data store file with 
# Marshal.  That carries the usual limitations.  Proc objects cannot be 
# marshalled, for example.
#
# == Usage example:
# 
#  require "pstore"
#  
#  # a mock wiki object...
#  class WikiPage
#    def initialize( page_name, author, contents )
#      @page_name = page_name
#      @revisions = Array.new
#      
#      add_revision(author, contents)
#    end
#    
#    attr_reader :page_name
#    
#    def add_revision( author, contents )
#      @revisions << { :created  => Time.now,
#                      :author   => author,
#                      :contents => contents }
#    end
#    
#    def wiki_page_references
#      [@page_name] + @revisions.last[:contents].scan(/\b(?:[A-Z]+[a-z]+){2,}/)
#    end
#    
#    # ...
#  end
#  
#  # create a new page...
#  home_page = WikiPage.new( "HomePage", "James Edward Gray II",
#                            "A page about the JoysOfDocumentation..." )
#  
#  # then we want to update page data and the index together, or not at all...
#  wiki = PStore.new("wiki_pages.pstore")
#  wiki.transaction do  # begin transaction; do all of this or none of it
#    # store page...
#    wiki[home_page.page_name] = home_page
#    # ensure that an index has been created...
#    wiki[:wiki_index] ||= Array.new
#    # update wiki index...
#    wiki[:wiki_index].push(*home_page.wiki_page_references)
#  end                   # commit changes to wiki data store file
#  
#  ### Some time later... ###
#  
#  # read wiki data...
#  wiki.transaction(true) do  # begin read-only transaction, no changes allowed
#    wiki.roots.each do |data_root_name|
#      p data_root_name
#      p wiki[data_root_name]
#    end
#  end
#
class PStore
  binmode = defined?(File::BINARY) ? File::BINARY : 0
  RDWR_ACCESS = File::RDWR | File::CREAT | binmode
  RD_ACCESS = File::RDONLY | binmode
  WR_ACCESS = File::WRONLY | File::CREAT | File::TRUNC | binmode

  # The error type thrown by all PStore methods.
  class Error < StandardError
  end

  # 
  # To construct a PStore object, pass in the _file_ path where you would like 
  # the data to be stored.
  # 
  def initialize(file)
    dir = File::dirname(file)
    unless File::directory? dir
      raise PStore::Error, format("directory %s does not exist", dir)
    end
    if File::exist? file and not File::readable? file
      raise PStore::Error, format("file %s not readable", file)
    end
    @transaction = false
    @filename = file
    @abort = false
  end

  # Raises PStore::Error if the calling code is not in a PStore#transaction.
  def in_transaction
    raise PStore::Error, "not in transaction" unless @transaction
  end
  # 
  # Raises PStore::Error if the calling code is not in a PStore#transaction or
  # if the code is in a read-only PStore#transaction.
  # 
  def in_transaction_wr()
    in_transaction()
    raise PStore::Error, "in read-only transaction" if @rdonly
  end
  private :in_transaction, :in_transaction_wr

  #
  # Retrieves a value from the PStore file data, by _name_.  The hierarchy of 
  # Ruby objects stored under that root _name_ will be returned.
  # 
  # *WARNING*:  This method is only valid in a PStore#transaction.  It will
  # raise PStore::Error if called at any other time.
  #
  def [](name)
    in_transaction
    @table[name]
  end
  #
  # This method is just like PStore#[], save that you may also provide a 
  # _default_ value for the object.  In the event the specified _name_ is not 
  # found in the data store, your _default_ will be returned instead.  If you do 
  # not specify a default, PStore::Error will be raised if the object is not 
  # found.
  # 
  # *WARNING*:  This method is only valid in a PStore#transaction.  It will
  # raise PStore::Error if called at any other time.
  #
  def fetch(name, default=PStore::Error)
    in_transaction
    unless @table.key? name
      if default==PStore::Error
	raise PStore::Error, format("undefined root name `%s'", name)
      else
	return default
      end
    end
    @table[name]
  end
  #
  # Stores an individual Ruby object or a hierarchy of Ruby objects in the data
  # store file under the root _name_.  Assigning to a _name_ already in the data
  # store clobbers the old data.
  # 
  # == Example:
  # 
  #  require "pstore"
  #  
  #  store = PStore.new("data_file.pstore")
  #  store.transaction do  # begin transaction
  #    # load some data into the store...
  #    store[:single_object] = "My data..."
  #    store[:obj_heirarchy] = { "Kev Jackson" => ["rational.rb", "pstore.rb"],
  #                              "James Gray"  => ["erb.rb", "pstore.rb"] }
  #  end                   # commit changes to data store file
  # 
  # *WARNING*:  This method is only valid in a PStore#transaction and it cannot
  # be read-only.  It will raise PStore::Error if called at any other time.
  #
  def []=(name, value)
    in_transaction_wr()
    @table[name] = value
  end
  #
  # Removes an object hierarchy from the data store, by _name_.
  # 
  # *WARNING*:  This method is only valid in a PStore#transaction and it cannot
  # be read-only.  It will raise PStore::Error if called at any other time.
  #
  def delete(name)
    in_transaction_wr()
    @table.delete name
  end

  #
  # Returns the names of all object hierarchies currently in the store.
  # 
  # *WARNING*:  This method is only valid in a PStore#transaction.  It will
  # raise PStore::Error if called at any other time.
  #
  def roots
    in_transaction
    @table.keys
  end
  #
  # Returns true if the supplied _name_ is currently in the data store.
  # 
  # *WARNING*:  This method is only valid in a PStore#transaction.  It will
  # raise PStore::Error if called at any other time.
  #
  def root?(name)
    in_transaction
    @table.key? name
  end
  # Returns the path to the data store file.
  def path
    @filename
  end

  #
  # Ends the current PStore#transaction, committing any changes to the data
  # store immediately.
  # 
  # == Example:
  # 
  #  require "pstore"
  #   
  #  store = PStore.new("data_file.pstore")
  #  store.transaction do  # begin transaction
  #    # load some data into the store...
  #    store[:one] = 1
  #    store[:two] = 2
  #  
  #    store.commit        # end transaction here, committing changes
  #  
  #    store[:three] = 3   # this change is never reached
  #  end
  # 
  # *WARNING*:  This method is only valid in a PStore#transaction.  It will
  # raise PStore::Error if called at any other time.
  #
  def commit
    in_transaction
    @abort = false
    throw :pstore_abort_transaction
  end
  #
  # Ends the current PStore#transaction, discarding any changes to the data
  # store.
  # 
  # == Example:
  # 
  #  require "pstore"
  #   
  #  store = PStore.new("data_file.pstore")
  #  store.transaction do  # begin transaction
  #    store[:one] = 1     # this change is not applied, see below...
  #    store[:two] = 2     # this change is not applied, see below...
  #  
  #    store.abort         # end transaction here, discard all changes
  #  
  #    store[:three] = 3   # this change is never reached
  #  end
  # 
  # *WARNING*:  This method is only valid in a PStore#transaction.  It will
  # raise PStore::Error if called at any other time.
  #
  def abort
    in_transaction
    @abort = true
    throw :pstore_abort_transaction
  end

  #
  # Opens a new transaction for the data store.  Code executed inside a block
  # passed to this method may read and write data to and from the data store 
  # file.
  # 
  # At the end of the block, changes are committed to the data store
  # automatically.  You may exit the transaction early with a call to either 
  # PStore#commit or PStore#abort.  See those methods for details about how
  # changes are handled.  Raising an uncaught Exception in the block is 
  # equivalent to calling PStore#abort.
  # 
  # If _read_only_ is set to +true+, you will only be allowed to read from the
  # data store during the transaction and any attempts to change the data will
  # raise a PStore::Error.
  # 
  # Note that PStore does not support nested transactions.
  #
  def transaction(read_only=false)  # :yields:  pstore
    raise PStore::Error, "nested transaction" if @transaction
    begin
      @rdonly = read_only
      @abort = false
      @transaction = true
      value = nil
      new_file = @filename + ".new"

      content = nil
      unless read_only
        file = File.open(@filename, RDWR_ACCESS)
        file.flock(File::LOCK_EX)
        commit_new(file) if FileTest.exist?(new_file)
        content = file.read()
      else
        begin
          file = File.open(@filename, RD_ACCESS)
          file.flock(File::LOCK_SH)
          content = (File.open(new_file, RD_ACCESS) {|n| n.read} rescue file.read())
        rescue Errno::ENOENT
          content = ""
        end
      end

      if content != ""
	@table = load(content)
        if !read_only
          size = content.size
          md5 = Digest::MD5.digest(content)
        end
      else
	@table = {}
      end
      content = nil		# unreference huge data

      begin
	catch(:pstore_abort_transaction) do
	  value = yield(self)
	end
      rescue Exception
	@abort = true
	raise
      ensure
	if !read_only and !@abort
          tmp_file = @filename + ".tmp"
	  content = dump(@table)
	  if !md5 || size != content.size || md5 != Digest::MD5.digest(content)
            File.open(tmp_file, WR_ACCESS) {|t| t.write(content)}
            File.rename(tmp_file, new_file)
            commit_new(file)
          end
          content = nil		# unreference huge data
	end
      end
    ensure
      @table = nil
      @transaction = false
      file.close if file
    end
    value
  end

  # This method is just a wrapped around Marshal.dump.
  def dump(table)  # :nodoc:
    Marshal::dump(table)
  end

  # This method is just a wrapped around Marshal.load.
  def load(content)  # :nodoc:
    Marshal::load(content)
  end

  # This method is just a wrapped around Marshal.load.
  def load_file(file)  # :nodoc:
    Marshal::load(file)
  end

  private
  # Commits changes to the data store file.
  def commit_new(f)
    f.truncate(0)
    f.rewind
    new_file = @filename + ".new"
    File.open(new_file, RD_ACCESS) do |nf|
      FileUtils.copy_stream(nf, f)
    end
    File.unlink(new_file)
  end
end

# :enddoc:

if __FILE__ == $0
  db = PStore.new("/tmp/foo")
  db.transaction do
    p db.roots
    ary = db["root"] = [1,2,3,4]
    ary[1] = [1,1.5]
  end

  1000.times do
    db.transaction do
      db["root"][0] += 1
      p db["root"][0]
    end
  end

  db.transaction(true) do
    p db["root"]
  end
end
PK     vZ\-q      Env.rbnu [        # Env.rb -- imports environment variables as global variables, Perlish ;(
# Usage:
#
#  require 'Env'
#  p $USER
#  $USER = "matz"
#  p ENV["USER"]

require 'importenv'

if __FILE__ == $0
  p $TERM
  $TERM = nil
  p $TERM
  p ENV["TERM"]
  $TERM = "foo"
  p ENV["TERM"]
end
PK     wZ\Րk        drb.rbnu [        require 'drb/drb'

PK     wZ\ln[3  [3  
  complex.rbnu [        #
#   complex.rb - 
#   	$Release Version: 0.5 $
#   	$Revision: 1.3 $
#   	$Date: 1998/07/08 10:05:28 $
#   	by Keiju ISHITSUKA(SHL Japan Inc.)
#
# ----
#
# complex.rb implements the Complex class for complex numbers.  Additionally,
# some methods in other Numeric classes are redefined or added to allow greater
# interoperability with Complex numbers.
#
# Complex numbers can be created in the following manner:
# - <tt>Complex(a, b)</tt>
# - <tt>Complex.polar(radius, theta)</tt>
#   
# Additionally, note the following:
# - <tt>Complex::I</tt> (the mathematical constant <i>i</i>)
# - <tt>Numeric#im</tt> (e.g. <tt>5.im -> 0+5i</tt>)
#
# The following +Math+ module methods are redefined to handle Complex arguments.
# They will work as normal with non-Complex arguments.
#    sqrt exp cos sin tan log log10
#    cosh sinh tanh acos asin atan atan2 acosh asinh atanh
#


#
# Numeric is a built-in class on which Fixnum, Bignum, etc., are based.  Here
# some methods are added so that all number types can be treated to some extent
# as Complex numbers.
#
class Numeric
  #
  # Returns a Complex number <tt>(0,<i>self</i>)</tt>.
  #
  def im
    Complex(0, self)
  end
  
  #
  # The real part of a complex number, i.e. <i>self</i>.
  #
  def real
    self
  end
  
  #
  # The imaginary part of a complex number, i.e. 0.
  #
  def image
    0
  end
  alias imag image
  
  #
  # See Complex#arg.
  #
  def arg
    Math.atan2!(0, self)
  end
  alias angle arg
  
  #
  # See Complex#polar.
  #
  def polar
    return abs, arg
  end
  
  #
  # See Complex#conjugate (short answer: returns <i>self</i>).
  #
  def conjugate
    self
  end
  alias conj conjugate
end


#
# Creates a Complex number.  +a+ and +b+ should be Numeric.  The result will be
# <tt>a+bi</tt>.
#
def Complex(a, b = 0)
  if b == 0 and (a.kind_of?(Complex) or defined? Complex::Unify)
    a
  else
    Complex.new( a.real-b.imag, a.imag+b.real )
  end
end

#
# The complex number class.  See complex.rb for an overview.
#
class Complex < Numeric
  @RCS_ID='-$Id: complex.rb,v 1.3 1998/07/08 10:05:28 keiju Exp keiju $-'

  undef step
  undef div, divmod
  undef floor, truncate, ceil, round

  def Complex.generic?(other) # :nodoc:
    other.kind_of?(Integer) or
    other.kind_of?(Float) or
    (defined?(Rational) and other.kind_of?(Rational))
  end

  #
  # Creates a +Complex+ number in terms of +r+ (radius) and +theta+ (angle).
  #
  def Complex.polar(r, theta)
    Complex(r*Math.cos(theta), r*Math.sin(theta))
  end

  #
  # Creates a +Complex+ number <tt>a</tt>+<tt>b</tt><i>i</i>.
  #
  def Complex.new!(a, b=0)
    new(a,b)
  end

  def initialize(a, b)
    raise TypeError, "non numeric 1st arg `#{a.inspect}'" if !a.kind_of? Numeric
    raise TypeError, "`#{a.inspect}' for 1st arg" if a.kind_of? Complex
    raise TypeError, "non numeric 2nd arg `#{b.inspect}'" if !b.kind_of? Numeric
    raise TypeError, "`#{b.inspect}' for 2nd arg" if b.kind_of? Complex
    @real = a
    @image = b
  end

  #
  # Addition with real or complex number.
  #
  def + (other)
    if other.kind_of?(Complex)
      re = @real + other.real
      im = @image + other.image
      Complex(re, im)
    elsif Complex.generic?(other)
      Complex(@real + other, @image)
    else
      x , y = other.coerce(self)
      x + y
    end
  end
  
  #
  # Subtraction with real or complex number.
  #
  def - (other)
    if other.kind_of?(Complex)
      re = @real - other.real
      im = @image - other.image
      Complex(re, im)
    elsif Complex.generic?(other)
      Complex(@real - other, @image)
    else
      x , y = other.coerce(self)
      x - y
    end
  end
  
  #
  # Multiplication with real or complex number.
  #
  def * (other)
    if other.kind_of?(Complex)
      re = @real*other.real - @image*other.image
      im = @real*other.image + @image*other.real
      Complex(re, im)
    elsif Complex.generic?(other)
      Complex(@real * other, @image * other)
    else
      x , y = other.coerce(self)
      x * y
    end
  end
  
  #
  # Division by real or complex number.
  #
  def / (other)
    if other.kind_of?(Complex)
      self*other.conjugate/other.abs2
    elsif Complex.generic?(other)
      Complex(@real/other, @image/other)
    else
      x, y = other.coerce(self)
      x/y
    end
  end
  
  def quo(other)
    Complex(@real.quo(1), @image.quo(1)) / other
  end

  #
  # Raise this complex number to the given (real or complex) power.
  #
  def ** (other)
    if other == 0
      return Complex(1)
    end
    if other.kind_of?(Complex)
      r, theta = polar
      ore = other.real
      oim = other.image
      nr = Math.exp!(ore*Math.log!(r) - oim * theta)
      ntheta = theta*ore + oim*Math.log!(r)
      Complex.polar(nr, ntheta)
    elsif other.kind_of?(Integer)
      if other > 0
	x = self
	z = x
	n = other - 1
	while n != 0
	  while (div, mod = n.divmod(2)
		 mod == 0)
	    x = Complex(x.real*x.real - x.image*x.image, 2*x.real*x.image)
	    n = div
	  end
	  z *= x
	  n -= 1
	end
	z
      else
	if defined? Rational
	  (Rational(1) / self) ** -other
	else
	  self ** Float(other)
	end
      end
    elsif Complex.generic?(other)
      r, theta = polar
      Complex.polar(r**other, theta*other)
    else
      x, y = other.coerce(self)
      x**y
    end
  end
  
  #
  # Remainder after division by a real or complex number.
  #
  def % (other)
    if other.kind_of?(Complex)
      Complex(@real % other.real, @image % other.image)
    elsif Complex.generic?(other)
      Complex(@real % other, @image % other)
    else
      x , y = other.coerce(self)
      x % y
    end
  end
  
#--
#    def divmod(other)
#      if other.kind_of?(Complex)
#        rdiv, rmod = @real.divmod(other.real)
#        idiv, imod = @image.divmod(other.image)
#        return Complex(rdiv, idiv), Complex(rmod, rmod)
#      elsif Complex.generic?(other)
#        Complex(@real.divmod(other), @image.divmod(other))
#      else
#        x , y = other.coerce(self)
#        x.divmod(y)
#      end
#    end
#++
  
  #
  # Absolute value (aka modulus): distance from the zero point on the complex
  # plane.
  #
  def abs
    Math.hypot(@real, @image)
  end
  
  #
  # Square of the absolute value.
  #
  def abs2
    @real*@real + @image*@image
  end
  
  #
  # Argument (angle from (1,0) on the complex plane).
  #
  def arg
    Math.atan2!(@image, @real)
  end
  alias angle arg
  
  #
  # Returns the absolute value _and_ the argument.
  #
  def polar
    return abs, arg
  end
  
  #
  # Complex conjugate (<tt>z + z.conjugate = 2 * z.real</tt>).
  #
  def conjugate
    Complex(@real, -@image)
  end
  alias conj conjugate
  
  #
  # Compares the absolute values of the two numbers.
  #
  def <=> (other)
    self.abs <=> other.abs
  end
  
  #
  # Test for numerical equality (<tt>a == a + 0<i>i</i></tt>).
  #
  def == (other)
    if other.kind_of?(Complex)
      @real == other.real and @image == other.image
    elsif Complex.generic?(other)
      @real == other and @image == 0
    else
      other == self
    end
  end

  #
  # Attempts to coerce +other+ to a Complex number.
  #
  def coerce(other)
    if Complex.generic?(other)
      return Complex.new!(other), self
    else
      super
    end
  end

  #
  # FIXME
  #
  def denominator
    @real.denominator.lcm(@image.denominator)
  end
  
  #
  # FIXME
  #
  def numerator
    cd = denominator
    Complex(@real.numerator*(cd/@real.denominator),
	    @image.numerator*(cd/@image.denominator))
  end
  
  #
  # Standard string representation of the complex number.
  #
  def to_s
    if @real != 0
      if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
	if @image >= 0
	  @real.to_s+"+("+@image.to_s+")i"
	else
	  @real.to_s+"-("+(-@image).to_s+")i"
	end
      else
	if @image >= 0
	  @real.to_s+"+"+@image.to_s+"i"
	else
	  @real.to_s+"-"+(-@image).to_s+"i"
	end
      end
    else
      if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
	"("+@image.to_s+")i"
      else
	@image.to_s+"i"
      end
    end
  end
  
  #
  # Returns a hash code for the complex number.
  #
  def hash
    @real.hash ^ @image.hash
  end
  
  #
  # Returns "<tt>Complex(<i>real</i>, <i>image</i>)</tt>".
  #
  def inspect
    sprintf("Complex(%s, %s)", @real.inspect, @image.inspect)
  end

  
  #
  # +I+ is the imaginary number.  It exists at point (0,1) on the complex plane.
  #
  I = Complex(0,1)
  
  # The real part of a complex number.
  attr :real

  # The imaginary part of a complex number.
  attr :image
  alias imag image
  
end

class Integer

  unless defined?(1.numerator)
    def numerator() self end
    def denominator() 1 end

    def gcd(other)
      min = self.abs
      max = other.abs
      while min > 0
        tmp = min
        min = max % min
        max = tmp
      end
      max
    end

    def lcm(other)
      if self.zero? or other.zero?
        0
      else
        (self.div(self.gcd(other)) * other).abs
      end
    end

  end

end

module Math
  alias sqrt! sqrt
  alias exp! exp
  alias log! log
  alias log10! log10
  alias cos! cos
  alias sin! sin
  alias tan! tan
  alias cosh! cosh
  alias sinh! sinh
  alias tanh! tanh
  alias acos! acos
  alias asin! asin
  alias atan! atan
  alias atan2! atan2
  alias acosh! acosh
  alias asinh! asinh
  alias atanh! atanh  

  # Redefined to handle a Complex argument.
  def sqrt(z)
    if Complex.generic?(z)
      if z >= 0
	sqrt!(z)
      else
	Complex(0,sqrt!(-z))
      end
    else
      if z.image < 0
	sqrt(z.conjugate).conjugate
      else
	r = z.abs
	x = z.real
	Complex( sqrt!((r+x)/2), sqrt!((r-x)/2) )
      end
    end
  end
  
  # Redefined to handle a Complex argument.
  def exp(z)
    if Complex.generic?(z)
      exp!(z)
    else
      Complex(exp!(z.real) * cos!(z.image), exp!(z.real) * sin!(z.image))
    end
  end
  
  # Redefined to handle a Complex argument.
  def cos(z)
    if Complex.generic?(z)
      cos!(z)
    else
      Complex(cos!(z.real)*cosh!(z.image),
	      -sin!(z.real)*sinh!(z.image))
    end
  end
    
  # Redefined to handle a Complex argument.
  def sin(z)
    if Complex.generic?(z)
      sin!(z)
    else
      Complex(sin!(z.real)*cosh!(z.image),
	      cos!(z.real)*sinh!(z.image))
    end
  end
  
  # Redefined to handle a Complex argument.
  def tan(z)
    if Complex.generic?(z)
      tan!(z)
    else
      sin(z)/cos(z)
    end
  end

  def sinh(z)
    if Complex.generic?(z)
      sinh!(z)
    else
      Complex( sinh!(z.real)*cos!(z.image), cosh!(z.real)*sin!(z.image) )
    end
  end

  def cosh(z)
    if Complex.generic?(z)
      cosh!(z)
    else
      Complex( cosh!(z.real)*cos!(z.image), sinh!(z.real)*sin!(z.image) )
    end
  end

  def tanh(z)
    if Complex.generic?(z)
      tanh!(z)
    else
      sinh(z)/cosh(z)
    end
  end
  
  # Redefined to handle a Complex argument.
  def log(z)
    if Complex.generic?(z) and z >= 0
      log!(z)
    else
      r, theta = z.polar
      Complex(log!(r.abs), theta)
    end
  end
  
  # Redefined to handle a Complex argument.
  def log10(z)
    if Complex.generic?(z)
      log10!(z)
    else
      log(z)/log!(10)
    end
  end

  def acos(z)
    if Complex.generic?(z) and z >= -1 and z <= 1
      acos!(z)
    else
      -1.0.im * log( z + 1.0.im * sqrt(1.0-z*z) )
    end
  end

  def asin(z)
    if Complex.generic?(z) and z >= -1 and z <= 1
      asin!(z)
    else
      -1.0.im * log( 1.0.im * z + sqrt(1.0-z*z) )
    end
  end

  def atan(z)
    if Complex.generic?(z)
      atan!(z)
    else
      1.0.im * log( (1.0.im+z) / (1.0.im-z) ) / 2.0
    end
  end

  def atan2(y,x)
    if Complex.generic?(y) and Complex.generic?(x)
      atan2!(y,x)
    else
      -1.0.im * log( (x+1.0.im*y) / sqrt(x*x+y*y) )
    end
  end

  def acosh(z)
    if Complex.generic?(z) and z >= 1
      acosh!(z)
    else
      log( z + sqrt(z*z-1.0) )
    end
  end

  def asinh(z)
    if Complex.generic?(z)
      asinh!(z)
    else
      log( z + sqrt(1.0+z*z) )
    end
  end

  def atanh(z)
    if Complex.generic?(z) and z >= -1 and z <= 1
      atanh!(z)
    else
      log( (1.0+z) / (1.0-z) ) / 2.0
    end
  end

  module_function :sqrt!
  module_function :sqrt
  module_function :exp!
  module_function :exp
  module_function :log!
  module_function :log
  module_function :log10!
  module_function :log10
  module_function :cosh!
  module_function :cosh
  module_function :cos!
  module_function :cos
  module_function :sinh!
  module_function :sinh
  module_function :sin!
  module_function :sin
  module_function :tan!
  module_function :tan
  module_function :tanh!
  module_function :tanh
  module_function :acos!
  module_function :acos
  module_function :asin!
  module_function :asin
  module_function :atan!
  module_function :atan
  module_function :atan2!
  module_function :atan2
  module_function :acosh!
  module_function :acosh
  module_function :asinh!
  module_function :asinh
  module_function :atanh!
  module_function :atanh
  
end

# Documentation comments:
#  - source: original (researched from pickaxe)
#  - a couple of fixme's
#  - RDoc output for Bignum etc. is a bit short, with nothing but an
#    (undocumented) alias.  No big deal.
PK     xZ\+      dl/struct.rbnu [        # -*- ruby -*-

require 'dl'
require 'dl/import'

module DL
  module Importable
    module Internal
      def define_struct(contents)
	init_types()
	Struct.new(@types, contents)
      end
      alias struct define_struct

      def define_union(contents)
	init_types()
	Union.new(@types, contents)
      end
      alias union define_union

      class Memory
	def initialize(ptr, names, ty, len, enc, dec)
	  @ptr = ptr
	  @names = names
	  @ty    = ty
	  @len   = len
	  @enc   = enc
	  @dec   = dec

	  # define methods
	  @names.each{|name|
	    instance_eval [
	      "def #{name}",
	      "  v = @ptr[\"#{name}\"]",
	      "  if( @len[\"#{name}\"] )",
	      "    v = v.collect{|x| @dec[\"#{name}\"] ? @dec[\"#{name}\"].call(x) : x }",
              "  else",
	      "    v = @dec[\"#{name}\"].call(v) if @dec[\"#{name}\"]",
	      "  end",
	      "  return v",
	      "end",
	      "def #{name}=(v)",
	      "  if( @len[\"#{name}\"] )",
	      "    v = v.collect{|x| @enc[\"#{name}\"] ? @enc[\"#{name}\"].call(x) : x }",
	      "  else",
	      "    v = @enc[\"#{name}\"].call(v) if @enc[\"#{name}\"]",
              "  end",
	      "  @ptr[\"#{name}\"] = v",
	      "  return v",
	      "end",
	    ].join("\n")
	  }
	end

	def to_ptr
	  return @ptr
	end

	def size
	  return @ptr.size
	end
      end

      class Struct
	def initialize(types, contents)
	  @names = []
	  @ty   = {}
	  @len  = {}
	  @enc  = {}
	  @dec  = {}
	  @size = 0
	  @tys  = ""
	  @types = types
	  parse(contents)
	end

	def size
	  return @size
	end

	def members
	  return @names
	end

	# ptr must be a PtrData object.
	def new(ptr)
	  ptr.struct!(@tys, *@names)
	  mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec)
	  return mem
	end

	def malloc(size = nil)
	  if( !size )
	    size = @size
	  end
	  ptr = DL::malloc(size)
	  return new(ptr)
	end

	def parse(contents)
	  contents.each{|elem|
	    name,ty,num,enc,dec = parse_elem(elem)
	    @names.push(name)
	    @ty[name]  = ty
	    @len[name] = num
	    @enc[name] = enc
	    @dec[name] = dec
	    if( num )
	      @tys += "#{ty}#{num}"
	    else
	      @tys += ty
	    end
	  }
	  @size = DL.sizeof(@tys)
	end
	
	def parse_elem(elem)
	  elem.strip!
	  case elem
	  when /^([\w\d_\*]+)([\*\s]+)([\w\d_]+)$/
	    ty = ($1 + $2).strip
	    name = $3
	    num = nil;
	  when /^([\w\d_\*]+)([\*\s]+)([\w\d_]+)\[(\d+)\]$/
	    ty = ($1 + $2).strip
	    name = $3
	    num = $4.to_i
	  else
	    raise(RuntimeError, "invalid element: #{elem}")
	  end
	  ty,enc,dec = @types.encode_struct_type(ty)
          if( !ty )
            raise(TypeError, "unsupported type: #{ty}")
          end
	  return [name,ty,num,enc,dec]
	end
      end  # class Struct
      
      class Union < Struct
	def new
	  ptr = DL::malloc(@size)
	  ptr.union!(@tys, *@names)
	  mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec)
	  return mem
	end
      end
    end  # module Internal
  end  # module Importable
end  # module DL
PK     xZ\b      dl/types.rbnu [        # -*- ruby -*-

require 'dl'

module DL
  class Types
    TYPES = [
      # FORMAT:
      # ["alias name",
      #  "type name", encoding_method, decoding_method,   for function prototypes
      #  "type name", encoding_method, decoding_method]   for structures (not implemented)
      
      # for Windows
      ["DWORD",  "unsigned long", nil, nil,
                 "unsigned long", nil, nil],
      ["PDWORD", "unsigned long *", nil, nil,
                 "unsigned long *", nil, nil],
      ["WORD",   "unsigned short", nil, nil,
                 "unsigned short", nil, nil],
      ["PWORD",  "unsigned int *", nil, nil,
                 "unsigned int *", nil, nil],
      ["BYTE",   "unsigned char",   nil, nil,
                 "unsigned char", nil, nil],
      ["PBYTE",  "unsigned char *", nil, nil,
                 "unsigned char *", nil, nil],
      ["BOOL",   "ibool", nil, nil,
                 "ibool", nil, nil],
      ["ATOM",   "int", nil, nil,
                 "int", nil, nil],
      ["BYTE",   "unsigned char", nil, nil,
                 "unsigned char", nil, nil],
      ["PBYTE",  "unsigned char *", nil, nil,
                 "unsigned char *", nil, nil],
      ["UINT",   "unsigned int", nil, nil,
                 "unsigned int", nil, nil],
      ["ULONG",  "unsigned long", nil, nil,
                 "unsigned long", nil, nil],
      ["UCHAR",  "unsigned char", nil, nil,
                 "unsigned char", nil, nil],
      ["HANDLE", "unsigned long", nil, nil,
                 "unsigned long", nil, nil],
      ["PHANDLE","void*", nil, nil,
                 "void*", nil, nil],
      ["PVOID",  "void*", nil, nil,
                 "void*", nil, nil],
      ["LPCSTR", "char*", nil, nil,
                 "char*", nil, nil],
      ["HDC",    "unsigned int", nil, nil,
                 "unsigned int", nil, nil],
      ["HWND",   "unsigned int", nil, nil,
                 "unsigned int", nil, nil],
      
      # Others
      ["uint",   "unsigned int", nil, nil,
                 "unsigned int", nil, nil],
      ["u_int",  "unsigned int", nil, nil,
                 "unsigned int", nil, nil],
      ["ulong",  "unsigned long", nil, nil,
                 "unsigned long", nil, nil],
      ["u_long", "unsigned long", nil, nil,
                 "unsigned long", nil, nil],

      # DL::Importable primitive types
      ["ibool",
        "I",
	proc{|v| v ? 1 : 0},
	proc{|v| (v != 0) ? true : false},
        "I",
	proc{|v| v ? 1 : 0 },
	proc{|v| (v != 0) ? true : false} ],
      ["cbool",
        "C",
	proc{|v| v ? 1 : 0},
	proc{|v| (v != 0) ? true : false},
        "C",
	proc{|v,len| v ? 1 : 0},
	proc{|v,len| (v != 0) ? true : false}],
      ["lbool",
        "L",
	proc{|v| v ? 1 : 0},
	proc{|v| (v != 0) ? true : false},
        "L",
	proc{|v,len| v ? 1 : 0},
	proc{|v,len| (v != 0) ? true : false}],
      ["unsigned char",
        "C",
	proc{|v| [v].pack("C").unpack("c")[0]},
	proc{|v| [v].pack("c").unpack("C")[0]},
        "C",
	proc{|v| [v].pack("C").unpack("c")[0]},
	proc{|v| [v].pack("c").unpack("C")[0]}],
      ["unsigned short",
        "H",
	proc{|v| [v].pack("S").unpack("s")[0]},
	proc{|v| [v].pack("s").unpack("S")[0]},
        "H",
	proc{|v| [v].pack("S").unpack("s")[0]},
	proc{|v| [v].pack("s").unpack("S")[0]}],
      ["unsigned int",
        "I",
	proc{|v| [v].pack("I").unpack("i")[0]},
	proc{|v| [v].pack("i").unpack("I")[0]},
        "I",
	proc{|v| [v].pack("I").unpack("i")[0]},
	proc{|v| [v].pack("i").unpack("I")[0]}],
      ["unsigned long",
        "L",
	proc{|v| [v].pack("L").unpack("l")[0]},
	proc{|v| [v].pack("l").unpack("L")[0]},
        "L",
	proc{|v| [v].pack("L").unpack("l")[0]},
	proc{|v| [v].pack("l").unpack("L")[0]}],
      ["unsigned char ref",
        "c",
	proc{|v| [v].pack("C").unpack("c")[0]},
	proc{|v| [v].pack("c").unpack("C")[0]},
	nil, nil, nil],
      ["unsigned int ref",
        "i",
	proc{|v| [v].pack("I").unpack("i")[0]},
	proc{|v| [v].pack("i").unpack("I")[0]},
	nil, nil, nil],
      ["unsigned long ref",
        "l",
	proc{|v| [v].pack("L").unpack("l")[0]},
	proc{|v| [v].pack("l").unpack("L")[0]},
	nil, nil, nil],
      ["char ref",  "c", nil, nil,
                    nil, nil, nil],
      ["short ref", "h", nil, nil,
                    nil, nil, nil],
      ["int ref",   "i", nil, nil,
                    nil, nil, nil],
      ["long ref",  "l", nil, nil,
                    nil, nil, nil],
      ["float ref", "f", nil, nil,
                    nil, nil, nil],
      ["double ref","d", nil, nil,
                    nil, nil, nil],
      ["char",   "C", nil, nil,
                 "C", nil, nil],
      ["short",  "H", nil, nil,
                 "H", nil, nil],
      ["int",    "I", nil, nil,
                 "I", nil, nil],
      ["long",   "L", nil, nil,
                 "L", nil, nil],
      ["float",  "F", nil, nil,
                 "F", nil, nil],
      ["double", "D", nil, nil,
                 "D", nil, nil],
      [/^char\s*\*$/,"s",nil, nil,
                     "S",nil, nil],
      [/^const char\s*\*$/,"S",nil, nil,
                           "S",nil, nil],
      [/^.+\*$/,   "P", nil, nil,
                   "P", nil, nil],
      [/^.+\[\]$/, "a", nil, nil,
                   "a", nil, nil],
      ["void",   "0", nil, nil,
                 nil, nil, nil],
    ]

    def initialize
      init_types()
    end

    def typealias(ty1, ty2, enc=nil, dec=nil, ty3=nil, senc=nil, sdec=nil)
      @TYDEFS.unshift([ty1, ty2, enc, dec, ty3, senc, sdec])
    end

    def init_types
      @TYDEFS = TYPES.dup
    end

    def encode_argument_type(alias_type)
      proc_encode = nil
      proc_decode = nil
      @TYDEFS.each{|aty,ty,enc,dec,_,_,_|
	if( (aty.is_a?(Regexp) && (aty =~ alias_type)) || (aty == alias_type) )
	  alias_type = alias_type.gsub(aty,ty) if ty
          alias_type.strip! if alias_type
	  if( proc_encode )
	    if( enc )
	      conv1 = proc_encode
	      proc_encode = proc{|v| enc.call(conv1.call(v))}
	    end
	  else
	    if( enc )
	      proc_encode = enc
	    end
	  end
	  if( proc_decode )
	    if( dec )
	      conv2 = proc_decode
	      proc_decode = proc{|v| dec.call(conv2.call(v))}
	    end
	  else
	    if( dec )
	      proc_decode = dec
	    end
	  end
	end
      }
      return [alias_type, proc_encode, proc_decode]
    end

    def encode_return_type(ty)
      ty, enc, dec = encode_argument_type(ty)
      return [ty, enc, dec]
    end

    def encode_struct_type(alias_type)
      proc_encode = nil
      proc_decode = nil
      @TYDEFS.each{|aty,_,_,_,ty,enc,dec|
	if( (aty.is_a?(Regexp) && (aty =~ alias_type)) || (aty == alias_type) )
	  alias_type = alias_type.gsub(aty,ty) if ty
          alias_type.strip! if alias_type
	  if( proc_encode )
	    if( enc )
	      conv1 = proc_encode
	      proc_encode = proc{|v| enc.call(conv1.call(v))}
	    end
	  else
	    if( enc )
	      proc_encode = enc
	    end
	  end
	  if( proc_decode )
	    if( dec )
	      conv2 = proc_decode
	      proc_decode = proc{|v| dec.call(conv2.call(v))}
	    end
	  else
	    if( dec )
	      proc_decode = dec
	    end
	  end
	end
      }
      return [alias_type, proc_encode, proc_decode]
    end
  end # end of Types
end
PK     xZ\nI  I    dl/win32.rbnu [        # -*- ruby -*-

require 'dl'

class Win32API
  DLL = {}

  def initialize(dllname, func, import, export = "0")
    prototype = (export + import.to_s).tr("VPpNnLlIi", "0SSI").sub(/^(.)0*$/, '\1')
    handle = DLL[dllname] ||= DL::Handle.new(dllname)
    @sym = handle.sym(func, prototype)
  end

  def call(*args)
    import = @sym.proto.split("", 2)[1]
    args.each_with_index do |x, i|
      args[i] = nil if x == 0 and import[i] == ?S
      args[i], = [x].pack("I").unpack("i") if import[i] == ?I
    end
    ret, = @sym.call(*args)
    return ret || 0
  end

  alias Call call
end
PK     yZ\Y'C      dl/import.rbnu [        # -*- ruby -*-

require 'dl'
require 'dl/types'

module DL
  module Importable
    LIB_MAP = {}

    module Internal
      def init_types()
	@types ||= ::DL::Types.new
      end

      def init_sym()
	@SYM ||= {}
      end

      def [](name)
	return @SYM[name.to_s][0]
      end

      def dlload(*libnames)
	if( !defined?(@LIBS) )
	  @LIBS = []
	end
	libnames.each{|libname|
	  if( !LIB_MAP[libname] )
	    LIB_MAP[libname] = DL.dlopen(libname)
	  end
	  @LIBS.push(LIB_MAP[libname])
	}
      end
      alias dllink :dlload

      def parse_cproto(proto)
	proto = proto.gsub(/\s+/, " ").strip
	case proto
	when /^([\d\w\*_\s]+)\(([\d\w\*_\s\,\[\]]*)\)$/
	  ret = $1
	  args = $2.strip()
	  ret = ret.split(/\s+/)
	  args = args.split(/\s*,\s*/)
	  func = ret.pop()
	  if( func =~ /^\*/ )
	    func.gsub!(/^\*+/,"")
	    ret.push("*")
	  end
	  ret  = ret.join(" ")
	  return [func, ret, args]
	else
	  raise(RuntimeError,"can't parse the function prototype: #{proto}")
	end
      end

      # example:
      #   extern "int strlen(char*)"
      #
      def extern(proto)
	func,ret,args = parse_cproto(proto)
	return import(func, ret, args)
      end

      # example:
      #   callback "int method_name(int, char*)"
      #
      def callback(proto)
	func,ret,args = parse_cproto(proto)

	init_types()
	init_sym()

	rty,renc,rdec = @types.encode_return_type(ret)
        if( !rty )
          raise(TypeError, "unsupported type: #{ret}")
        end
	ty,enc,dec = encode_argument_types(args)
	symty = rty + ty

	module_eval("module_function :#{func}")
	sym = module_eval([
	  "DL::callback(\"#{symty}\"){|*args|",
	  "  sym,rdec,enc,dec  = @SYM['#{func}']",
	  "  args = enc.call(args) if enc",
	  "  r,rs = #{func}(*args)",
	  "  r  = renc.call(r) if rdec",
	  "  rs = dec.call(rs) if (dec && rs)",
	  "  @retval = r",
	  "  @args   = rs",
	  "  r",
	  "}",
	].join("\n"))

	@SYM[func] = [sym,rdec,enc,dec]

	return sym
      end

      # example:
      #  typealias("uint", "unsigned int")
      #
      def typealias(alias_type, ty1, enc1=nil, dec1=nil, ty2=nil, enc2=nil, dec2=nil)
	init_types()
	@types.typealias(alias_type, ty1, enc1, dec1,
                                     ty2||ty1, enc2, dec2)
      end

      # example:
      #  symbol "foo_value"
      #  symbol "foo_func", "IIP"
      #
      def symbol(name, ty = nil)
	sym = nil
	@LIBS.each{|lib|
	  begin
	    if( ty )
	      sym = lib[name, ty]
	    else
	      sym = lib[name]
	    end
	  rescue
	    next
	  end
	}
	if( !sym )
	  raise(RuntimeError, "can't find the symbol `#{name}'")
	end
	return sym
      end

      # example:
      #   import("get_length", "int", ["void*", "int"])
      #
      def import(name, rettype, argtypes = nil)
	init_types()
	init_sym()

	rty,_,rdec = @types.encode_return_type(rettype)
        if( !rty )
          raise(TypeError, "unsupported type: #{rettype}")
        end
	ty,enc,dec = encode_argument_types(argtypes)
	symty = rty + ty

	sym = symbol(name, symty)

	mname = name.dup
	if( ?A <= mname[0] && mname[0] <= ?Z )
	  mname[0,1] = mname[0,1].downcase
	end
	@SYM[mname] = [sym,rdec,enc,dec]
	
	module_eval [
	  "def #{mname}(*args)",
	  "  sym,rdec,enc,dec  = @SYM['#{mname}']",
	  "  args = enc.call(args) if enc",
	  if( $DEBUG )
	    "  p \"[DL] call #{mname} with \#{args.inspect}\""
	  else
	    ""
	  end,
	  "  r,rs = sym.call(*args)",
	  if( $DEBUG )
	    "  p \"[DL] retval=\#{r.inspect} args=\#{rs.inspect}\""
	  else
	    ""
	  end,
	  "  r  = rdec.call(r) if rdec",
	  "  rs = dec.call(rs) if dec",
	  "  @retval = r",
	  "  @args   = rs",
	  "  return r",
	  "end",
	  "module_function :#{mname}",
	].join("\n")

	return sym
      end

      def _args_
	return @args
      end

      def _retval_
	return @retval
      end

      def encode_argument_types(tys)
	init_types()
	encty = []
	enc = nil
	dec = nil
	tys.each_with_index{|ty,idx|
	  ty,c1,c2 = @types.encode_argument_type(ty)
          if( !ty )
            raise(TypeError, "unsupported type: #{ty}")
          end
	  encty.push(ty)
	  if( enc )
	    if( c1 )
	      conv1 = enc
	      enc = proc{|v| v = conv1.call(v); v[idx] = c1.call(v[idx]); v}
	    end
	  else
	    if( c1 )
	      enc = proc{|v| v[idx] = c1.call(v[idx]); v}
	    end
	  end
	  if( dec )
	    if( c2 )
	      conv2 = dec
	      dec = proc{|v| v = conv2.call(v); v[idx] = c2.call(v[idx]); v}
	    end
	  else
	    if( c2 )
	      dec = proc{|v| v[idx] = c2.call(v[idx]); v}
	    end
	  end
	}
	return [encty.join, enc, dec]
      end
    end # end of Internal
    include Internal
  end # end of Importable
end
PK     zZ\"g0  0    jcode.rbnu [        # jcode.rb - ruby code to handle japanese (EUC/SJIS) string

if $VERBOSE && $KCODE == "NONE"
  warn "Warning: $KCODE is NONE."
end

$vsave, $VERBOSE = $VERBOSE, false
class String
  warn "feel free for some warnings:\n" if $VERBOSE

  def _regex_quote(str)
    str.gsub(/(\\[\[\]\-\\])|\\(.)|([\[\]\\])/) do
      $1 || $2 || '\\' + $3
    end
  end
  private :_regex_quote

  PATTERN_SJIS = '[\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc]'
  PATTERN_EUC = '[\xa1-\xfe][\xa1-\xfe]'
  PATTERN_UTF8 = '[\xc0-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf][\x80-\xbf]'

  RE_SJIS = Regexp.new(PATTERN_SJIS, 0, 'n')
  RE_EUC = Regexp.new(PATTERN_EUC, 0, 'n')
  RE_UTF8 = Regexp.new(PATTERN_UTF8, 0, 'n')

  SUCC = {}
  SUCC['s'] = Hash.new(1)
  for i in 0 .. 0x3f
    SUCC['s'][i.chr] = 0x40 - i
  end
  SUCC['s']["\x7e"] = 0x80 - 0x7e
  SUCC['s']["\xfd"] = 0x100 - 0xfd
  SUCC['s']["\xfe"] = 0x100 - 0xfe
  SUCC['s']["\xff"] = 0x100 - 0xff
  SUCC['e'] = Hash.new(1)
  for i in 0 .. 0xa0
    SUCC['e'][i.chr] = 0xa1 - i
  end
  SUCC['e']["\xfe"] = 2
  SUCC['u'] = Hash.new(1)
  for i in 0 .. 0x7f
    SUCC['u'][i.chr] = 0x80 - i
  end
  SUCC['u']["\xbf"] = 0x100 - 0xbf

  def mbchar?
    case $KCODE[0]
    when ?s, ?S
      self =~ RE_SJIS
    when ?e, ?E
      self =~ RE_EUC
    when ?u, ?U
      self =~ RE_UTF8
    else
      nil
    end
  end

  def end_regexp
    case $KCODE[0]
    when ?s, ?S
      /#{PATTERN_SJIS}$/on
    when ?e, ?E
      /#{PATTERN_EUC}$/on
    when ?u, ?U
      /#{PATTERN_UTF8}$/on
    else
      /.$/on
    end
  end

  alias original_succ! succ!
  private :original_succ!

  alias original_succ succ
  private :original_succ

  def succ!
    reg = end_regexp
    if  $KCODE != 'NONE' && self =~ reg
      succ_table = SUCC[$KCODE[0,1].downcase]
      begin
	self[-1] += succ_table[self[-1]]
	self[-2] += 1 if self[-1] == 0
      end while self !~ reg
      self
    else
      original_succ!
    end
  end

  def succ
    str = self.dup
    str.succ! or str
  end

  private

  def _expand_ch str
    a = []
    str.scan(/(?:\\(.)|([^\\]))-(?:\\(.)|([^\\]))|(?:\\(.)|(.))/m) do
      from = $1 || $2
      to = $3 || $4
      one = $5 || $6
      if one
	a.push one
      elsif from.length != to.length
	next
      elsif from.length == 1
	from[0].upto(to[0]) { |c| a.push c.chr }
      else
	from.upto(to) { |c| a.push c }
      end
    end
    a
  end

  def expand_ch_hash from, to
    h = {}
    afrom = _expand_ch(from)
    ato = _expand_ch(to)
    afrom.each_with_index do |x,i| h[x] = ato[i] || ato[-1] end
    h
  end

  HashCache = {}
  TrPatternCache = {}
  DeletePatternCache = {}
  SqueezePatternCache = {}

  public

  def tr!(from, to)
    return nil if from == ""
    return self.delete!(from) if to == ""

    pattern = TrPatternCache[from] ||= /[#{_regex_quote(from)}]/
    if from[0] == ?^
      last = /.$/.match(to)[0]
      self.gsub!(pattern, last)
    else
      h = HashCache[from + "1-0" + to] ||= expand_ch_hash(from, to)
      self.gsub!(pattern) do |c| h[c] end
    end
  end

  def tr(from, to)
    (str = self.dup).tr!(from, to) or str
  end

  def delete!(del)
    return nil if del == ""
    self.gsub!(DeletePatternCache[del] ||= /[#{_regex_quote(del)}]+/, '')
  end

  def delete(del)
    (str = self.dup).delete!(del) or str
  end

  def squeeze!(del=nil)
    return nil if del == ""
    pattern =
      if del
	SqueezePatternCache[del] ||= /([#{_regex_quote(del)}])\1+/
      else
	/(.|\n)\1+/
      end
    self.gsub!(pattern, '\1')
  end

  def squeeze(del=nil)
    (str = self.dup).squeeze!(del) or str
  end

  def tr_s!(from, to)
    return self.delete!(from) if to.length == 0

    pattern = SqueezePatternCache[from] ||= /([#{_regex_quote(from)}])\1*/
    if from[0] == ?^
      last = /.$/.match(to)[0]
      self.gsub!(pattern, last)
    else
      h = HashCache[from + "1-0" + to] ||= expand_ch_hash(from, to)
      self.gsub!(pattern) do h[$1] end
    end
  end

  def tr_s(from, to)
    (str = self.dup).tr_s!(from,to) or str
  end

  def chop!
    self.gsub!(/(?:.|\r?\n)\z/, '')
  end

  def chop
    (str = self.dup).chop! or str
  end

  def jlength
    self.gsub(/[^\Wa-zA-Z_\d]/, ' ').length
  end
  alias jsize jlength

  def jcount(str)
    self.delete("^#{str}").jlength
  end

  def each_char
    if block_given?
      scan(/./m) do |x|
        yield x
      end
    else
      scan(/./m)
    end
  end

end
$VERBOSE = $vsave
PK     {Z\2Vi  i    test/unit/collector.rbnu [        module Test
  module Unit
    module Collector
      def initialize
        @filters = []
      end

      def filter=(filters)
        @filters = case(filters)
          when Proc
            [filters]
          when Array
            filters
        end
      end

      def add_suite(destination, suite)
        to_delete = suite.tests.find_all{|t| !include?(t)}
        to_delete.each{|t| suite.delete(t)}
        destination << suite unless(suite.size == 0)
      end

      def include?(test)
        return true if(@filters.empty?)
        @filters.each do |filter|
          result = filter[test]
          if(result.nil?)
            next
          elsif(!result)
            return false
          else
            return true
          end
        end
        true
      end

      def sort(suites)
        suites.sort_by{|s| s.name}
      end
    end
  end
end
PK     |Z\=!n  n    test/unit/collector/dir.rbnu [        require 'test/unit/testsuite'
require 'test/unit/collector'

module Test
  module Unit
    module Collector
      class Dir
        include Collector

        attr_reader :pattern, :exclude
        attr_accessor :base

        def initialize(dir=::Dir, file=::File, object_space=::ObjectSpace, req=nil)
          super()
          @dir = dir
          @file = file
          @object_space = object_space
          @req = req
          @pattern = [/\btest_.*\.rb\Z/m]
          @exclude = []
        end

        def collect(*from)
          basedir = @base
          $:.push(basedir) if basedir
          if(from.empty?)
            recursive_collect('.', find_test_cases)
          elsif(from.size == 1)
            recursive_collect(from.first, find_test_cases)
          else
            suites = []
            from.each do |f|
              suite = recursive_collect(f, find_test_cases)
              suites << suite unless(suite.tests.empty?)
            end
            suite = TestSuite.new("[#{from.join(', ')}]")
            sort(suites).each{|s| suite << s}
            suite
          end
        ensure
          $:.delete_at($:.rindex(basedir)) if basedir
        end

        def find_test_cases(ignore=[])
          cases = []
          @object_space.each_object(Class) do |c|
            cases << c if(c < TestCase && !ignore.include?(c))
          end
          ignore.concat(cases)
          cases
        end

        def recursive_collect(name, already_gathered)
          sub_suites = []
          path = realdir(name)
          if @file.directory?(path)
	    dir_name = name unless name == '.'
            @dir.entries(path).each do |e|
              next if(e == '.' || e == '..')
              e_name = dir_name ? @file.join(dir_name, e) : e
              if @file.directory?(realdir(e_name))
                next if /\ACVS\z/ =~ e
                sub_suite = recursive_collect(e_name, already_gathered)
                sub_suites << sub_suite unless(sub_suite.empty?)
              else
                next if /~\z/ =~ e_name or /\A\.\#/ =~ e
                if @pattern and !@pattern.empty?
                  next unless @pattern.any? {|pat| pat =~ e_name}
                end
                if @exclude and !@exclude.empty?
                  next if @exclude.any? {|pat| pat =~ e_name}
                end
                collect_file(e_name, sub_suites, already_gathered)
              end
            end
          else
            collect_file(name, sub_suites, already_gathered)
          end
          suite = TestSuite.new(@file.basename(name))
          sort(sub_suites).each{|s| suite << s}
          suite
        end

        def collect_file(name, suites, already_gathered)
          dir = @file.dirname(@file.expand_path(name, @base))
          $:.unshift(dir)
          if(@req)
            @req.require(name)
          else
            require(name)
          end
          find_test_cases(already_gathered).each{|t| add_suite(suites, t.suite)}
        ensure
          $:.delete_at($:.rindex(dir)) if(dir)
        end

	def realdir(path)
	  if @base
	    @file.join(@base, path)
	  else
	    path
	  end
	end
      end
    end
  end
end
PK     }Z\+  +  "  test/unit/collector/objectspace.rbnu [        # Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit/collector'

module Test
  module Unit
    module Collector
      class ObjectSpace
        include Collector
        
        NAME = 'collected from the ObjectSpace'
        
        def initialize(source=::ObjectSpace)
          super()
          @source = source
        end
        
        def collect(name=NAME)
          suite = TestSuite.new(name)
          sub_suites = []
          @source.each_object(Class) do |klass|
            if(Test::Unit::TestCase > klass)
              add_suite(sub_suites, klass.suite)
            end
          end
          sort(sub_suites).each{|s| suite << s}
          suite
        end
      end
    end
  end
end
PK     }Z\2>  >    test/unit/ui/gtk2/testrunner.rbnu [        #--
#
# Author:: Kenta MURATA.
# Copyright:: Copyright (c) 2000-2002 Kenta MURATA. All rights reserved.
# License:: Ruby license.

require "gtk2"
require "test/unit/ui/testrunnermediator"
require "test/unit/ui/testrunnerutilities"

module Test
  module Unit
    module UI
      module GTK2

        Gtk.init

        class EnhancedLabel < Gtk::Label
          def set_text(text)
            super(text.gsub(/\n\t/, "\n    "))
          end
        end

        class FaultList < Gtk::TreeView
          def initialize
            @faults = []
            @model = Gtk::ListStore.new(String, String)
            super(@model)
            column = Gtk::TreeViewColumn.new
            column.visible = false
            append_column(column)
            renderer = Gtk::CellRendererText.new
            column = Gtk::TreeViewColumn.new("Failures", renderer, {:text => 1})
            append_column(column)
            selection.mode = Gtk::SELECTION_SINGLE
            set_rules_hint(true)
            set_headers_visible(false)
          end # def initialize

          def add_fault(fault)
            @faults.push(fault)
            iter = @model.append
            iter.set_value(0, (@faults.length - 1).to_s)
            iter.set_value(1, fault.short_display)
          end # def add_fault(fault)

          def get_fault(iter)
            @faults[iter.get_value(0).to_i]
          end # def get_fault

          def clear
            model.clear
          end # def clear
        end

        class TestRunner
          extend TestRunnerUtilities

          def lazy_initialize(symbol)
            if !instance_eval("defined?(@#{symbol})") then
              yield
            end
            return instance_eval("@#{symbol}")
          end
          private :lazy_initialize

          def status_entry
            lazy_initialize(:status_entry) do
              @status_entry = Gtk::Entry.new
              @status_entry.editable = false
            end
          end
          private :status_entry

          def status_panel
            lazy_initialize(:status_panel) do
              @status_panel = Gtk::HBox.new
              @status_panel.border_width = 10
              @status_panel.pack_start(status_entry, true, true, 0)
            end
          end
          private :status_panel

          def fault_detail_label
            lazy_initialize(:fault_detail_label) do
              @fault_detail_label = EnhancedLabel.new("")
#              style = Gtk::Style.new
#              font = Gdk::Font.
#               font_load("-*-Courier 10 Pitch-medium-r-normal--*-120-*-*-*-*-*-*")
#              style.set_font(font)
#              @fault_detail_label.style = style
              @fault_detail_label.justify = Gtk::JUSTIFY_LEFT
              @fault_detail_label.wrap = false
            end
          end
          private :fault_detail_label

          def inner_detail_sub_panel
            lazy_initialize(:inner_detail_sub_panel) do
              @inner_detail_sub_panel = Gtk::HBox.new
              @inner_detail_sub_panel.pack_start(fault_detail_label, false, false, 0)
            end
          end
          private :inner_detail_sub_panel

          def outer_detail_sub_panel
            lazy_initialize(:outer_detail_sub_panel) do
              @outer_detail_sub_panel = Gtk::VBox.new
              @outer_detail_sub_panel.pack_start(inner_detail_sub_panel, false, false, 0)
            end
          end
          private :outer_detail_sub_panel

          def detail_scrolled_window
            lazy_initialize(:detail_scrolled_window) do
              @detail_scrolled_window = Gtk::ScrolledWindow.new
              @detail_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
              @detail_scrolled_window.
                set_size_request(400, @detail_scrolled_window.allocation.height)
              @detail_scrolled_window.add_with_viewport(outer_detail_sub_panel)
            end
          end
          private :detail_scrolled_window

          def detail_panel
            lazy_initialize(:detail_panel) do
              @detail_panel = Gtk::HBox.new
              @detail_panel.border_width = 10
              @detail_panel.pack_start(detail_scrolled_window, true, true, 0)
            end
          end
          private :detail_panel

          def fault_list
            lazy_initialize(:fault_list) do
              @fault_list = FaultList.new
            end
          end
          private :fault_list

          def list_scrolled_window
            lazy_initialize(:list_scrolled_window) do
              @list_scrolled_window = Gtk::ScrolledWindow.new
              @list_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
              @list_scrolled_window.
                set_size_request(@list_scrolled_window.allocation.width, 150)
              @list_scrolled_window.add_with_viewport(fault_list)
            end
          end
          private :list_scrolled_window

          def list_panel
            lazy_initialize(:list_panel) do
              @list_panel = Gtk::HBox.new
              @list_panel.border_width = 10
              @list_panel.pack_start(list_scrolled_window, true, true, 0)
            end
          end
          private :list_panel

          def error_count_label
            lazy_initialize(:error_count_label) do
              @error_count_label = Gtk::Label.new("0")
              @error_count_label.justify = Gtk::JUSTIFY_LEFT
            end
          end
          private :error_count_label

          def failure_count_label
            lazy_initialize(:failure_count_label) do
              @failure_count_label = Gtk::Label.new("0")
              @failure_count_label.justify = Gtk::JUSTIFY_LEFT
            end
          end
          private :failure_count_label

          def assertion_count_label
            lazy_initialize(:assertion_count_label) do
              @assertion_count_label = Gtk::Label.new("0")
              @assertion_count_label.justify = Gtk::JUSTIFY_LEFT
            end
          end
          private :assertion_count_label

          def run_count_label
            lazy_initialize(:run_count_label) do
              @run_count_label = Gtk::Label.new("0")
              @run_count_label.justify = Gtk::JUSTIFY_LEFT
            end
          end
          private :run_count_label
          
          def info_panel
            lazy_initialize(:info_panel) do
              @info_panel = Gtk::HBox.new(false, 0)
              @info_panel.border_width = 10
              @info_panel.pack_start(Gtk::Label.new("Runs:"), false, false, 0)
              @info_panel.pack_start(run_count_label, true, false, 0)
              @info_panel.pack_start(Gtk::Label.new("Assertions:"), false, false, 0)
              @info_panel.pack_start(assertion_count_label, true, false, 0)
              @info_panel.pack_start(Gtk::Label.new("Failures:"), false, false, 0)
              @info_panel.pack_start(failure_count_label, true, false, 0)
              @info_panel.pack_start(Gtk::Label.new("Errors:"), false, false, 0)
              @info_panel.pack_start(error_count_label, true, false, 0)
            end
          end # def info_panel
          private :info_panel

          def green_style
            lazy_initialize(:green_style) do
              @green_style = Gtk::Style.new
              @green_style.set_bg(Gtk::STATE_PRELIGHT, 0x0000, 0xFFFF, 0x0000)
            end
          end # def green_style
          private :green_style
          
          def red_style
            lazy_initialize(:red_style) do
              @red_style = Gtk::Style.new
              @red_style.set_bg(Gtk::STATE_PRELIGHT, 0xFFFF, 0x0000, 0x0000)
            end
          end # def red_style
          private :red_style
          
          def test_progress_bar
            lazy_initialize(:test_progress_bar) {
              @test_progress_bar = Gtk::ProgressBar.new
              @test_progress_bar.fraction = 0.0
              @test_progress_bar.
                set_size_request(@test_progress_bar.allocation.width,
                                 info_panel.size_request[1])
              @test_progress_bar.style = green_style
            }
          end # def test_progress_bar
          private :test_progress_bar
          
          def progress_panel
            lazy_initialize(:progress_panel) do
              @progress_panel = Gtk::HBox.new(false, 10)
              @progress_panel.border_width = 10
              @progress_panel.pack_start(test_progress_bar, true, true, 0)
            end
          end # def progress_panel

          def run_button
            lazy_initialize(:run_button) do
              @run_button = Gtk::Button.new("Run")
            end
          end # def run_button

          def suite_name_entry
            lazy_initialize(:suite_name_entry) do
              @suite_name_entry = Gtk::Entry.new
              @suite_name_entry.editable = false
            end
          end # def suite_name_entry
          private :suite_name_entry

          def suite_panel
            lazy_initialize(:suite_panel) do
              @suite_panel = Gtk::HBox.new(false, 10)
              @suite_panel.border_width = 10
              @suite_panel.pack_start(Gtk::Label.new("Suite:"), false, false, 0)
              @suite_panel.pack_start(suite_name_entry, true, true, 0)
              @suite_panel.pack_start(run_button, false, false, 0)
            end
          end # def suite_panel
          private :suite_panel

          def main_panel
            lazy_initialize(:main_panel) do
              @main_panel = Gtk::VBox.new(false, 0)
              @main_panel.pack_start(suite_panel, false, false, 0)
              @main_panel.pack_start(progress_panel, false, false, 0)
              @main_panel.pack_start(info_panel, false, false, 0)
              @main_panel.pack_start(list_panel, false, false, 0)
              @main_panel.pack_start(detail_panel, true, true, 0)
              @main_panel.pack_start(status_panel, false, false, 0)
            end
          end # def main_panel
          private :main_panel

          def main_window
            lazy_initialize(:main_window) do
              @main_window = Gtk::Window.new(Gtk::Window::TOPLEVEL)
              @main_window.set_title("Test::Unit TestRunner")
              @main_window.set_default_size(800, 600)
              @main_window.set_resizable(true)
              @main_window.add(main_panel)
            end
          end # def main_window
          private :main_window

          def setup_ui
            main_window.signal_connect("destroy", nil) { stop }
            main_window.show_all
            fault_list.selection.signal_connect("changed", nil) do
              |selection, data|
              if selection.selected then
                show_fault(fault_list.get_fault(selection.selected))
              else
                clear_fault
              end
            end
          end # def setup_ui
          private :setup_ui

          def output_status(string)
            status_entry.set_text(string)
          end # def output_status(string)
          private :output_status

          def finished(elapsed_time)
            test_progress_bar.fraction = 1.0
            output_status("Finished in #{elapsed_time} seconds")
          end # def finished(elapsed_time)
          private :finished

          def test_started(test_name)
            output_status("Running #{test_name}...")
          end # def test_started(test_name)
          private :test_started

          def started(result)
            @result = result
            output_status("Started...")
          end # def started(result)
          private :started

          def test_finished(result)
            test_progress_bar.fraction += 1.0 / @count
          end # def test_finished(result)

          def result_changed(result)
            run_count_label.label = result.run_count.to_s
            assertion_count_label.label = result.assertion_count.to_s
            failure_count_label.label = result.failure_count.to_s
            error_count_label.label = result.error_count.to_s
          end # def result_changed(result)
          private :result_changed

          def clear_fault
            raw_show_fault("")
          end # def clear_fault
          private :clear_fault

          def raw_show_fault(string)
            fault_detail_label.set_text(string)
            outer_detail_sub_panel.queue_resize
          end # def raw_show_fault(string)
          private :raw_show_fault

          def show_fault(fault)
            raw_show_fault(fault.long_display)
          end # def show_fault(fault)
          private :show_fault

          def add_fault(fault)
            if not @red then
              test_progress_bar.style = red_style
              @red = true
            end
            fault_list.add_fault(fault)
          end # def add_fault(fault)
          private :add_fault

          def reset_ui(count)
            test_progress_bar.style = green_style
            test_progress_bar.fraction = 0.0
            @count = count + 1
            @red = false

            run_count_label.set_text("0")
            assertion_count_label.set_text("0")
            failure_count_label.set_text("0")
            error_count_label.set_text("0")

            fault_list.clear
          end # def reset_ui(count)
          private :reset_ui

          def stop
            Gtk.main_quit
          end # def stop
          private :stop

          def run_test
            @runner.raise(@restart_signal)
          end
          private :run_test

          def start_ui
            @viewer.run
            running = false
            begin
              loop do
                if (running ^= true)
                  run_button.child.text = "Stop"
                  @mediator.run_suite
                else
                  run_button.child.text = "Run"
                  @viewer.join
                  break
                end
              end
            rescue @restart_signal
              retry
            rescue
            end
          end # def start_ui
          private :start_ui

          def attach_to_mediator
            run_button.signal_connect("clicked", nil) { run_test }
            @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))
            @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
            @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))
            @mediator.add_listener(TestResult::FAULT, &method(:add_fault))
            @mediator.add_listener(TestResult::CHANGED, &method(:result_changed))
            @mediator.add_listener(TestCase::STARTED, &method(:test_started))
            @mediator.add_listener(TestCase::FINISHED, &method(:test_finished))
          end # def attach_to_mediator
          private :attach_to_mediator

          def setup_mediator
            @mediator = TestRunnerMediator.new(@suite)
            suite_name = @suite.to_s
            if @suite.kind_of?(Module) then
              suite_name = @suite.name
            end
            suite_name_entry.set_text(suite_name)
          end # def setup_mediator
          private :setup_mediator

          def start
            setup_mediator
            setup_ui
            attach_to_mediator
            start_ui
            @result
          end # def start

          def initialize(suite, output_level = NORMAL)
            if suite.respond_to?(:suite) then
              @suite = suite.suite
            else
              @suite = suite
            end
            @result = nil

            @runner = Thread.current
            @restart_signal = Class.new(Exception)
            @viewer = Thread.start do
              @runner.join rescue @runner.run
              Gtk.main
            end
            @viewer.join rescue nil # wait deadlock to handshake
          end # def initialize(suite)

        end # class TestRunner

      end # module GTK2
    end # module UI
  end # module Unit
end # module Test
PK     Z\` Dc"  c"    test/unit/ui/tk/testrunner.rbnu [        #--
#
# Original Author:: Nathaniel Talbott.
# Author:: Kazuhiro NISHIYAMA.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# Copyright:: Copyright (c) 2003 Kazuhiro NISHIYAMA. All rights reserved.
# License:: Ruby license.

require 'tk'
require 'test/unit/ui/testrunnermediator'
require 'test/unit/ui/testrunnerutilities'

module Test
  module Unit
    module UI
      module Tk

        # Runs a Test::Unit::TestSuite in a Tk UI. Obviously,
        # this one requires you to have Tk
        # and the Ruby Tk extension installed.
        class TestRunner
          extend TestRunnerUtilities

          # Creates a new TestRunner for running the passed
          # suite.
          def initialize(suite, output_level = NORMAL)
            if (suite.respond_to?(:suite))
              @suite = suite.suite
            else
              @suite = suite
            end
            @result = nil

            @red = false
            @fault_detail_list = []
            @runner = Thread.current
            @restart_signal = Class.new(Exception)
            @viewer = Thread.start do
              @runner.join rescue @runner.run
              ::Tk.mainloop
            end
            @viewer.join rescue nil # wait deadlock to handshake
          end

          # Begins the test run.
          def start
            setup_ui
            setup_mediator
            attach_to_mediator
            start_ui
            @result
          end

          private
          def setup_mediator
            @mediator = TestRunnerMediator.new(@suite)
            suite_name = @suite.to_s
            if ( @suite.kind_of?(Module) )
              suite_name = @suite.name
            end
            @suite_name_entry.value = suite_name
          end

          def attach_to_mediator
            @run_button.command(method(:run_test))
            @fault_list.bind('ButtonPress-1', proc{|y|
              fault = @fault_detail_list[@fault_list.nearest(y)]
              if fault
                show_fault(fault)
              end
            }, '%y')
            @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))
            @mediator.add_listener(TestResult::FAULT, &method(:add_fault))
            @mediator.add_listener(TestResult::CHANGED, &method(:result_changed))
            @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
            @mediator.add_listener(TestCase::STARTED, &method(:test_started))
            @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))
          end

          def run_test
            @runner.raise(@restart_signal)
          end

          def start_ui
            @viewer.run
            running = false
            begin
              loop do
                if (running ^= true)
                  @run_button.configure('text'=>'Stop')
                  @mediator.run_suite
                else
                  @run_button.configure('text'=>'Run')
                  @viewer.join
                  break
                end
              end
            rescue @restart_signal
              retry
            rescue
            end
          end

          def stop
            ::Tk.exit
          end

          def reset_ui(count)
            @test_total_count = count.to_f
            @test_progress_bar.configure('background'=>'green')
            @test_progress_bar.place('relwidth'=>(count.zero? ? 0 : 0/count))
            @red = false

            @test_count_label.value = 0
            @assertion_count_label.value = 0
            @failure_count_label.value = 0
            @error_count_label.value = 0

            @fault_list.delete(0, 'end')
            @fault_detail_list = []
            clear_fault
          end

          def add_fault(fault)
            if ( ! @red )
              @test_progress_bar.configure('background'=>'red')
              @red = true
            end
            @fault_detail_list.push fault
            @fault_list.insert('end', fault.short_display)
          end

          def show_fault(fault)
            raw_show_fault(fault.long_display)
          end

          def raw_show_fault(string)
            @detail_text.value = string
          end

          def clear_fault
            raw_show_fault("")
          end

          def result_changed(result)
            @test_count_label.value = result.run_count
            @test_progress_bar.place('relwidth'=>result.run_count/@test_total_count)
            @assertion_count_label.value = result.assertion_count
            @failure_count_label.value = result.failure_count
            @error_count_label.value = result.error_count
          end

          def started(result)
            @result = result
            output_status("Started...")
          end

          def test_started(test_name)
            output_status("Running #{test_name}...")
          end

          def finished(elapsed_time)
            output_status("Finished in #{elapsed_time} seconds")
          end

          def output_status(string)
            @status_entry.value = string
          end

          def setup_ui
            @status_entry = TkVariable.new
            l = TkLabel.new(nil, 'textvariable'=>@status_entry, 'relief'=>'sunken')
            l.pack('side'=>'bottom', 'fill'=>'x')

            suite_frame = TkFrame.new.pack('fill'=>'x')

            @run_button = TkButton.new(suite_frame, 'text'=>'Run')
            @run_button.pack('side'=>'right')

            TkLabel.new(suite_frame, 'text'=>'Suite:').pack('side'=>'left')
            @suite_name_entry = TkVariable.new
            l = TkLabel.new(suite_frame, 'textvariable'=>@suite_name_entry, 'relief'=>'sunken')
            l.pack('side'=>'left', 'fill'=>'x', 'expand'=>true)

            f = TkFrame.new(nil, 'relief'=>'sunken', 'borderwidth'=>3, 'height'=>20).pack('fill'=>'x', 'padx'=>1)
            @test_progress_bar = TkFrame.new(f, 'background'=>'green').place('anchor'=>'nw', 'relwidth'=>0.0, 'relheight'=>1.0)

            info_frame = TkFrame.new.pack('fill'=>'x')
            @test_count_label = create_count_label(info_frame, 'Tests:')
            @assertion_count_label = create_count_label(info_frame, 'Assertions:')
            @failure_count_label = create_count_label(info_frame, 'Failures:')
            @error_count_label = create_count_label(info_frame, 'Errors:')

	    if (::Tk.info('command', TkPanedWindow::TkCommandNames[0]) != "")
	      # use panedwindow
	      paned_frame = TkPanedWindow.new("orient"=>"vertical").pack('fill'=>'both', 'expand'=>true)

	      fault_list_frame = TkFrame.new(paned_frame)
	      detail_frame = TkFrame.new(paned_frame)

	      paned_frame.add(fault_list_frame, detail_frame)
	    else
	      # no panedwindow
	      paned_frame = nil
	      fault_list_frame = TkFrame.new.pack('fill'=>'both', 'expand'=>true)
	      detail_frame = TkFrame.new.pack('fill'=>'both', 'expand'=>true)
	    end

	    TkGrid.rowconfigure(fault_list_frame, 0, 'weight'=>1, 'minsize'=>0)
	    TkGrid.columnconfigure(fault_list_frame, 0, 'weight'=>1, 'minsize'=>0)

            fault_scrollbar_y = TkScrollbar.new(fault_list_frame)
            fault_scrollbar_x = TkScrollbar.new(fault_list_frame)
            @fault_list = TkListbox.new(fault_list_frame)
            @fault_list.yscrollbar(fault_scrollbar_y)
            @fault_list.xscrollbar(fault_scrollbar_x)

	    TkGrid.rowconfigure(detail_frame, 0, 'weight'=>1, 'minsize'=>0)
	    TkGrid.columnconfigure(detail_frame, 0, 'weight'=>1, 'minsize'=>0)

	    ::Tk.grid(@fault_list, fault_scrollbar_y, 'sticky'=>'news')
	    ::Tk.grid(fault_scrollbar_x, 'sticky'=>'news')

            detail_scrollbar_y = TkScrollbar.new(detail_frame)
            detail_scrollbar_x = TkScrollbar.new(detail_frame)
            @detail_text = TkText.new(detail_frame, 'height'=>10, 'wrap'=>'none') {
              bindtags(bindtags - [TkText])
	    }
	    @detail_text.yscrollbar(detail_scrollbar_y)
	    @detail_text.xscrollbar(detail_scrollbar_x)

	    ::Tk.grid(@detail_text, detail_scrollbar_y, 'sticky'=>'news')
	    ::Tk.grid(detail_scrollbar_x, 'sticky'=>'news')

	    # rubber-style pane
	    if paned_frame
	      ::Tk.update
	      @height = paned_frame.winfo_height
	      paned_frame.bind('Configure', proc{|h|
		paned_frame.sash_place(0, 0, paned_frame.sash_coord(0)[1] * h / @height)
		@height = h
	      }, '%h')
	    end
          end

          def create_count_label(parent, label)
            TkLabel.new(parent, 'text'=>label).pack('side'=>'left', 'expand'=>true)
            v = TkVariable.new(0)
            TkLabel.new(parent, 'textvariable'=>v).pack('side'=>'left', 'expand'=>true)
            v
          end
        end
      end
    end
  end
end

if __FILE__ == $0
  Test::Unit::UI::Tk::TestRunner.start_command_line_test
end
PK     Z\00  0  "  test/unit/ui/testrunnermediator.rbnu [        #--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit'
require 'test/unit/util/observable'
require 'test/unit/testresult'

module Test
  module Unit
    module UI

      # Provides an interface to write any given UI against,
      # hopefully making it easy to write new UIs.
      class TestRunnerMediator
        RESET = name + "::RESET"
        STARTED = name + "::STARTED"
        FINISHED = name + "::FINISHED"
        
        include Util::Observable
        
        # Creates a new TestRunnerMediator initialized to run
        # the passed suite.
        def initialize(suite)
          @suite = suite
        end

        # Runs the suite the TestRunnerMediator was created
        # with.
        def run_suite
          Unit.run = true
          begin_time = Time.now
          notify_listeners(RESET, @suite.size)
          result = create_result
          notify_listeners(STARTED, result)
          result_listener = result.add_listener(TestResult::CHANGED) do |updated_result|
            notify_listeners(TestResult::CHANGED, updated_result)
          end
          
          fault_listener = result.add_listener(TestResult::FAULT) do |fault|
            notify_listeners(TestResult::FAULT, fault)
          end
          
          @suite.run(result) do |channel, value|
            notify_listeners(channel, value)
          end
          
          result.remove_listener(TestResult::FAULT, fault_listener)
          result.remove_listener(TestResult::CHANGED, result_listener)
          end_time = Time.now
          elapsed_time = end_time - begin_time
          notify_listeners(FINISHED, elapsed_time) #"Finished in #{elapsed_time} seconds.")
          return result
        end

        private
        # A factory method to create the result the mediator
        # should run with. Can be overridden by subclasses if
        # one wants to use a different result.
        def create_result
          return TestResult.new
        end
      end
    end
  end
end
PK     Z\\~!  ~!    test/unit/ui/fox/testrunner.rbnu [        #--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'fox'
require 'test/unit/ui/testrunnermediator'
require 'test/unit/ui/testrunnerutilities'

include Fox

module Test
  module Unit
    module UI
      module Fox

        # Runs a Test::Unit::TestSuite in a Fox UI. Obviously,
        # this one requires you to have Fox
        # (http://www.fox-toolkit.org/fox.html) and the Ruby
        # Fox extension (http://fxruby.sourceforge.net/)
        # installed.
        class TestRunner

          extend TestRunnerUtilities
          
          RED_STYLE = FXRGBA(0xFF,0,0,0xFF) #0xFF000000
          GREEN_STYLE = FXRGBA(0,0xFF,0,0xFF) #0x00FF0000

          # Creates a new TestRunner for running the passed
          # suite.
          def initialize(suite, output_level = NORMAL)
            if (suite.respond_to?(:suite))
              @suite = suite.suite
            else
              @suite = suite
            end

            @result = nil
            @red = false
          end
  
          # Begins the test run.
          def start
            setup_ui
            setup_mediator
            attach_to_mediator
            start_ui
            @result
          end

          def setup_mediator
            @mediator = TestRunnerMediator.new(@suite)
            suite_name = @suite.to_s
            if ( @suite.kind_of?(Module) )
              suite_name = @suite.name
            end
            @suite_name_entry.text = suite_name
          end
          
          def attach_to_mediator
            @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))
            @mediator.add_listener(TestResult::FAULT, &method(:add_fault))
            @mediator.add_listener(TestResult::CHANGED, &method(:result_changed))
            @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
            @mediator.add_listener(TestCase::STARTED, &method(:test_started))
            @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))
          end
  
          def start_ui
            @application.create
            @window.show(PLACEMENT_SCREEN)
            @application.addTimeout(1) do
              @mediator.run_suite
            end
            @application.run
          end
          
          def stop
            @application.exit(0)
          end
          
          def reset_ui(count)
            @test_progress_bar.barColor = GREEN_STYLE
            @test_progress_bar.total = count
            @test_progress_bar.progress = 0
            @red = false
  
            @test_count_label.text = "0"
            @assertion_count_label.text = "0"
            @failure_count_label.text = "0"
            @error_count_label.text = "0"
  
            @fault_list.clearItems
          end
          
          def add_fault(fault)
            if ( ! @red )
              @test_progress_bar.barColor = RED_STYLE
              @red = true
            end
            item = FaultListItem.new(fault)
            @fault_list.appendItem(item)
          end
          
          def show_fault(fault)
            raw_show_fault(fault.long_display)
          end
          
          def raw_show_fault(string)
            @detail_text.setText(string)
          end
          
          def clear_fault
            raw_show_fault("")
          end
          
          def result_changed(result)
            @test_progress_bar.progress = result.run_count
  
            @test_count_label.text = result.run_count.to_s
            @assertion_count_label.text = result.assertion_count.to_s
            @failure_count_label.text = result.failure_count.to_s
            @error_count_label.text = result.error_count.to_s

             # repaint now!
             @info_panel.repaint
             @application.flush
          end
          
          def started(result)
            @result = result
            output_status("Started...")
          end
          
          def test_started(test_name)
            output_status("Running #{test_name}...")
          end
          
          def finished(elapsed_time)
            output_status("Finished in #{elapsed_time} seconds")
          end
          
          def output_status(string)
            @status_entry.text = string
            @status_entry.repaint
          end
  
          def setup_ui
            @application = create_application
            create_tooltip(@application)

            @window = create_window(@application)
            
            @status_entry = create_entry(@window)
            
            main_panel = create_main_panel(@window)
            
            suite_panel = create_suite_panel(main_panel)
            create_label(suite_panel, "Suite:")
            @suite_name_entry = create_entry(suite_panel)
            create_button(suite_panel, "&Run\tRun the current suite", proc { @mediator.run_suite })
            
            @test_progress_bar = create_progress_bar(main_panel)
            
            @info_panel = create_info_panel(main_panel)
            create_label(@info_panel, "Tests:")
            @test_count_label = create_label(@info_panel, "0")
            create_label(@info_panel, "Assertions:")
            @assertion_count_label = create_label(@info_panel, "0")
            create_label(@info_panel, "Failures:")
            @failure_count_label = create_label(@info_panel, "0")
            create_label(@info_panel, "Errors:")
            @error_count_label = create_label(@info_panel, "0")
            
            list_panel = create_list_panel(main_panel)
            @fault_list = create_fault_list(list_panel)
            
            detail_panel = create_detail_panel(main_panel)
            @detail_text = create_text(detail_panel)
          end
          
          def create_application
            app = FXApp.new("TestRunner", "Test::Unit")
            app.init([])
            app
          end
          
          def create_window(app)
            FXMainWindow.new(app, "Test::Unit TestRunner", nil, nil, DECOR_ALL, 0, 0, 450)
          end
          
          def create_tooltip(app)
            FXTooltip.new(app)
          end
  
          def create_main_panel(parent)
            panel = FXVerticalFrame.new(parent, LAYOUT_FILL_X | LAYOUT_FILL_Y)
            panel.vSpacing = 10
            panel
          end
  
          def create_suite_panel(parent)
            FXHorizontalFrame.new(parent, LAYOUT_SIDE_LEFT | LAYOUT_FILL_X)
          end
          
          def create_button(parent, text, action)
            FXButton.new(parent, text).connect(SEL_COMMAND, &action)
          end
          
          def create_progress_bar(parent)
            FXProgressBar.new(parent, nil, 0, PROGRESSBAR_NORMAL | LAYOUT_FILL_X)
          end
          
          def create_info_panel(parent)
            FXMatrix.new(parent, 1, MATRIX_BY_ROWS | LAYOUT_FILL_X)
          end
          
          def create_label(parent, text)
            FXLabel.new(parent, text, nil, JUSTIFY_CENTER_X | LAYOUT_FILL_COLUMN)
          end
          
          def create_list_panel(parent)
            FXHorizontalFrame.new(parent, LAYOUT_FILL_X | FRAME_SUNKEN | FRAME_THICK)
          end
          
          def create_fault_list(parent)
            list = FXList.new(parent, 10, nil, 0, LIST_SINGLESELECT | LAYOUT_FILL_X) #, 0, 0, 0, 150)
            list.connect(SEL_COMMAND) do |sender, sel, ptr|
              if sender.retrieveItem(sender.currentItem).selected?
                show_fault(sender.retrieveItem(sender.currentItem).fault)
              else
                clear_fault
              end
            end
            list
          end
          
          def create_detail_panel(parent)
            FXHorizontalFrame.new(parent, LAYOUT_FILL_X | LAYOUT_FILL_Y | FRAME_SUNKEN | FRAME_THICK)
          end
          
          def create_text(parent)
            FXText.new(parent, nil, 0, TEXT_READONLY | LAYOUT_FILL_X | LAYOUT_FILL_Y)
          end
          
          def create_entry(parent)
            entry = FXTextField.new(parent, 30, nil, 0, TEXTFIELD_NORMAL | LAYOUT_SIDE_BOTTOM | LAYOUT_FILL_X)
            entry.disable
            entry
          end
        end
  
        class FaultListItem < FXListItem
          attr_reader(:fault)
          def initialize(fault)
            super(fault.short_display)
            @fault = fault
          end
        end
      end
    end
  end
end

if __FILE__ == $0
  Test::Unit::UI::Fox::TestRunner.start_command_line_test
end
PK     Z\K    #  test/unit/ui/testrunnerutilities.rbnu [        #--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

module Test
  module Unit
    module UI

      SILENT = 0
      PROGRESS_ONLY = 1
      NORMAL = 2
      VERBOSE = 3

      # Provides some utilities common to most, if not all,
      # TestRunners.
      #
      #--
      #
      # Perhaps there ought to be a TestRunner superclass? There
      # seems to be a decent amount of shared code between test
      # runners.

      module TestRunnerUtilities

        # Creates a new TestRunner and runs the suite.
        def run(suite, output_level=NORMAL)
          return new(suite, output_level).start
        end

        # Takes care of the ARGV parsing and suite
        # determination necessary for running one of the
        # TestRunners from the command line.
        def start_command_line_test
          if ARGV.empty?
            puts "You should supply the name of a test suite file to the runner"
            exit
          end
          require ARGV[0].gsub(/.+::/, '')
          new(eval(ARGV[0])).start
        end
      end
    end
  end
end
PK     Z\o/    "  test/unit/ui/console/testrunner.rbnu [        #--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit/ui/testrunnermediator'
require 'test/unit/ui/testrunnerutilities'

module Test
  module Unit
    module UI
      module Console

        # Runs a Test::Unit::TestSuite on the console.
        class TestRunner
          extend TestRunnerUtilities

          # Creates a new TestRunner for running the passed
          # suite. If quiet_mode is true, the output while
          # running is limited to progress dots, errors and
          # failures, and the final result. io specifies
          # where runner output should go to; defaults to
          # STDOUT.
          def initialize(suite, output_level=NORMAL, io=STDOUT)
            if (suite.respond_to?(:suite))
              @suite = suite.suite
            else
              @suite = suite
            end
            @output_level = output_level
            @io = io
            @already_outputted = false
            @faults = []
          end

          # Begins the test run.
          def start
            setup_mediator
            attach_to_mediator
            return start_mediator
          end

          private
          def setup_mediator
            @mediator = create_mediator(@suite)
            suite_name = @suite.to_s
            if ( @suite.kind_of?(Module) )
              suite_name = @suite.name
            end
            output("Loaded suite #{suite_name}")
          end
          
          def create_mediator(suite)
            return TestRunnerMediator.new(suite)
          end
          
          def attach_to_mediator
            @mediator.add_listener(TestResult::FAULT, &method(:add_fault))
            @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
            @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))
            @mediator.add_listener(TestCase::STARTED, &method(:test_started))
            @mediator.add_listener(TestCase::FINISHED, &method(:test_finished))
          end
          
          def start_mediator
            return @mediator.run_suite
          end
          
          def add_fault(fault)
            @faults << fault
            output_single(fault.single_character_display, PROGRESS_ONLY)
            @already_outputted = true
          end
          
          def started(result)
            @result = result
            output("Started")
          end
          
          def finished(elapsed_time)
            nl
            output("Finished in #{elapsed_time} seconds.")
            @faults.each_with_index do |fault, index|
              nl
              output("%3d) %s" % [index + 1, fault.long_display])
            end
            nl
            output(@result)
          end
          
          def test_started(name)
            output_single(name + ": ", VERBOSE)
          end
          
          def test_finished(name)
            output_single(".", PROGRESS_ONLY) unless (@already_outputted)
            nl(VERBOSE)
            @already_outputted = false
          end
          
          def nl(level=NORMAL)
            output("", level)
          end
          
          def output(something, level=NORMAL)
            @io.puts(something) if (output?(level))
            @io.flush
          end
          
          def output_single(something, level=NORMAL)
            @io.write(something) if (output?(level))
            @io.flush
          end
          
          def output?(level)
            level <= @output_level
          end
        end
      end
    end
  end
end

if __FILE__ == $0
  Test::Unit::UI::Console::TestRunner.start_command_line_test
end
PK     Z\997  7    test/unit/ui/gtk/testrunner.rbnu [        #--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'gtk'
require 'test/unit/ui/testrunnermediator'
require 'test/unit/ui/testrunnerutilities'

module Test
  module Unit
    module UI
      module GTK

        # Runs a Test::Unit::TestSuite in a Gtk UI. Obviously,
        # this one requires you to have Gtk
        # (http://www.gtk.org/) and the Ruby Gtk extension
        # (http://ruby-gnome.sourceforge.net/) installed.
        class TestRunner
          extend TestRunnerUtilities

          # Creates a new TestRunner for running the passed
          # suite.
          def initialize(suite, output_level = NORMAL)
            if (suite.respond_to?(:suite))
              @suite = suite.suite
            else
              @suite = suite
            end
            @result = nil

            @runner = Thread.current
            @restart_signal = Class.new(Exception)
            @viewer = Thread.start do
              @runner.join rescue @runner.run
              Gtk.main
            end
            @viewer.join rescue nil # wait deadlock to handshake
          end

          # Begins the test run.
          def start
            setup_mediator
            setup_ui
            attach_to_mediator
            start_ui
            @result
          end

          private
          def setup_mediator
            @mediator = TestRunnerMediator.new(@suite)
            suite_name = @suite.to_s
            if ( @suite.kind_of?(Module) )
              suite_name = @suite.name
            end
            suite_name_entry.set_text(suite_name)
          end
          
          def attach_to_mediator
            run_button.signal_connect("clicked", nil, &method(:run_test))
            @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))
            @mediator.add_listener(TestResult::FAULT, &method(:add_fault))
            @mediator.add_listener(TestResult::CHANGED, &method(:result_changed))
            @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
            @mediator.add_listener(TestCase::STARTED, &method(:test_started))
            @mediator.add_listener(TestCase::FINISHED, &method(:test_finished))
            @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))
          end

          def run_test(*)
            @runner.raise(@restart_signal)
          end
          
          def start_ui
            @viewer.run
            running = false
            begin
              loop do
                if (running ^= true)
                  run_button.child.text = "Stop"
                  @mediator.run_suite
                else
                  run_button.child.text = "Run"
                  @viewer.join
                  break
                end
              end
            rescue @restart_signal
              retry
            rescue
            end
          end
          
          def stop(*)
            Gtk.main_quit
          end
          
          def reset_ui(count)
            test_progress_bar.set_style(green_style)
            test_progress_bar.configure(0, 0, count)
            @red = false
  
            run_count_label.set_text("0")
            assertion_count_label.set_text("0")
            failure_count_label.set_text("0")
            error_count_label.set_text("0")
  
            fault_list.remove_items(fault_list.children)
          end
          
          def add_fault(fault)
            if ( ! @red )
              test_progress_bar.set_style(red_style)
              @red = true
            end
            item = FaultListItem.new(fault)
            item.show
            fault_list.append_items([item])
          end
          
          def show_fault(fault)
            raw_show_fault(fault.long_display)
          end
          
          def raw_show_fault(string)
            fault_detail_label.set_text(string)
            outer_detail_sub_panel.queue_resize
          end
          
          def clear_fault
            raw_show_fault("")
          end
          
          def result_changed(result)
            run_count_label.set_text(result.run_count.to_s)
            assertion_count_label.set_text(result.assertion_count.to_s)
            failure_count_label.set_text(result.failure_count.to_s)
            error_count_label.set_text(result.error_count.to_s)
          end
          
          def started(result)
            @result = result
            output_status("Started...")
          end
          
          def test_started(test_name)
            output_status("Running #{test_name}...")
          end
          
          def test_finished(test_name)
            test_progress_bar.set_value(test_progress_bar.get_value + 1)
          end
          
          def finished(elapsed_time)
            output_status("Finished in #{elapsed_time} seconds")
          end
          
          def output_status(string)
            status_entry.set_text(string)
          end
  
          def setup_ui
            main_window.signal_connect("destroy", nil, &method(:stop))
            main_window.show_all
            fault_list.signal_connect("select-child", nil) {
              | list, item, data |
              show_fault(item.fault)
            }
            fault_list.signal_connect("unselect-child", nil) {
              clear_fault
            }
            @red = false
          end
          
          def main_window
            lazy_initialize(:main_window) {
              @main_window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL)
              @main_window.set_title("Test::Unit TestRunner")
              @main_window.set_usize(800, 600)
              @main_window.set_uposition(20, 20)
              @main_window.set_policy(true, true, false)
              @main_window.add(main_panel)
            }
          end
          
          def main_panel
            lazy_initialize(:main_panel) {
              @main_panel = Gtk::VBox.new(false, 0)
              @main_panel.pack_start(suite_panel, false, false, 0)
              @main_panel.pack_start(progress_panel, false, false, 0)
              @main_panel.pack_start(info_panel, false, false, 0)
              @main_panel.pack_start(list_panel, false, false, 0)
              @main_panel.pack_start(detail_panel, true, true, 0)
              @main_panel.pack_start(status_panel, false, false, 0)
            }
          end
          
          def suite_panel
            lazy_initialize(:suite_panel) {
              @suite_panel = Gtk::HBox.new(false, 10)
              @suite_panel.border_width(10)
              @suite_panel.pack_start(Gtk::Label.new("Suite:"), false, false, 0)
              @suite_panel.pack_start(suite_name_entry, true, true, 0)
              @suite_panel.pack_start(run_button, false, false, 0)
            }
          end
          
          def suite_name_entry
            lazy_initialize(:suite_name_entry) {
              @suite_name_entry = Gtk::Entry.new
              @suite_name_entry.set_editable(false)
            }
          end
          
          def run_button
            lazy_initialize(:run_button) {
              @run_button = Gtk::Button.new("Run")
            }
          end
          
          def progress_panel
            lazy_initialize(:progress_panel) {
              @progress_panel = Gtk::HBox.new(false, 10)
              @progress_panel.border_width(10)
              @progress_panel.pack_start(test_progress_bar, true, true, 0)
            }
          end
          
          def test_progress_bar
            lazy_initialize(:test_progress_bar) {
              @test_progress_bar = EnhancedProgressBar.new
              @test_progress_bar.set_usize(@test_progress_bar.allocation.width,
                                           info_panel.size_request.height)
              @test_progress_bar.set_style(green_style)
            }
          end
          
          def green_style
            lazy_initialize(:green_style) {
              @green_style = Gtk::Style.new
              @green_style.set_bg(Gtk::STATE_PRELIGHT, 0x0000, 0xFFFF, 0x0000)
            }
          end
          
          def red_style
            lazy_initialize(:red_style) {
              @red_style = Gtk::Style.new
              @red_style.set_bg(Gtk::STATE_PRELIGHT, 0xFFFF, 0x0000, 0x0000)
            }
          end
          
          def info_panel
            lazy_initialize(:info_panel) {
              @info_panel = Gtk::HBox.new(false, 0)
              @info_panel.border_width(10)
              @info_panel.pack_start(Gtk::Label.new("Runs:"), false, false, 0)
              @info_panel.pack_start(run_count_label, true, false, 0)
              @info_panel.pack_start(Gtk::Label.new("Assertions:"), false, false, 0)
              @info_panel.pack_start(assertion_count_label, true, false, 0)
              @info_panel.pack_start(Gtk::Label.new("Failures:"), false, false, 0)
              @info_panel.pack_start(failure_count_label, true, false, 0)
              @info_panel.pack_start(Gtk::Label.new("Errors:"), false, false, 0)
              @info_panel.pack_start(error_count_label, true, false, 0)
            }
          end
          
          def run_count_label
            lazy_initialize(:run_count_label) {
              @run_count_label = Gtk::Label.new("0")
              @run_count_label.set_justify(Gtk::JUSTIFY_LEFT)
            }
          end
          
          def assertion_count_label
            lazy_initialize(:assertion_count_label) {
              @assertion_count_label = Gtk::Label.new("0")
              @assertion_count_label.set_justify(Gtk::JUSTIFY_LEFT)
            }
          end
          
          def failure_count_label
            lazy_initialize(:failure_count_label) {
              @failure_count_label = Gtk::Label.new("0")
              @failure_count_label.set_justify(Gtk::JUSTIFY_LEFT)
            }
          end
          
          def error_count_label
            lazy_initialize(:error_count_label) {
              @error_count_label = Gtk::Label.new("0")
              @error_count_label.set_justify(Gtk::JUSTIFY_LEFT)
            }
          end
          
          def list_panel
            lazy_initialize(:list_panel) {
              @list_panel = Gtk::HBox.new
              @list_panel.border_width(10)
              @list_panel.pack_start(list_scrolled_window, true, true, 0)
            }
          end
          
          def list_scrolled_window
            lazy_initialize(:list_scrolled_window) {
              @list_scrolled_window = Gtk::ScrolledWindow.new
              @list_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
              @list_scrolled_window.set_usize(@list_scrolled_window.allocation.width, 150)
              @list_scrolled_window.add_with_viewport(fault_list)
            }
          end
          
          def fault_list
            lazy_initialize(:fault_list) {
              @fault_list = Gtk::List.new
            }
          end
          
          def detail_panel
            lazy_initialize(:detail_panel) {
              @detail_panel = Gtk::HBox.new
              @detail_panel.border_width(10)
              @detail_panel.pack_start(detail_scrolled_window, true, true, 0)
            }
          end
          
          def detail_scrolled_window
            lazy_initialize(:detail_scrolled_window) {
              @detail_scrolled_window = Gtk::ScrolledWindow.new
              @detail_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
              @detail_scrolled_window.set_usize(400, @detail_scrolled_window.allocation.height)
              @detail_scrolled_window.add_with_viewport(outer_detail_sub_panel)
            }
          end
          
          def outer_detail_sub_panel
            lazy_initialize(:outer_detail_sub_panel) {
              @outer_detail_sub_panel = Gtk::VBox.new
              @outer_detail_sub_panel.pack_start(inner_detail_sub_panel, false, false, 0)
            }
          end
          
          def inner_detail_sub_panel
            lazy_initialize(:inner_detail_sub_panel) {
              @inner_detail_sub_panel = Gtk::HBox.new
              @inner_detail_sub_panel.pack_start(fault_detail_label, false, false, 0)
            }
          end
          
          def fault_detail_label
            lazy_initialize(:fault_detail_label) {
              @fault_detail_label = EnhancedLabel.new("")
              style = Gtk::Style.new
              font = Gdk::Font.font_load("-*-Courier New-medium-r-normal--*-120-*-*-*-*-*-*")
              begin
                style.set_font(font)
              rescue ArgumentError; end
              @fault_detail_label.set_style(style)
              @fault_detail_label.set_justify(Gtk::JUSTIFY_LEFT)
              @fault_detail_label.set_line_wrap(false)
            }
          end
          
          def status_panel
            lazy_initialize(:status_panel) {
              @status_panel = Gtk::HBox.new
              @status_panel.border_width(10)
              @status_panel.pack_start(status_entry, true, true, 0)
            }
          end
          
          def status_entry
            lazy_initialize(:status_entry) {
              @status_entry = Gtk::Entry.new
              @status_entry.set_editable(false)
            }
          end
  
          def lazy_initialize(symbol)
            if (!instance_eval("defined?(@#{symbol.to_s})"))
              yield
            end
            return instance_eval("@" + symbol.to_s)
          end
        end
  
        class EnhancedProgressBar < Gtk::ProgressBar
          def set_style(style)
            super
            hide
            show
          end
        end
  
        class EnhancedLabel < Gtk::Label
          def set_text(text)
            super(text.gsub(/\n\t/, "\n" + (" " * 4)))
          end
        end
  
        class FaultListItem < Gtk::ListItem
          attr_reader(:fault)
          def initialize(fault)
            super(fault.short_display)
            @fault = fault
          end
        end
      end
    end
  end
end

if __FILE__ == $0
  Test::Unit::UI::GTK::TestRunner.start_command_line_test
end
PK     Z\aAmV  V    test/unit/autorunner.rbnu [        require 'test/unit'
require 'test/unit/ui/testrunnerutilities'
require 'optparse'

module Test
  module Unit
    class AutoRunner
      def self.run(force_standalone=false, default_dir=nil, argv=ARGV, &block)
        r = new(force_standalone || standalone?, &block)
        r.base = default_dir
        r.process_args(argv)
        r.run
      end
      
      def self.standalone?
        return false unless("-e" == $0)
        ObjectSpace.each_object(Class) do |klass|
          return false if(klass < TestCase)
        end
        true
      end

      RUNNERS = {
        :console => proc do |r|
          require 'test/unit/ui/console/testrunner'
          Test::Unit::UI::Console::TestRunner
        end,
        :gtk => proc do |r|
          require 'test/unit/ui/gtk/testrunner'
          Test::Unit::UI::GTK::TestRunner
        end,
        :gtk2 => proc do |r|
          require 'test/unit/ui/gtk2/testrunner'
          Test::Unit::UI::GTK2::TestRunner
        end,
        :fox => proc do |r|
          require 'test/unit/ui/fox/testrunner'
          Test::Unit::UI::Fox::TestRunner
        end,
        :tk => proc do |r|
          require 'test/unit/ui/tk/testrunner'
          Test::Unit::UI::Tk::TestRunner
        end,
      }

      OUTPUT_LEVELS = [
        [:silent, UI::SILENT],
        [:progress, UI::PROGRESS_ONLY],
        [:normal, UI::NORMAL],
        [:verbose, UI::VERBOSE],
      ]

      COLLECTORS = {
        :objectspace => proc do |r|
          require 'test/unit/collector/objectspace'
          c = Collector::ObjectSpace.new
          c.filter = r.filters
          c.collect($0.sub(/\.rb\Z/, ''))
        end,
        :dir => proc do |r|
          require 'test/unit/collector/dir'
          c = Collector::Dir.new
          c.filter = r.filters
          c.pattern.concat(r.pattern) if(r.pattern)
          c.exclude.concat(r.exclude) if(r.exclude)
          c.base = r.base
          $:.push(r.base) if r.base
          c.collect(*(r.to_run.empty? ? ['.'] : r.to_run))
        end,
      }

      attr_reader :suite
      attr_accessor :output_level, :filters, :to_run, :pattern, :exclude, :base, :workdir
      attr_writer :runner, :collector

      def initialize(standalone)
        Unit.run = true
        @standalone = standalone
        @runner = RUNNERS[:console]
        @collector = COLLECTORS[(standalone ? :dir : :objectspace)]
        @filters = []
        @to_run = []
        @output_level = UI::NORMAL
        @workdir = nil
        yield(self) if(block_given?)
      end

      def process_args(args = ARGV)
        begin
          options.order!(args) {|arg| @to_run << arg}
        rescue OptionParser::ParseError => e
          puts e
          puts options
          $! = nil
          abort
        else
          @filters << proc{false} unless(@filters.empty?)
        end
        not @to_run.empty?
      end

      def options
        @options ||= OptionParser.new do |o|
          o.banner = "Test::Unit automatic runner."
          o.banner << "\nUsage: #{$0} [options] [-- untouched arguments]"

          o.on
          o.on('-r', '--runner=RUNNER', RUNNERS,
               "Use the given RUNNER.",
               "(" + keyword_display(RUNNERS) + ")") do |r|
            @runner = r
          end

          if(@standalone)
            o.on('-b', '--basedir=DIR', "Base directory of test suites.") do |b|
              @base = b
            end

            o.on('-w', '--workdir=DIR', "Working directory to run tests.") do |w|
              @workdir = w
            end

            o.on('-a', '--add=TORUN', Array,
                 "Add TORUN to the list of things to run;",
                 "can be a file or a directory.") do |a|
              @to_run.concat(a)
            end

            @pattern = []
            o.on('-p', '--pattern=PATTERN', Regexp,
                 "Match files to collect against PATTERN.") do |e|
              @pattern << e
            end

            @exclude = []
            o.on('-x', '--exclude=PATTERN', Regexp,
                 "Ignore files to collect against PATTERN.") do |e|
              @exclude << e
            end
          end

          o.on('-n', '--name=NAME', String,
               "Runs tests matching NAME.",
               "(patterns may be used).") do |n|
            n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n)
            case n
            when Regexp
              @filters << proc{|t| n =~ t.method_name ? true : nil}
            else
              @filters << proc{|t| n == t.method_name ? true : nil}
            end
          end

          o.on('-t', '--testcase=TESTCASE', String,
               "Runs tests in TestCases matching TESTCASE.",
               "(patterns may be used).") do |n|
            n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n)
            case n
            when Regexp
              @filters << proc{|t| n =~ t.class.name ? true : nil}
            else
              @filters << proc{|t| n == t.class.name ? true : nil}
            end
          end

          o.on('-I', "--load-path=DIR[#{File::PATH_SEPARATOR}DIR...]",
               "Appends directory list to $LOAD_PATH.") do |dirs|
            $LOAD_PATH.concat(dirs.split(File::PATH_SEPARATOR))
          end

          o.on('-v', '--verbose=[LEVEL]', OUTPUT_LEVELS,
               "Set the output level (default is verbose).",
               "(" + keyword_display(OUTPUT_LEVELS) + ")") do |l|
            @output_level = l || UI::VERBOSE
          end

          o.on('--',
               "Stop processing options so that the",
               "remaining options will be passed to the",
               "test."){o.terminate}

          o.on('-h', '--help', 'Display this help.'){puts o; exit}

          o.on_tail
          o.on_tail('Deprecated options:')

          o.on_tail('--console', 'Console runner (use --runner).') do
            warn("Deprecated option (--console).")
            @runner = RUNNERS[:console]
          end

          o.on_tail('--gtk', 'GTK runner (use --runner).') do
            warn("Deprecated option (--gtk).")
            @runner = RUNNERS[:gtk]
          end

          o.on_tail('--fox', 'Fox runner (use --runner).') do
            warn("Deprecated option (--fox).")
            @runner = RUNNERS[:fox]
          end

          o.on_tail
        end
      end

      def keyword_display(array)
        list = array.collect {|e, *| e.to_s}
        Array === array or list.sort!
        list.collect {|e| e.sub(/^(.)([A-Za-z]+)(?=\w*$)/, '\\1[\\2]')}.join(", ")
      end

      def run
        @suite = @collector[self]
        result = @runner[self] or return false
        Dir.chdir(@workdir) if @workdir
        result.run(@suite, @output_level).passed?
      end
    end
  end
end
PK     Z\K4      test/unit/testresult.rbnu [        #--
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit/util/observable'

module Test
  module Unit

    # Collects Test::Unit::Failure and Test::Unit::Error so that
    # they can be displayed to the user. To this end, observers
    # can be added to it, allowing the dynamic updating of, say, a
    # UI.
    class TestResult
      include Util::Observable

      CHANGED = "CHANGED"
      FAULT = "FAULT"

      attr_reader(:run_count, :assertion_count)

      # Constructs a new, empty TestResult.
      def initialize
        @run_count, @assertion_count = 0, 0
        @failures, @errors = Array.new, Array.new
      end

      # Records a test run.
      def add_run
        @run_count += 1
        notify_listeners(CHANGED, self)
      end

      # Records a Test::Unit::Failure.
      def add_failure(failure)
        @failures << failure
        notify_listeners(FAULT, failure)
        notify_listeners(CHANGED, self)
      end

      # Records a Test::Unit::Error.
      def add_error(error)
        @errors << error
        notify_listeners(FAULT, error)
        notify_listeners(CHANGED, self)
      end

      # Records an individual assertion.
      def add_assertion
        @assertion_count += 1
        notify_listeners(CHANGED, self)
      end

      # Returns a string contain the recorded runs, assertions,
      # failures and errors in this TestResult.
      def to_s
        "#{run_count} tests, #{assertion_count} assertions, #{failure_count} failures, #{error_count} errors"
      end

      # Returns whether or not this TestResult represents
      # successful completion.
      def passed?
        return @failures.empty? && @errors.empty?
      end

      # Returns the number of failures this TestResult has
      # recorded.
      def failure_count
        return @failures.size
      end

      # Returns the number of errors this TestResult has
      # recorded.
      def error_count
        return @errors.size
      end
    end
  end
end
PK     Z\ J)  )  !  test/unit/assertionfailederror.rbnu [        #--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

module Test
  module Unit

    # Thrown by Test::Unit::Assertions when an assertion fails.
    class AssertionFailedError < StandardError
    end
  end
end
PK     Z\&  &    test/unit/failure.rbnu [        #--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

module Test
  module Unit

    # Encapsulates a test failure. Created by Test::Unit::TestCase
    # when an assertion fails.
    class Failure
      attr_reader :test_name, :location, :message
      
      SINGLE_CHARACTER = 'F'

      # Creates a new Failure with the given location and
      # message.
      def initialize(test_name, location, message)
        @test_name = test_name
        @location = location
        @message = message
      end
      
      # Returns a single character representation of a failure.
      def single_character_display
        SINGLE_CHARACTER
      end

      # Returns a brief version of the error description.
      def short_display
        "#@test_name: #{@message.split("\n")[0]}"
      end

      # Returns a verbose version of the error description.
      def long_display
        location_display = if(location.size == 1)
          location[0].sub(/\A(.+:\d+).*/, ' [\\1]')
        else
          "\n    [#{location.join("\n     ")}]"
        end
        "Failure:\n#@test_name#{location_display}:\n#@message"
      end

      # Overridden to return long_display.
      def to_s
        long_display
      end
    end
  end
end
PK     Z\ݮ?3G  3G    test/unit/assertions.rbnu [        # Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit/assertionfailederror'
require 'test/unit/util/backtracefilter'

module Test
  module Unit

    ##
    # Test::Unit::Assertions contains the standard Test::Unit assertions.
    # Assertions is included in Test::Unit::TestCase.
    #
    # To include it in your own code and use its functionality, you simply
    # need to rescue Test::Unit::AssertionFailedError. Additionally you may
    # override add_assertion to get notified whenever an assertion is made.
    #
    # Notes:
    # * The message to each assertion, if given, will be propagated with the
    #   failure.
    # * It is easy to add your own assertions based on assert_block().
    #
    # = Example Custom Assertion
    #
    #   def deny(boolean, message = nil)
    #     message = build_message message, '<?> is not false or nil.', boolean
    #     assert_block message do
    #       not boolean
    #     end
    #   end

    module Assertions

      ##
      # The assertion upon which all other assertions are based. Passes if the
      # block yields true.
      #
      # Example:
      #   assert_block "Couldn't do the thing" do
      #     do_the_thing
      #   end

      public
      def assert_block(message="assert_block failed.") # :yields: 
        _wrap_assertion do
          if (! yield)
            raise AssertionFailedError.new(message.to_s)
          end
        end
      end

      ##
      # Asserts that +boolean+ is not false or nil.
      #
      # Example:
      #   assert [1, 2].include?(5)

      public
      def assert(boolean, message=nil)
        _wrap_assertion do
          assert_block("assert should not be called with a block.") { !block_given? }
          assert_block(build_message(message, "<?> is not true.", boolean)) { boolean }
        end
      end

      ##
      # Passes if +expected+ == +actual.
      #
      # Note that the ordering of arguments is important, since a helpful
      # error message is generated when this one fails that tells you the
      # values of expected and actual.
      #
      # Example:
      #   assert_equal 'MY STRING', 'my string'.upcase

      public
      def assert_equal(expected, actual, message=nil)
        full_message = build_message(message, <<EOT, expected, actual)
<?> expected but was
<?>.
EOT
        assert_block(full_message) { expected == actual }
      end

      private
      def _check_exception_class(args) # :nodoc:
        args.partition do |klass|
          next if klass.instance_of?(Module)
          assert(Exception >= klass, "Should expect a class of exception, #{klass}")
          true
        end
      end

      private
      def _expected_exception?(actual_exception, exceptions, modules) # :nodoc:
        exceptions.include?(actual_exception.class) or
          modules.any? {|mod| actual_exception.is_a?(mod)}
      end

      ##
      # Passes if the block raises one of the given exceptions.
      #
      # Example:
      #   assert_raise RuntimeError, LoadError do
      #     raise 'Boom!!!'
      #   end

      public
      def assert_raise(*args)
        _wrap_assertion do
          if Module === args.last
            message = ""
          else
            message = args.pop
          end
          exceptions, modules = _check_exception_class(args)
          expected = args.size == 1 ? args.first : args
          actual_exception = nil
          full_message = build_message(message, "<?> exception expected but none was thrown.", expected)
          assert_block(full_message) do
            begin
              yield
            rescue Exception => actual_exception
              break
            end
            false
          end
          full_message = build_message(message, "<?> exception expected but was\n?", expected, actual_exception)
          assert_block(full_message) {_expected_exception?(actual_exception, exceptions, modules)}
          actual_exception
        end
      end

      ##
      # Alias of assert_raise.
      #
      # Will be deprecated in 1.9, and removed in 2.0.

      public
      def assert_raises(*args, &block)
        assert_raise(*args, &block)
      end

      ##
      # Passes if +object+ .instance_of? +klass+
      #
      # Example:
      #   assert_instance_of String, 'foo'

      public
      def assert_instance_of(klass, object, message="")
        _wrap_assertion do
          assert_equal(Class, klass.class, "assert_instance_of takes a Class as its first argument")
          full_message = build_message(message, <<EOT, object, klass, object.class)
<?> expected to be an instance of
<?> but was
<?>.
EOT
          assert_block(full_message){object.instance_of?(klass)}
        end
      end

      ##
      # Passes if +object+ is nil.
      #
      # Example:
      #   assert_nil [1, 2].uniq!

      public
      def assert_nil(object, message="")
        assert_equal(nil, object, message)
      end

      ##
      # Passes if +object+ .kind_of? +klass+
      #
      # Example:
      #   assert_kind_of Object, 'foo'

      public
      def assert_kind_of(klass, object, message="")
        _wrap_assertion do
          assert(klass.kind_of?(Module), "The first parameter to assert_kind_of should be a kind_of Module.")
          full_message = build_message(message, "<?>\nexpected to be kind_of\\?\n<?> but was\n<?>.", object, klass, object.class)
          assert_block(full_message){object.kind_of?(klass)}
        end
      end

      ##
      # Passes if +object+ .respond_to? +method+
      #
      # Example:
      #   assert_respond_to 'bugbear', :slice

      public
      def assert_respond_to(object, method, message="")
        _wrap_assertion do
          full_message = build_message(nil, "<?>\ngiven as the method name argument to #assert_respond_to must be a Symbol or #respond_to\\?(:to_str).", method)

          assert_block(full_message) do
            method.kind_of?(Symbol) || method.respond_to?(:to_str)
          end
          full_message = build_message(message, <<EOT, object, object.class, method)
<?>
of type <?>
expected to respond_to\\?<?>.
EOT
          assert_block(full_message) { object.respond_to?(method) }
        end
      end

      ##
      # Passes if +string+ =~ +pattern+.
      #
      # Example:
      #   assert_match(/\d+/, 'five, 6, seven')

      public
      def assert_match(pattern, string, message="")
        _wrap_assertion do
          pattern = case(pattern)
            when String
              Regexp.new(Regexp.escape(pattern))
            else
              pattern
          end
          full_message = build_message(message, "<?> expected to be =~\n<?>.", string, pattern)
          assert_block(full_message) { string =~ pattern }
        end
      end

      ##
      # Passes if +actual+ .equal? +expected+ (i.e. they are the same
      # instance).
      #
      # Example:
      #   o = Object.new
      #   assert_same o, o

      public
      def assert_same(expected, actual, message="")
        full_message = build_message(message, <<EOT, expected, expected.__id__, actual, actual.__id__)
<?>
with id <?> expected to be equal\\? to
<?>
with id <?>.
EOT
        assert_block(full_message) { actual.equal?(expected) }
      end

      ##
      # Compares the +object1+ with +object2+ using +operator+.
      #
      # Passes if object1.__send__(operator, object2) is true.
      #
      # Example:
      #   assert_operator 5, :>=, 4

      public
      def assert_operator(object1, operator, object2, message="")
        _wrap_assertion do
          full_message = build_message(nil, "<?>\ngiven as the operator for #assert_operator must be a Symbol or #respond_to\\?(:to_str).", operator)
          assert_block(full_message){operator.kind_of?(Symbol) || operator.respond_to?(:to_str)}
          full_message = build_message(message, <<EOT, object1, AssertionMessage.literal(operator), object2)
<?> expected to be
?
<?>.
EOT
          assert_block(full_message) { object1.__send__(operator, object2) }
        end
      end

      ##
      # Passes if block does not raise an exception.
      #
      # Example:
      #   assert_nothing_raised do
      #     [1, 2].uniq
      #   end

      public
      def assert_nothing_raised(*args)
        _wrap_assertion do
          if Module === args.last
            message = ""
          else
            message = args.pop
          end
          exceptions, modules = _check_exception_class(args)
          begin
            yield
          rescue Exception => e
            if ((args.empty? && !e.instance_of?(AssertionFailedError)) ||
                _expected_exception?(e, exceptions, modules))
              assert_block(build_message(message, "Exception raised:\n?", e)){false}
            else
              raise
            end
          end
          nil
        end
      end

      ##
      # Flunk always fails.
      #
      # Example:
      #   flunk 'Not done testing yet.'

      public
      def flunk(message="Flunked")
        assert_block(build_message(message)){false}
      end

      ##
      # Passes if ! +actual+ .equal? +expected+
      #
      # Example:
      #   assert_not_same Object.new, Object.new

      public
      def assert_not_same(expected, actual, message="")
        full_message = build_message(message, <<EOT, expected, expected.__id__, actual, actual.__id__)
<?>
with id <?> expected to not be equal\\? to
<?>
with id <?>.
EOT
        assert_block(full_message) { !actual.equal?(expected) }
      end

      ##
      # Passes if +expected+ != +actual+
      #
      # Example:
      #   assert_not_equal 'some string', 5

      public
      def assert_not_equal(expected, actual, message="")
        full_message = build_message(message, "<?> expected to be != to\n<?>.", expected, actual)
        assert_block(full_message) { expected != actual }
      end

      ##
      # Passes if ! +object+ .nil?
      #
      # Example:
      #   assert_not_nil '1 two 3'.sub!(/two/, '2')

      public
      def assert_not_nil(object, message="")
        full_message = build_message(message, "<?> expected to not be nil.", object)
        assert_block(full_message){!object.nil?}
      end

      ##
      # Passes if +regexp+ !~ +string+ 
      #
      # Example:
      #   assert_no_match(/two/, 'one 2 three')

      public
      def assert_no_match(regexp, string, message="")
        _wrap_assertion do
          assert_instance_of(Regexp, regexp, "The first argument to assert_no_match should be a Regexp.")
          full_message = build_message(message, "<?> expected to not match\n<?>.", regexp, string)
          assert_block(full_message) { regexp !~ string }
        end
      end

      UncaughtThrow = {NameError => /^uncaught throw \`(.+)\'$/,
                       ThreadError => /^uncaught throw \`(.+)\' in thread /} #`

      ##
      # Passes if the block throws +expected_symbol+
      #
      # Example:
      #   assert_throws :done do
      #     throw :done
      #   end

      public
      def assert_throws(expected_symbol, message="", &proc)
        _wrap_assertion do
          assert_instance_of(Symbol, expected_symbol, "assert_throws expects the symbol that should be thrown for its first argument")
          assert_block("Should have passed a block to assert_throws."){block_given?}
          caught = true
          begin
            catch(expected_symbol) do
              proc.call
              caught = false
            end
            full_message = build_message(message, "<?> should have been thrown.", expected_symbol)
            assert_block(full_message){caught}
          rescue NameError, ThreadError => error
            if UncaughtThrow[error.class] !~ error.message
              raise error
            end
            full_message = build_message(message, "<?> expected to be thrown but\n<?> was thrown.", expected_symbol, $1.intern)
            flunk(full_message)
          end
        end
      end

      ##
      # Passes if block does not throw anything.
      #
      # Example:
      #  assert_nothing_thrown do
      #    [1, 2].uniq
      #  end

      public
      def assert_nothing_thrown(message="", &proc)
        _wrap_assertion do
          assert(block_given?, "Should have passed a block to assert_nothing_thrown")
          begin
            proc.call
          rescue NameError, ThreadError => error
            if UncaughtThrow[error.class] !~ error.message
              raise error
            end
            full_message = build_message(message, "<?> was thrown when nothing was expected", $1.intern)
            flunk(full_message)
          end
          assert(true, "Expected nothing to be thrown")
        end
      end

      ##
      # Passes if +expected_float+ and +actual_float+ are equal
      # within +delta+ tolerance.
      #
      # Example:
      #   assert_in_delta 0.05, (50000.0 / 10**6), 0.00001

      public
      def assert_in_delta(expected_float, actual_float, delta, message="")
        _wrap_assertion do
          {expected_float => "first float", actual_float => "second float", delta => "delta"}.each do |float, name|
            assert_respond_to(float, :to_f, "The arguments must respond to to_f; the #{name} did not")
          end
          assert_operator(delta, :>=, 0.0, "The delta should not be negative")
          full_message = build_message(message, <<EOT, expected_float, actual_float, delta)
<?> and
<?> expected to be within
<?> of each other.
EOT
          assert_block(full_message) { (expected_float.to_f - actual_float.to_f).abs <= delta.to_f }
        end
      end

      ##
      # Passes if the method send returns a true value.
      #
      # +send_array+ is composed of:
      # * A receiver
      # * A method
      # * Arguments to the method
      #
      # Example:
      #   assert_send [[1, 2], :include?, 4]

      public
      def assert_send(send_array, message="")
        _wrap_assertion do
          assert_instance_of(Array, send_array, "assert_send requires an array of send information")
          assert(send_array.size >= 2, "assert_send requires at least a receiver and a message name")
          full_message = build_message(message, <<EOT, send_array[0], AssertionMessage.literal(send_array[1].to_s), send_array[2..-1])
<?> expected to respond to
<?(?)> with a true value.
EOT
          assert_block(full_message) { send_array[0].__send__(send_array[1], *send_array[2..-1]) }
        end
      end

      ##
      # Builds a failure message.  +head+ is added before the +template+ and
      # +arguments+ replaces the '?'s positionally in the template.

      public
      def build_message(head, template=nil, *arguments)
        template &&= template.chomp
        return AssertionMessage.new(head, template, arguments)
      end

      private
      def _wrap_assertion
        @_assertion_wrapped ||= false
        unless (@_assertion_wrapped)
          @_assertion_wrapped = true
          begin
            add_assertion
            return yield
          ensure
            @_assertion_wrapped = false
          end
        else
          return yield
        end
      end
      
      ##
      # Called whenever an assertion is made.  Define this in classes that
      # include Test::Unit::Assertions to record assertion counts.

      private
      def add_assertion
      end

      ##
      # Select whether or not to use the pretty-printer. If this option is set
      # to false before any assertions are made, pp.rb will not be required.

      public
      def self.use_pp=(value)
        AssertionMessage.use_pp = value
      end
      
      # :stopdoc:

      class AssertionMessage
        @use_pp = true
        class << self
          attr_accessor :use_pp
        end

        class Literal
          def initialize(value)
            @value = value
          end
          
          def inspect
            @value.to_s
          end
        end

        class Template
          def self.create(string)
            parts = (string ? string.scan(/(?=[^\\])\?|(?:\\\?|[^\?])+/m) : [])
            self.new(parts)
          end

          attr_reader :count

          def initialize(parts)
            @parts = parts
            @count = parts.find_all{|e| e == '?'}.size
          end

          def result(parameters)
            raise "The number of parameters does not match the number of substitutions." if(parameters.size != count)
            params = parameters.dup
            @parts.collect{|e| e == '?' ? params.shift : e.gsub(/\\\?/m, '?')}.join('')
          end
        end

        def self.literal(value)
          Literal.new(value)
        end

        include Util::BacktraceFilter

        def initialize(head, template_string, parameters)
          @head = head
          @template_string = template_string
          @parameters = parameters
        end

        def convert(object)
          case object
            when Exception
              <<EOM.chop
Class: <#{convert(object.class)}>
Message: <#{convert(object.message)}>
---Backtrace---
#{filter_backtrace(object.backtrace).join("\n")}
---------------
EOM
            else
              if(self.class.use_pp)
                begin
                  require 'pp'
                rescue LoadError
                  self.class.use_pp = false
                  return object.inspect
                end unless(defined?(PP))
                PP.pp(object, '').chomp
              else
                object.inspect
              end
          end
        end

        def template
          @template ||= Template.create(@template_string)
        end

        def add_period(string)
          (string =~ /\.\Z/ ? string : string + '.')
        end

        def to_s
          message_parts = []
          if (@head)
            head = @head.to_s 
            unless(head.empty?)
              message_parts << add_period(head)
            end
          end
          tail = template.result(@parameters.collect{|e| convert(e)})
          message_parts << tail unless(tail.empty?)
          message_parts.join("\n")
        end
      end

      # :startdoc:

    end
  end
end
PK     Z\    !  test/unit/util/backtracefilter.rbnu [        module Test
  module Unit
    module Util
      module BacktraceFilter
        TESTUNIT_FILE_SEPARATORS = %r{[\\/:]}
        TESTUNIT_PREFIX = __FILE__.split(TESTUNIT_FILE_SEPARATORS)[0..-3]
        TESTUNIT_RB_FILE = /\.rb\Z/
        
        def filter_backtrace(backtrace, prefix=nil)
          return ["No backtrace"] unless(backtrace)
          split_p = if(prefix)
            prefix.split(TESTUNIT_FILE_SEPARATORS)
          else
            TESTUNIT_PREFIX
          end
          match = proc do |e|
            split_e = e.split(TESTUNIT_FILE_SEPARATORS)[0, split_p.size]
            next false unless(split_e[0..-2] == split_p[0..-2])
            split_e[-1].sub(TESTUNIT_RB_FILE, '') == split_p[-1]
          end
          return backtrace unless(backtrace.detect(&match))
          found_prefix = false
          new_backtrace = backtrace.reverse.reject do |e|
            if(match[e])
              found_prefix = true
              true
            elsif(found_prefix)
              false
            else
              true
            end
          end.reverse
          new_backtrace = (new_backtrace.empty? ? backtrace : new_backtrace)
          new_backtrace = new_backtrace.reject(&match)
          new_backtrace.empty? ? backtrace : new_backtrace
        end
      end
    end
  end
end
PK     Z\}hU  U    test/unit/util/procwrapper.rbnu [        #--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

module Test
  module Unit
    module Util

      # Allows the storage of a Proc passed through '&' in a
      # hash.
      #
      # Note: this may be inefficient, since the hash being
      # used is not necessarily very good. In Observable,
      # efficiency is not too important, since the hash is
      # only accessed when adding and removing listeners,
      # not when notifying.

      class ProcWrapper

        # Creates a new wrapper for a_proc.
        def initialize(a_proc)
          @a_proc = a_proc
          @hash = a_proc.inspect.sub(/^(#<#{a_proc.class}:)/){''}.sub(/(>)$/){''}.hex
        end

        def hash
          return @hash
        end

        def ==(other)
          case(other)
            when ProcWrapper
              return @a_proc == other.to_proc
            else
              return super
          end
        end
        alias :eql? :==

        def to_proc
          return @a_proc
        end
      end
    end
  end
end
PK     Z\y3  3    test/unit/util/observable.rbnu [        #--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit/util/procwrapper'

module Test
  module Unit
    module Util

      # This is a utility class that allows anything mixing
      # it in to notify a set of listeners about interesting
      # events.
      module Observable
        # We use this for defaults since nil might mean something
        NOTHING = "NOTHING/#{__id__}"

        # Adds the passed proc as a listener on the
        # channel indicated by channel_name. listener_key
        # is used to remove the listener later; if none is
        # specified, the proc itself is used.
        #
        # Whatever is used as the listener_key is
        # returned, making it very easy to use the proc
        # itself as the listener_key:
        #
        #  listener = add_listener("Channel") { ... }
        #  remove_listener("Channel", listener)
        def add_listener(channel_name, listener_key=NOTHING, &listener) # :yields: value
          unless(block_given?)
            raise ArgumentError.new("No callback was passed as a listener")
          end
      
          key = listener_key
          if (listener_key == NOTHING)
            listener_key = listener
            key = ProcWrapper.new(listener)
          end
      
          channels[channel_name] ||= {}
          channels[channel_name][key] = listener
          return listener_key
        end

        # Removes the listener indicated by listener_key
        # from the channel indicated by
        # channel_name. Returns the registered proc, or
        # nil if none was found.
        def remove_listener(channel_name, listener_key)
          channel = channels[channel_name]
          return nil unless (channel)
          key = listener_key
          if (listener_key.instance_of?(Proc))
            key = ProcWrapper.new(listener_key)
          end
          if (channel.has_key?(key))
            return channel.delete(key)
          end
          return nil
        end

        # Calls all the procs registered on the channel
        # indicated by channel_name. If value is
        # specified, it is passed in to the procs,
        # otherwise they are called with no arguments.
        #
        #--
        #
        # Perhaps this should be private? Would it ever
        # make sense for an external class to call this
        # method directly?
        def notify_listeners(channel_name, *arguments)
          channel = channels[channel_name]
          return 0 unless (channel)
          listeners = channel.values
          listeners.each { |listener| listener.call(*arguments) }
          return listeners.size
        end

        private
        def channels
          @channels ||= {}
          return @channels
        end
      end
    end
  end
end
PK     Z\x      test/unit/testcase.rbnu [        #--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit/assertions'
require 'test/unit/failure'
require 'test/unit/error'
require 'test/unit/testsuite'
require 'test/unit/assertionfailederror'
require 'test/unit/util/backtracefilter'

module Test
  module Unit

    # Ties everything together. If you subclass and add your own
    # test methods, it takes care of making them into tests and
    # wrapping those tests into a suite. It also does the
    # nitty-gritty of actually running an individual test and
    # collecting its results into a Test::Unit::TestResult object.
    class TestCase
      include Assertions
      include Util::BacktraceFilter
      
      attr_reader :method_name
      
      STARTED = name + "::STARTED"
      FINISHED = name + "::FINISHED"

      ##
      # These exceptions are not caught by #run.

      PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, Interrupt,
                                SystemExit]

      # Creates a new instance of the fixture for running the
      # test represented by test_method_name.
      def initialize(test_method_name)
        unless(respond_to?(test_method_name) and
               (method(test_method_name).arity == 0 ||
                method(test_method_name).arity == -1))
          throw :invalid_test
        end
        @method_name = test_method_name
        @test_passed = true
      end

      # Rolls up all of the test* methods in the fixture into
      # one suite, creating a new instance of the fixture for
      # each method.
      def self.suite
        method_names = public_instance_methods(true)
        tests = method_names.delete_if {|method_name| method_name !~ /^test./}
        suite = TestSuite.new(name)
        tests.sort.each do
          |test|
          catch(:invalid_test) do
            suite << new(test)
          end
        end
        if (suite.empty?)
          catch(:invalid_test) do
            suite << new("default_test")
          end
        end
        return suite
      end

      # Runs the individual test method represented by this
      # instance of the fixture, collecting statistics, failures
      # and errors in result.
      def run(result)
        yield(STARTED, name)
        @_result = result
        begin
          setup
          __send__(@method_name)
        rescue AssertionFailedError => e
          add_failure(e.message, e.backtrace)
        rescue Exception
          raise if PASSTHROUGH_EXCEPTIONS.include? $!.class
          add_error($!)
        ensure
          begin
            teardown
          rescue AssertionFailedError => e
            add_failure(e.message, e.backtrace)
          rescue Exception
            raise if PASSTHROUGH_EXCEPTIONS.include? $!.class
            add_error($!)
          end
        end
        result.add_run
        yield(FINISHED, name)
      end

      # Called before every test method runs. Can be used
      # to set up fixture information.
      def setup
      end

      # Called after every test method runs. Can be used to tear
      # down fixture information.
      def teardown
      end
      
      def default_test
        flunk("No tests were specified")
      end

      # Returns whether this individual test passed or
      # not. Primarily for use in teardown so that artifacts
      # can be left behind if the test fails.
      def passed?
        return @test_passed
      end
      private :passed?

      def size
        1
      end

      def add_assertion
        @_result.add_assertion
      end
      private :add_assertion

      def add_failure(message, all_locations=caller())
        @test_passed = false
        @_result.add_failure(Failure.new(name, filter_backtrace(all_locations), message))
      end
      private :add_failure

      def add_error(exception)
        @test_passed = false
        @_result.add_error(Error.new(name, exception))
      end
      private :add_error

      # Returns a human-readable name for the specific test that
      # this instance of TestCase represents.
      def name
        "#{@method_name}(#{self.class.name})"
      end

      # Overridden to return #name.
      def to_s
        name
      end
      
      # It's handy to be able to compare TestCase instances.
      def ==(other)
        return false unless(other.kind_of?(self.class))
        return false unless(@method_name == other.method_name)
        self.class == other.class
      end
    end
  end
end
PK     Z\Fӥ      test/unit/testsuite.rbnu [        #--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

module Test
  module Unit

    # A collection of tests which can be #run.
    #
    # Note: It is easy to confuse a TestSuite instance with
    # something that has a static suite method; I know because _I_
    # have trouble keeping them straight. Think of something that
    # has a suite method as simply providing a way to get a
    # meaningful TestSuite instance.
    class TestSuite
      attr_reader :name, :tests
      
      STARTED = name + "::STARTED"
      FINISHED = name + "::FINISHED"

      # Creates a new TestSuite with the given name.
      def initialize(name="Unnamed TestSuite")
        @name = name
        @tests = []
      end

      # Runs the tests and/or suites contained in this
      # TestSuite.
      def run(result, &progress_block)
        yield(STARTED, name)
        @tests.each do |test|
          test.run(result, &progress_block)
        end
        yield(FINISHED, name)
      end

      # Adds the test to the suite.
      def <<(test)
        @tests << test
        self
      end

      def delete(test)
        @tests.delete(test)
      end

      # Retuns the rolled up number of tests in this suite;
      # i.e. if the suite contains other suites, it counts the
      # tests within those suites, not the suites themselves.
      def size
        total_size = 0
        @tests.each { |test| total_size += test.size }
        total_size
      end
      
      def empty?
        tests.empty?
      end

      # Overridden to return the name given the suite at
      # creation.
      def to_s
        @name
      end
      
      # It's handy to be able to compare TestSuite instances.
      def ==(other)
        return false unless(other.kind_of?(self.class))
        return false unless(@name == other.name)
        @tests == other.tests
      end
    end
  end
end
PK     Z\      test/unit/error.rbnu [        #--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.

require 'test/unit/util/backtracefilter'

module Test
  module Unit

    # Encapsulates an error in a test. Created by
    # Test::Unit::TestCase when it rescues an exception thrown
    # during the processing of a test.
    class Error
      include Util::BacktraceFilter

      attr_reader(:test_name, :exception)

      SINGLE_CHARACTER = 'E'

      # Creates a new Error with the given test_name and
      # exception.
      def initialize(test_name, exception)
        @test_name = test_name
        @exception = exception
      end

      # Returns a single character representation of an error.
      def single_character_display
        SINGLE_CHARACTER
      end

      # Returns the message associated with the error.
      def message
        "#{@exception.class.name}: #{@exception.message}"
      end

      # Returns a brief version of the error description.
      def short_display
        "#@test_name: #{message.split("\n")[0]}"
      end

      # Returns a verbose version of the error description.
      def long_display
        backtrace = filter_backtrace(@exception.backtrace).join("\n    ")
        "Error:\n#@test_name:\n#{message}\n    #{backtrace}"
      end

      # Overridden to return long_display.
      def to_s
        long_display
      end
    end
  end
end
PK     Z\$q+  q+    test/unit.rbnu [        require 'test/unit/testcase'
require 'test/unit/autorunner'

module Test # :nodoc:
  #
  # = Test::Unit - Ruby Unit Testing Framework
  # 
  # == Introduction
  # 
  # Unit testing is making waves all over the place, largely due to the
  # fact that it is a core practice of XP. While XP is great, unit testing
  # has been around for a long time and has always been a good idea. One
  # of the keys to good unit testing, though, is not just writing tests,
  # but having tests. What's the difference? Well, if you just _write_ a
  # test and throw it away, you have no guarantee that something won't
  # change later which breaks your code. If, on the other hand, you _have_
  # tests (obviously you have to write them first), and run them as often
  # as possible, you slowly build up a wall of things that cannot break
  # without you immediately knowing about it. This is when unit testing
  # hits its peak usefulness.
  # 
  # Enter Test::Unit, a framework for unit testing in Ruby, helping you to
  # design, debug and evaluate your code by making it easy to write and
  # have tests for it.
  # 
  # 
  # == Notes
  # 
  # Test::Unit has grown out of and superceded Lapidary.
  # 
  # 
  # == Feedback
  # 
  # I like (and do my best to practice) XP, so I value early releases,
  # user feedback, and clean, simple, expressive code. There is always
  # room for improvement in everything I do, and Test::Unit is no
  # exception. Please, let me know what you think of Test::Unit as it
  # stands, and what you'd like to see expanded/changed/improved/etc. If
  # you find a bug, let me know ASAP; one good way to let me know what the
  # bug is is to submit a new test that catches it :-) Also, I'd love to
  # hear about any successes you have with Test::Unit, and any
  # documentation you might add will be greatly appreciated. My contact
  # info is below.
  # 
  # 
  # == Contact Information
  # 
  # A lot of discussion happens about Ruby in general on the ruby-talk
  # mailing list (http://www.ruby-lang.org/en/ml.html), and you can ask
  # any questions you might have there. I monitor the list, as do many
  # other helpful Rubyists, and you're sure to get a quick answer. Of
  # course, you're also welcome to email me (Nathaniel Talbott) directly
  # at mailto:testunit@talbott.ws, and I'll do my best to help you out.
  # 
  # 
  # == Credits
  # 
  # I'd like to thank...
  # 
  # Matz, for a great language!
  # 
  # Masaki Suketa, for his work on RubyUnit, which filled a vital need in
  # the Ruby world for a very long time. I'm also grateful for his help in
  # polishing Test::Unit and getting the RubyUnit compatibility layer
  # right. His graciousness in allowing Test::Unit to supercede RubyUnit
  # continues to be a challenge to me to be more willing to defer my own
  # rights.
  # 
  # Ken McKinlay, for his interest and work on unit testing, and for his
  # willingness to dialog about it. He was also a great help in pointing
  # out some of the holes in the RubyUnit compatibility layer.
  # 
  # Dave Thomas, for the original idea that led to the extremely simple
  # "require 'test/unit'", plus his code to improve it even more by
  # allowing the selection of tests from the command-line. Also, without
  # RDoc, the documentation for Test::Unit would stink a lot more than it
  # does now.
  # 
  # Everyone who's helped out with bug reports, feature ideas,
  # encouragement to continue, etc. It's a real privilege to be a part of
  # the Ruby community.
  # 
  # The guys at RoleModel Software, for putting up with me repeating, "But
  # this would be so much easier in Ruby!" whenever we're coding in Java.
  # 
  # My Creator, for giving me life, and giving it more abundantly.
  # 
  # 
  # == License
  # 
  # Test::Unit is copyright (c) 2000-2003 Nathaniel Talbott. It is free
  # software, and is distributed under the Ruby license. See the COPYING
  # file in the standard Ruby distribution for details.
  # 
  # 
  # == Warranty
  # 
  # This software is provided "as is" and without any express or
  # implied warranties, including, without limitation, the implied
  # warranties of merchantibility and fitness for a particular
  # purpose.
  # 
  # 
  # == Author
  # 
  # Nathaniel Talbott.
  # Copyright (c) 2000-2003, Nathaniel Talbott
  #
  # ----
  #
  # = Usage
  #
  # The general idea behind unit testing is that you write a _test_
  # _method_ that makes certain _assertions_ about your code, working
  # against a _test_ _fixture_. A bunch of these _test_ _methods_ are
  # bundled up into a _test_ _suite_ and can be run any time the
  # developer wants. The results of a run are gathered in a _test_
  # _result_ and displayed to the user through some UI. So, lets break
  # this down and see how Test::Unit provides each of these necessary
  # pieces.
  #
  #
  # == Assertions
  #
  # These are the heart of the framework. Think of an assertion as a
  # statement of expected outcome, i.e. "I assert that x should be equal
  # to y". If, when the assertion is executed, it turns out to be
  # correct, nothing happens, and life is good. If, on the other hand,
  # your assertion turns out to be false, an error is propagated with
  # pertinent information so that you can go back and make your
  # assertion succeed, and, once again, life is good. For an explanation
  # of the current assertions, see Test::Unit::Assertions.
  #
  #
  # == Test Method & Test Fixture
  #
  # Obviously, these assertions have to be called within a context that
  # knows about them and can do something meaningful with their
  # pass/fail value. Also, it's handy to collect a bunch of related
  # tests, each test represented by a method, into a common test class
  # that knows how to run them. The tests will be in a separate class
  # from the code they're testing for a couple of reasons. First of all,
  # it allows your code to stay uncluttered with test code, making it
  # easier to maintain. Second, it allows the tests to be stripped out
  # for deployment, since they're really there for you, the developer,
  # and your users don't need them. Third, and most importantly, it
  # allows you to set up a common test fixture for your tests to run
  # against.
  #
  # What's a test fixture? Well, tests do not live in a vacuum; rather,
  # they're run against the code they are testing. Often, a collection
  # of tests will run against a common set of data, also called a
  # fixture. If they're all bundled into the same test class, they can
  # all share the setting up and tearing down of that data, eliminating
  # unnecessary duplication and making it much easier to add related
  # tests.
  #
  # Test::Unit::TestCase wraps up a collection of test methods together
  # and allows you to easily set up and tear down the same test fixture
  # for each test. This is done by overriding #setup and/or #teardown,
  # which will be called before and after each test method that is
  # run. The TestCase also knows how to collect the results of your
  # assertions into a Test::Unit::TestResult, which can then be reported
  # back to you... but I'm getting ahead of myself. To write a test,
  # follow these steps:
  #
  # * Make sure Test::Unit is in your library path.
  # * require 'test/unit' in your test script.
  # * Create a class that subclasses Test::Unit::TestCase.
  # * Add a method that begins with "test" to your class.
  # * Make assertions in your test method.
  # * Optionally define #setup and/or #teardown to set up and/or tear
  #   down your common test fixture.
  # * You can now run your test as you would any other Ruby
  #   script... try it and see!
  #
  # A really simple test might look like this (#setup and #teardown are
  # commented out to indicate that they are completely optional):
  #
  #     require 'test/unit'
  #     
  #     class TC_MyTest < Test::Unit::TestCase
  #       # def setup
  #       # end
  #     
  #       # def teardown
  #       # end
  #     
  #       def test_fail
  #         assert(false, 'Assertion was false.')
  #       end
  #     end
  #
  #
  # == Test Runners
  #
  # So, now you have this great test class, but you still need a way to
  # run it and view any failures that occur during the run. This is
  # where Test::Unit::UI::Console::TestRunner (and others, such as
  # Test::Unit::UI::GTK::TestRunner) comes into play. The console test
  # runner is automatically invoked for you if you require 'test/unit'
  # and simply run the file. To use another runner, or to manually
  # invoke a runner, simply call its run class method and pass in an
  # object that responds to the suite message with a
  # Test::Unit::TestSuite. This can be as simple as passing in your
  # TestCase class (which has a class suite method). It might look
  # something like this:
  #
  #    require 'test/unit/ui/console/testrunner'
  #    Test::Unit::UI::Console::TestRunner.run(TC_MyTest)
  #
  #
  # == Test Suite
  #
  # As more and more unit tests accumulate for a given project, it
  # becomes a real drag running them one at a time, and it also
  # introduces the potential to overlook a failing test because you
  # forget to run it. Suddenly it becomes very handy that the
  # TestRunners can take any object that returns a Test::Unit::TestSuite
  # in response to a suite method. The TestSuite can, in turn, contain
  # other TestSuites or individual tests (typically created by a
  # TestCase). In other words, you can easily wrap up a group of
  # TestCases and TestSuites like this:
  #
  #  require 'test/unit/testsuite'
  #  require 'tc_myfirsttests'
  #  require 'tc_moretestsbyme'
  #  require 'ts_anothersetoftests'
  #
  #  class TS_MyTests
  #    def self.suite
  #      suite = Test::Unit::TestSuite.new
  #      suite << TC_MyFirstTests.suite
  #      suite << TC_MoreTestsByMe.suite
  #      suite << TS_AnotherSetOfTests.suite
  #      return suite
  #    end
  #  end
  #  Test::Unit::UI::Console::TestRunner.run(TS_MyTests)
  #
  # Now, this is a bit cumbersome, so Test::Unit does a little bit more
  # for you, by wrapping these up automatically when you require
  # 'test/unit'. What does this mean? It means you could write the above
  # test case like this instead:
  #
  #  require 'test/unit'
  #  require 'tc_myfirsttests'
  #  require 'tc_moretestsbyme'
  #  require 'ts_anothersetoftests'
  #
  # Test::Unit is smart enough to find all the test cases existing in
  # the ObjectSpace and wrap them up into a suite for you. It then runs
  # the dynamic suite using the console TestRunner.
  #
  #
  # == Questions?
  #
  # I'd really like to get feedback from all levels of Ruby
  # practitioners about typos, grammatical errors, unclear statements,
  # missing points, etc., in this document (or any other).
  #

  module Unit
    # Set true when Test::Unit has run.  If set to true Test::Unit
    # will not automatically run at exit.
    def self.run=(flag)
      @run = flag
    end

    # Already tests have run?
    def self.run?
      @run ||= false
    end
  end
end

at_exit do
  unless $! || Test::Unit.run?
    Kernel.exit Test::Unit::AutoRunner.run
  end
end
PK     Z\`	      xmlrpc/create.rbnu [        #
# Creates XML-RPC call/response documents
# 
# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)
#
# $Id: create.rb 11818 2007-02-23 03:45:55Z knu $
#

require "date"
require "xmlrpc/base64"

module XMLRPC

  module XMLWriter

    class Abstract
      def ele(name, *children)
	element(name, nil, *children)
      end

      def tag(name, txt)
	element(name, nil, text(txt))
      end
    end


    class Simple < Abstract

      def document_to_str(doc)
	doc
      end

      def document(*params)
	params.join("")
      end

      def pi(name, *params)
	"<?#{name} " + params.join(" ") + " ?>"
      end

      def element(name, attrs, *children)
	raise "attributes not yet implemented" unless attrs.nil?
        if children.empty?
          "<#{name}/>" 
        else
          "<#{name}>" + children.join("") + "</#{name}>"
        end
      end

      def text(txt)
        cleaned = txt.dup
        cleaned.gsub!(/&/, '&amp;')
        cleaned.gsub!(/</, '&lt;')
        cleaned.gsub!(/>/, '&gt;')
        cleaned
      end

    end # class Simple


    class XMLParser < Abstract

      def initialize
	require "xmltreebuilder"
      end

      def document_to_str(doc)
	doc.to_s
      end

      def document(*params)
	XML::SimpleTree::Document.new(*params) 
      end

      def pi(name, *params)
	XML::SimpleTree::ProcessingInstruction.new(name, *params)
      end

      def element(name, attrs, *children)
	XML::SimpleTree::Element.new(name, attrs, *children)
      end

      def text(txt)
	XML::SimpleTree::Text.new(txt)
      end

    end # class XMLParser

    Classes = [Simple, XMLParser]

    # yields an instance of each installed XML writer
    def self.each_installed_writer
      XMLRPC::XMLWriter::Classes.each do |klass|
        begin
          yield klass.new
        rescue LoadError
        end
      end
    end

  end # module XMLWriter

  class Create

    def initialize(xml_writer = nil)
      @writer = xml_writer || Config::DEFAULT_WRITER.new
    end


    def methodCall(name, *params)
      name = name.to_s

      if name !~ /[a-zA-Z0-9_.:\/]+/
	raise ArgumentError, "Wrong XML-RPC method-name"
      end

      parameter = params.collect do |param|
	@writer.ele("param", conv2value(param))
      end

      tree = @writer.document(
	       @writer.pi("xml", 'version="1.0"'),
	       @writer.ele("methodCall",   
		 @writer.tag("methodName", name),
		 @writer.ele("params", *parameter)    
	       )
	     )

      @writer.document_to_str(tree) + "\n"
    end



    #
    # generates a XML-RPC methodResponse document
    #
    # if is_ret == false then the params array must
    # contain only one element, which is a structure
    # of a fault return-value.
    # 
    # if is_ret == true then a normal 
    # return-value of all the given params is created.
    #
    def methodResponse(is_ret, *params)

      if is_ret 
	resp = params.collect do |param|
	  @writer.ele("param", conv2value(param))
	end
     
	resp = [@writer.ele("params", *resp)]
      else
	if params.size != 1 or params[0] === XMLRPC::FaultException 
	  raise ArgumentError, "no valid fault-structure given"
	end
	resp = @writer.ele("fault", conv2value(params[0].to_h))
      end

	
      tree = @writer.document(
	       @writer.pi("xml", 'version="1.0"'),
	       @writer.ele("methodResponse", resp) 
	     )

      @writer.document_to_str(tree) + "\n"
    end



    #####################################
    private
    #####################################

    #
    # converts a Ruby object into
    # a XML-RPC <value> tag
    #
    def conv2value(param)

	val = case param
	when Fixnum 
	  @writer.tag("i4", param.to_s)

	when Bignum
          if Config::ENABLE_BIGINT
            @writer.tag("i4", param.to_s)
          else
            if param >= -(2**31) and param <= (2**31-1)
              @writer.tag("i4", param.to_s)
            else
              raise "Bignum is too big! Must be signed 32-bit integer!"
            end
          end
	when TrueClass, FalseClass
	  @writer.tag("boolean", param ? "1" : "0")

	when String 
	  @writer.tag("string", param)

	when Symbol 
	  @writer.tag("string", param.to_s)

        when NilClass
          if Config::ENABLE_NIL_CREATE
            @writer.ele("nil")
          else
            raise "Wrong type NilClass. Not allowed!"
          end

	when Float
	  @writer.tag("double", param.to_s)

	when Struct
	  h = param.members.collect do |key| 
	    value = param[key]
	    @writer.ele("member", 
	      @writer.tag("name", key.to_s),
	      conv2value(value) 
	    )
	  end

	  @writer.ele("struct", *h) 

	when Hash
	  # TODO: can a Hash be empty?
	  
	  h = param.collect do |key, value|
	    @writer.ele("member", 
	      @writer.tag("name", key.to_s),
	      conv2value(value) 
	    )
	  end

	  @writer.ele("struct", *h) 

	when Array
	  # TODO: can an Array be empty?
	  a = param.collect {|v| conv2value(v) }
	  
	  @writer.ele("array", 
	    @writer.ele("data", *a)
	  )

	when Time, Date, ::DateTime
	  @writer.tag("dateTime.iso8601", param.strftime("%Y%m%dT%H:%M:%S"))  

	when XMLRPC::DateTime
	  @writer.tag("dateTime.iso8601", 
	    format("%.4d%02d%02dT%02d:%02d:%02d", *param.to_a))
   
	when XMLRPC::Base64
	  @writer.tag("base64", param.encoded) 

	else 
          if Config::ENABLE_MARSHALLING and param.class.included_modules.include? XMLRPC::Marshallable
            # convert Ruby object into Hash
            ret = {"___class___" => param.class.name}
            param.instance_variables.each {|v| 
              name = v[1..-1]
              val = param.instance_variable_get(v)

              if val.nil?
                ret[name] = val if Config::ENABLE_NIL_CREATE
              else
                ret[name] = val
              end
            }
            return conv2value(ret)
          else 
            ok, pa = wrong_type(param)
            if ok
              return conv2value(pa)
            else 
              raise "Wrong type!"
            end
          end
	end
	 
	@writer.ele("value", val)
    end

    def wrong_type(value)
      false
    end

    
  end # class Create

end # module XMLRPC

PK     Z\J  J    xmlrpc/client.rbnu [        =begin
= xmlrpc/client.rb
Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)

Released under the same term of license as Ruby.

= Classes
* ((<XMLRPC::Client>))
* ((<XMLRPC::Client::Proxy>))


= XMLRPC::Client
== Synopsis
    require "xmlrpc/client"

    server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80)
    begin
      param = server.call("michael.add", 4, 5)
      puts "4 + 5 = #{param}"
    rescue XMLRPC::FaultException => e
      puts "Error:"
      puts e.faultCode
      puts e.faultString
    end

or

    require "xmlrpc/client"
  
    server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80)
    ok, param = server.call2("michael.add", 4, 5)
    if ok then
      puts "4 + 5 = #{param}"
    else
      puts "Error:"
      puts param.faultCode
      puts param.faultString
    end

== Description
Class (({XMLRPC::Client})) provides remote procedure calls to a XML-RPC server.
After setting the connection-parameters with ((<XMLRPC::Client.new>)) which
creates a new (({XMLRPC::Client})) instance, you can execute a remote procedure 
by sending the ((<call|XMLRPC::Client#call>)) or ((<call2|XMLRPC::Client#call2>))
message to this new instance. The given parameters indicate which method to 
call on the remote-side and of course the parameters for the remote procedure.

== Class Methods
--- XMLRPC::Client.new( host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil, user=nil, password=nil, use_ssl=false, timeout =nil)
    Creates an object which represents the remote XML-RPC server on the 
    given host ((|host|)). If the server is CGI-based, ((|path|)) is the
    path to the CGI-script, which will be called, otherwise (in the
    case of a standalone server) ((|path|)) should be (({"/RPC2"})).
    ((|port|)) is the port on which the XML-RPC server listens.
    If ((|proxy_host|)) is given, then a proxy server listening at
    ((|proxy_host|)) is used. ((|proxy_port|)) is the port of the
    proxy server.

    Default values for ((|host|)), ((|path|)) and ((|port|)) are 'localhost', '/RPC2' and
    '80' respectively using SSL '443'.

    If ((|user|)) and ((|password|)) are given, each time a request is send, 
    a Authorization header is send. Currently only Basic Authentification is 
    implemented no Digest.

    If ((|use_ssl|)) is set to (({true})), comunication over SSL is enabled.
    Note, that you need the SSL package from RAA installed.

    Parameter ((|timeout|)) is the time to wait for a XML-RPC response, defaults to 30.

--- XMLRPC::Client.new2( uri, proxy=nil, timeout=nil)
--- XMLRPC::Client.new_from_uri( uri, proxy=nil, timeout=nil)
:   uri
    URI specifying protocol (http or https), host, port, path, user and password.
    Example: https://user:password@host:port/path

:   proxy
    Is of the form "host:port".
 
:   timeout
    Defaults to 30. 

--- XMLRPC::Client.new3( hash={} )
--- XMLRPC::Client.new_from_hash( hash={} )
    Parameter ((|hash|)) has following case-insensitive keys:
    * host
    * path
    * port
    * proxy_host
    * proxy_port
    * user
    * password
    * use_ssl
    * timeout

    Calls ((<XMLRPC::Client.new>)) with the corresponding values.

== Instance Methods
--- XMLRPC::Client#call( method, *args )
    Invokes the method named ((|method|)) with the parameters given by 
    ((|args|)) on the XML-RPC server.
    The parameter ((|method|)) is converted into a (({String})) and should 
    be a valid XML-RPC method-name.  
    Each parameter of ((|args|)) must be of one of the following types,
    where (({Hash})), (({Struct})) and (({Array})) can contain any of these listed ((:types:)):
    * (({Fixnum})), (({Bignum}))
    * (({TrueClass})), (({FalseClass})) ((({true})), (({false})))
    * (({String})), (({Symbol}))
    * (({Float}))
    * (({Hash})), (({Struct}))
    * (({Array}))
    * (({Date})), (({Time})), (({XMLRPC::DateTime}))
    * (({XMLRPC::Base64})) 
    * A Ruby object which class includes XMLRPC::Marshallable (only if Config::ENABLE_MARSHALLABLE is (({true}))). 
      That object is converted into a hash, with one additional key/value pair "___class___" which contains the class name
      for restoring later that object.
    
    The method returns the return-value from the RPC 
    ((-stands for Remote Procedure Call-)). 
    The type of the return-value is one of the above shown,
    only that a (({Bignum})) is only allowed when it fits in 32-bit and
    that a XML-RPC (('dateTime.iso8601')) type is always returned as
    a ((<(({XMLRPC::DateTime}))|URL:datetime.html>)) object and 
    a (({Struct})) is never returned, only a (({Hash})), the same for a (({Symbol})), where
    always a (({String})) is returned. 
    A (({XMLRPC::Base64})) is returned as a (({String})) from xmlrpc4r version 1.6.1 on.
    
    If the remote procedure returned a fault-structure, then a 
    (({XMLRPC::FaultException})) exception is raised, which has two accessor-methods
    (({faultCode})) and (({faultString})) of type (({Integer})) and (({String})).

--- XMLRPC::Client#call2( method, *args )
    The difference between this method and ((<call|XMLRPC::Client#call>)) is, that
    this method do ((*not*)) raise a (({XMLRPC::FaultException})) exception.
    The method returns an array of two values. The first value indicates if 
    the second value is a return-value ((({true}))) or an object of type
    (({XMLRPC::FaultException})). 
    Both are explained in ((<call|XMLRPC::Client#call>)).

    Simple to remember: The "2" in "call2" denotes the number of values it returns.

--- XMLRPC::Client#multicall( *methods )
    You can use this method to execute several methods on a XMLRPC server which supports
    the multi-call extension.
    Example:

      s.multicall(
        ['michael.add', 3, 4],
        ['michael.sub', 4, 5]
      )
      # => [7, -1]

--- XMLRPC::Client#multicall2( *methods )
    Same as ((<XMLRPC::Client#multicall>)), but returns like ((<XMLRPC::Client#call2>)) two parameters 
    instead of raising an (({XMLRPC::FaultException})).

--- XMLRPC::Client#proxy( prefix, *args )
    Returns an object of class (({XMLRPC::Client::Proxy})), initialized with
    ((|prefix|)) and ((|args|)). A proxy object returned by this method behaves
    like ((<XMLRPC::Client#call>)), i.e. a call on that object will raise a
    (({XMLRPC::FaultException})) when a fault-structure is returned by that call. 

--- XMLRPC::Client#proxy2( prefix, *args )
    Almost the same like ((<XMLRPC::Client#proxy>)) only that a call on the returned
    (({XMLRPC::Client::Proxy})) object behaves like ((<XMLRPC::Client#call2>)), i.e.
    a call on that object will return two parameters. 




--- XMLRPC::Client#call_async(...)
--- XMLRPC::Client#call2_async(...)
--- XMLRPC::Client#multicall_async(...)
--- XMLRPC::Client#multicall2_async(...)
--- XMLRPC::Client#proxy_async(...)
--- XMLRPC::Client#proxy2_async(...)
    In contrast to corresponding methods without "_async", these can be
    called concurrently and use for each request a new connection, where the 
    non-asynchronous counterparts use connection-alive (one connection for all requests)
    if possible. 

    Note, that you have to use Threads to call these methods concurrently. 
    The following example calls two methods concurrently:
    
      Thread.new {
        p client.call_async("michael.add", 4, 5)
      }
 
      Thread.new {
        p client.call_async("michael.div", 7, 9)
      }
 

--- XMLRPC::Client#timeout
--- XMLRPC::Client#user
--- XMLRPC::Client#password
    Return the corresponding attributes.

--- XMLRPC::Client#timeout= (new_timeout)
--- XMLRPC::Client#user= (new_user)
--- XMLRPC::Client#password= (new_password)
    Set the corresponding attributes.
    

--- XMLRPC::Client#set_writer( writer )
    Sets the XML writer to use for generating XML output.
    Should be an instance of a class from module (({XMLRPC::XMLWriter})).
    If this method is not called, then (({XMLRPC::Config::DEFAULT_WRITER})) is used. 

--- XMLRPC::Client#set_parser( parser )
    Sets the XML parser to use for parsing XML documents.
    Should be an instance of a class from module (({XMLRPC::XMLParser})).
    If this method is not called, then (({XMLRPC::Config::DEFAULT_PARSER})) is used.

--- XMLRPC::Client#cookie
--- XMLRPC::Client#cookie= (cookieString)
    Get and set the HTTP Cookie header.

--- XMLRPC::Client#http_header_extra= (additionalHeaders)
    Set extra HTTP headers that are included in the request.

--- XMLRPC::Client#http_header_extra
    Access the via ((<XMLRPC::Client#http_header_extra=>)) assigned header. 

--- XMLRPC::Client#http_last_response
    Returns the (({Net::HTTPResponse})) object of the last RPC.

= XMLRPC::Client::Proxy
== Synopsis
    require "xmlrpc/client"

    server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80)

    michael  = server.proxy("michael")
    michael2 = server.proxy("michael", 4)

    # both calls should return the same value '9'.
    p michael.add(4,5)
    p michael2.add(5)

== Description
Class (({XMLRPC::Client::Proxy})) makes XML-RPC calls look nicer!
You can call any method onto objects of that class - the object handles 
(({method_missing})) and will forward the method call to a XML-RPC server.
Don't use this class directly, but use instead method ((<XMLRPC::Client#proxy>)) or
((<XMLRPC::Client#proxy2>)).

== Class Methods
--- XMLRPC::Client::Proxy.new( server, prefix, args=[], meth=:call, delim="." ) 
    Creates an object which provides (({method_missing})).

    ((|server|)) must be of type (({XMLRPC::Client})), which is the XML-RPC server to be used
    for a XML-RPC call. ((|prefix|)) and ((|delim|)) will be prepended to the methodname
    called onto this object. 

    Parameter ((|meth|)) is the method (call, call2, call_async, call2_async) to use for
    a RPC.

    ((|args|)) are arguments which are automatically given
    to every XML-RPC call before the arguments provides through (({method_missing})).
    
== Instance Methods
Every method call is forwarded to the XML-RPC server defined in ((<new|XMLRPC::Client::Proxy#new>)).
    
Note: Inherited methods from class (({Object})) cannot be used as XML-RPC names, because they get around
(({method_missing})). 
          


= History
    $Id: client.rb 18091 2008-07-16 17:07:44Z shyouhei $

=end



require "xmlrpc/parser"
require "xmlrpc/create"
require "xmlrpc/config"
require "xmlrpc/utils"     # ParserWriterChooseMixin
require "net/http"

module XMLRPC

  class Client
   
    USER_AGENT = "XMLRPC::Client (Ruby #{RUBY_VERSION})"

    include ParserWriterChooseMixin
    include ParseContentType


    # Constructors -------------------------------------------------------------------

    def initialize(host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil, 
                   user=nil, password=nil, use_ssl=nil, timeout=nil)

      @http_header_extra = nil
      @http_last_response = nil 
      @cookie = nil

      @host       = host || "localhost"
      @path       = path || "/RPC2"
      @proxy_host = proxy_host
      @proxy_port = proxy_port
      @proxy_host ||= 'localhost' if @proxy_port != nil
      @proxy_port ||= 8080 if @proxy_host != nil
      @use_ssl    = use_ssl || false
      @timeout    = timeout || 30

      if use_ssl
        require "net/https"
        @port = port || 443
      else
        @port = port || 80
      end

      @user, @password = user, password

      set_auth

      # convert ports to integers
      @port = @port.to_i if @port != nil
      @proxy_port = @proxy_port.to_i if @proxy_port != nil

      # HTTP object for synchronous calls
      Net::HTTP.version_1_2
      @http = Net::HTTP.new(@host, @port, @proxy_host, @proxy_port) 
      @http.use_ssl = @use_ssl if @use_ssl
      @http.read_timeout = @timeout
      @http.open_timeout = @timeout

      @parser = nil
      @create = nil
    end


    class << self

    def new2(uri, proxy=nil, timeout=nil)
      if match = /^([^:]+):\/\/(([^@]+)@)?([^\/]+)(\/.*)?$/.match(uri)
        proto = match[1]
        user, passwd = (match[3] || "").split(":")
        host, port = match[4].split(":") 
        path = match[5]

        if proto != "http" and proto != "https"
          raise "Wrong protocol specified. Only http or https allowed!"
        end

      else
        raise "Wrong URI as parameter!"
      end
 
      proxy_host, proxy_port = (proxy || "").split(":")

      self.new(host, path, port, proxy_host, proxy_port, user, passwd, (proto == "https"), timeout)
    end

    alias new_from_uri new2

    def new3(hash={})

      # convert all keys into lowercase strings
      h = {}
      hash.each { |k,v| h[k.to_s.downcase] = v }

      self.new(h['host'], h['path'], h['port'], h['proxy_host'], h['proxy_port'], h['user'], h['password'],
               h['use_ssl'], h['timeout'])
    end

    alias new_from_hash new3

    end


    # Attribute Accessors -------------------------------------------------------------------

    # add additional HTTP headers to the request
    attr_accessor :http_header_extra

    # makes last HTTP response accessible
    attr_reader :http_last_response

    # Cookie support
    attr_accessor :cookie
    

    attr_reader :timeout, :user, :password

    def timeout=(new_timeout)
      @timeout = new_timeout
      @http.read_timeout = @timeout
      @http.open_timeout = @timeout
    end

    def user=(new_user)
      @user = new_user
      set_auth
    end

    def password=(new_password)
      @password = new_password
      set_auth
    end

    # Call methods --------------------------------------------------------------

    def call(method, *args)
      ok, param = call2(method, *args) 
      if ok
        param
      else
        raise param
      end
    end 

    def call2(method, *args)
      request = create().methodCall(method, *args)
      data = do_rpc(request, false)
      parser().parseMethodResponse(data)
    end

    def call_async(method, *args)
      ok, param = call2_async(method, *args) 
      if ok
        param
      else
        raise param
      end
    end 

    def call2_async(method, *args)
      request = create().methodCall(method, *args)
      data = do_rpc(request, true)
      parser().parseMethodResponse(data)
    end


    # Multicall methods --------------------------------------------------------------

    def multicall(*methods)
      ok, params = multicall2(*methods)
      if ok
        params
      else
        raise params
      end
    end

    def multicall2(*methods)
      gen_multicall(methods, false)
    end

    def multicall_async(*methods)
      ok, params = multicall2_async(*methods)
      if ok
        params
      else
        raise params
      end
    end

    def multicall2_async(*methods)
      gen_multicall(methods, true)
    end


    # Proxy generating methods ------------------------------------------
    
    def proxy(prefix=nil, *args)
      Proxy.new(self, prefix, args, :call)
    end

    def proxy2(prefix=nil, *args)
      Proxy.new(self, prefix, args, :call2)
    end

    def proxy_async(prefix=nil, *args)
      Proxy.new(self, prefix, args, :call_async)
    end

    def proxy2_async(prefix=nil, *args)
      Proxy.new(self, prefix, args, :call2_async)
    end


    private # ----------------------------------------------------------

    def set_auth
      if @user.nil?
        @auth = nil
      else
        a =  "#@user"
        a << ":#@password" if @password != nil
        @auth = ("Basic " + [a].pack("m")).chomp
      end
    end

    def do_rpc(request, async=false)
      header = {  
       "User-Agent"     =>  USER_AGENT,
       "Content-Type"   => "text/xml; charset=utf-8",
       "Content-Length" => request.size.to_s, 
       "Connection"     => (async ? "close" : "keep-alive")
      }

      header["Cookie"] = @cookie        if @cookie
      header.update(@http_header_extra) if @http_header_extra

      if @auth != nil
        # add authorization header
        header["Authorization"] = @auth
      end
 
      resp = nil
      @http_last_response = nil

      if async
        # use a new HTTP object for each call 
        Net::HTTP.version_1_2
        http = Net::HTTP.new(@host, @port, @proxy_host, @proxy_port) 
        http.use_ssl = @use_ssl if @use_ssl
        http.read_timeout = @timeout
        http.open_timeout = @timeout
        
        # post request
        http.start {
          resp = http.post2(@path, request, header) 
        }
      else
        # reuse the HTTP object for each call => connection alive is possible
        # we must start connection explicitely first time so that http.request
        # does not assume that we don't want keepalive
        @http.start if not @http.started?
        
        # post request
        resp = @http.post2(@path, request, header) 
      end
  
      @http_last_response = resp

      data = resp.body

      if resp.code == "401"
        # Authorization Required
        raise "Authorization failed.\nHTTP-Error: #{resp.code} #{resp.message}" 
      elsif resp.code[0,1] != "2"
        raise "HTTP-Error: #{resp.code} #{resp.message}" 
      end

      ct = parse_content_type(resp["Content-Type"]).first
      if ct != "text/xml"
        if ct == "text/html"
          raise "Wrong content-type (received '#{ct}' but expected 'text/xml'): \n#{data}"
        else
          raise "Wrong content-type (received '#{ct}' but expected 'text/xml')"
        end
      end

      expected = resp["Content-Length"] || "<unknown>"
      if data.nil? or data.size == 0 
        raise "Wrong size. Was #{data.size}, should be #{expected}" 
      elsif expected != "<unknown>" and expected.to_i != data.size and resp["Transfer-Encoding"].nil?
        raise "Wrong size. Was #{data.size}, should be #{expected}"
      end

      set_cookies = resp.get_fields("Set-Cookie")
      if set_cookies and !set_cookies.empty?
        require 'webrick/cookie'
        @cookie = set_cookies.collect do |set_cookie|
          cookie = WEBrick::Cookie.parse_set_cookie(set_cookie)
          WEBrick::Cookie.new(cookie.name, cookie.value).to_s
        end.join("; ")
      end

      return data
    end

    def gen_multicall(methods=[], async=false)
      meth = :call2
      meth = :call2_async if async

      ok, params = self.send(meth, "system.multicall", 
        methods.collect {|m| {'methodName' => m[0], 'params' => m[1..-1]} }
      )

      if ok 
        params = params.collect do |param|
          if param.is_a? Array
            param[0]
          elsif param.is_a? Hash
            XMLRPC::FaultException.new(param["faultCode"], param["faultString"])
          else
            raise "Wrong multicall return value"
          end 
        end
      end

      return ok, params
    end



    class Proxy

      def initialize(server, prefix, args=[], meth=:call, delim=".")
	@server = server
	@prefix = prefix ? prefix + delim : ""
	@args   = args 
        @meth   = meth
      end

      def method_missing(mid, *args)
	pre = @prefix + mid.to_s
	arg = @args + args
	@server.send(@meth, pre, *arg)
      end

    end # class Proxy

  end # class Client

end # module XMLRPC

PK     Z\s      xmlrpc/httpserver.rbnu [        #
# Implements a simple HTTP-server by using John W. Small's (jsmall@laser.net) 
# ruby-generic-server.
# 
# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)
#
# $Id: httpserver.rb 11708 2007-02-12 23:01:19Z shyouhei $
#


require "gserver"

class HttpServer < GServer

  ##
  # handle_obj specifies the object, that receives calls to request_handler
  # and ip_auth_handler 
  def initialize(handle_obj, port = 8080, host = DEFAULT_HOST, maxConnections = 4, 
                 stdlog = $stdout, audit = true, debug = true)
    @handler = handle_obj
    super(port, host, maxConnections, stdlog, audit, debug)
  end

private

  # Constants -----------------------------------------------
  
  CRLF        = "\r\n"
  HTTP_PROTO  = "HTTP/1.0"
  SERVER_NAME = "HttpServer (Ruby #{RUBY_VERSION})"

  DEFAULT_HEADER = {
    "Server" => SERVER_NAME
  }

  ##
  # Mapping of status code and error message
  #
  StatusCodeMapping = {
    200 => "OK",
    400 => "Bad Request",
    403 => "Forbidden",
    405 => "Method Not Allowed",
    411 => "Length Required",
    500 => "Internal Server Error"
  }

  # Classes -------------------------------------------------
  
  class Request
    attr_reader :data, :header, :method, :path, :proto
    
    def initialize(data, method=nil, path=nil, proto=nil)
      @header, @data = Table.new, data
      @method, @path, @proto = method, path, proto
    end
    
    def content_length
      len = @header['Content-Length']
      return nil if len.nil?
      return len.to_i 
    end
    
  end
  
  class Response
    attr_reader   :header
    attr_accessor :body, :status, :status_message
    
    def initialize(status=200)
      @status = status
      @status_message = nil
      @header = Table.new
    end
  end


  ##
  # a case-insensitive Hash class for HTTP header
  #
  class Table
    include Enumerable

    def initialize(hash={})
      @hash = hash 
      update(hash)
    end

    def [](key)
      @hash[key.to_s.capitalize]
    end

    def []=(key, value)
      @hash[key.to_s.capitalize] = value
    end

    def update(hash)
      hash.each {|k,v| self[k] = v}
      self
    end

    def each
      @hash.each {|k,v| yield k.capitalize, v }
    end

    def writeTo(port)
      each { |k,v| port << "#{k}: #{v}" << CRLF }
    end
  end # class Table


  # Helper Methods ------------------------------------------

  def http_header(header=nil)
    new_header = Table.new(DEFAULT_HEADER)
    new_header.update(header) unless header.nil? 

    new_header["Connection"] = "close"
    new_header["Date"]       = http_date(Time.now)

    new_header
  end

  def http_date( aTime )
    aTime.gmtime.strftime( "%a, %d %b %Y %H:%M:%S GMT" )
  end

  def http_resp(status_code, status_message=nil, header=nil, body=nil)
    status_message ||= StatusCodeMapping[status_code]
    
    str = ""
    str << "#{HTTP_PROTO} #{status_code} #{status_message}" << CRLF
    http_header(header).writeTo(str)
    str << CRLF
    str << body unless body.nil?
    str
  end

  # Main Serve Loop -----------------------------------------
  
  def serve(io)  
    # perform IP authentification
    unless @handler.ip_auth_handler(io)
      io << http_resp(403, "Forbidden")
      return
    end

    # parse first line
    if io.gets =~ /^(\S+)\s+(\S+)\s+(\S+)/
      request = Request.new(io, $1, $2, $3)
    else
      io << http_resp(400, "Bad Request") 
      return
    end
     
    # parse HTTP headers
    while (line=io.gets) !~ /^(\n|\r)/
      if line =~ /^([\w-]+):\s*(.*)$/
	request.header[$1] = $2.strip
      end
    end

    io.binmode    
    response = Response.new

    # execute request handler
    @handler.request_handler(request, response)
   
    # write response back to the client
    io << http_resp(response.status, response.status_message,
                    response.header, response.body) 

  rescue Exception => e
    io << http_resp(500, "Internal Server Error")
  end

end # class HttpServer

PK     Z\_t  t    xmlrpc/datetime.rbnu [        =begin
= xmlrpc/datetime.rb
Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)

Released under the same term of license as Ruby.

= Classes
* ((<XMLRPC::DateTime>))

= XMLRPC::DateTime
== Description
This class is important to handle XMLRPC (('dateTime.iso8601')) values,
correcly, because normal UNIX-dates (class (({Date}))) only handle dates 
from year 1970 on, and class (({Time})) handles dates without the time
component. (({XMLRPC::DateTime})) is able to store a XMLRPC 
(('dateTime.iso8601')) value correctly.

== Class Methods
--- XMLRPC::DateTime.new( year, month, day, hour, min, sec )
    Creates a new (({XMLRPC::DateTime})) instance with the
    parameters ((|year|)), ((|month|)), ((|day|)) as date and 
    ((|hour|)), ((|min|)), ((|sec|)) as time.
    Raises (({ArgumentError})) if a parameter is out of range, or ((|year|)) is not
    of type (({Integer})).
    
== Instance Methods
--- XMLRPC::DateTime#year
--- XMLRPC::DateTime#month
--- XMLRPC::DateTime#day
--- XMLRPC::DateTime#hour
--- XMLRPC::DateTime#min
--- XMLRPC::DateTime#sec
    Return the value of the specified date/time component.

--- XMLRPC::DateTime#mon
    Alias for ((<XMLRPC::DateTime#month>)).

--- XMLRPC::DateTime#year=( value )
--- XMLRPC::DateTime#month=( value )
--- XMLRPC::DateTime#day=( value )
--- XMLRPC::DateTime#hour=( value )
--- XMLRPC::DateTime#min=( value )
--- XMLRPC::DateTime#sec=( value )
    Set ((|value|)) as the new date/time component.
    Raises (({ArgumentError})) if ((|value|)) is out of range, or in the case
    of (({XMLRPC::DateTime#year=})) if ((|value|)) is not of type (({Integer})).

--- XMLRPC::DateTime#mon=( value )
    Alias for ((<XMLRPC::DateTime#month=>)).

--- XMLRPC::DateTime#to_time
    Return a (({Time})) object of the date/time which (({self})) represents.
    If the (('year')) is below 1970, this method returns (({nil})), 
    because (({Time})) cannot handle years below 1970.
    The used timezone is GMT.

--- XMLRPC::DateTime#to_date
    Return a (({Date})) object of the date which (({self})) represents.
    The (({Date})) object do ((*not*)) contain the time component (only date).

--- XMLRPC::DateTime#to_a
    Returns all date/time components in an array.
    Returns (({[year, month, day, hour, min, sec]})).
=end

require "date"

module XMLRPC

class DateTime
  
  attr_reader :year, :month, :day, :hour, :min, :sec

  def year= (value)
    raise ArgumentError, "date/time out of range" unless value.is_a? Integer
    @year = value
  end

  def month= (value)
    raise ArgumentError, "date/time out of range" unless (1..12).include? value
    @month = value
  end

  def day= (value)
    raise ArgumentError, "date/time out of range" unless (1..31).include? value
    @day = value
  end

  def hour= (value)
    raise ArgumentError, "date/time out of range" unless (0..24).include? value
    @hour = value
  end

  def min= (value)
    raise ArgumentError, "date/time out of range" unless (0..59).include? value
    @min = value
  end

  def sec= (value)
    raise ArgumentError, "date/time out of range" unless (0..59).include? value
    @sec = value
  end

  alias mon  month
  alias mon= month= 
 

  def initialize(year, month, day, hour, min, sec)
    self.year, self.month, self.day = year, month, day
    self.hour, self.min, self.sec   = hour, min, sec
  end
 
  def to_time
    if @year >= 1970
      Time.gm(*to_a)
    else
      nil
    end
  end

  def to_date
    Date.new(*to_a[0,3])
  end

  def to_a
    [@year, @month, @day, @hour, @min, @sec]
  end

  def ==(o)
    Array(self) == Array(o)
  end

end


end # module XMLRPC


=begin
= History
    $Id: datetime.rb 11708 2007-02-12 23:01:19Z shyouhei $
=end
PK     Z\j?;  ;    xmlrpc/marshal.rbnu [        #
# Marshalling of XML-RPC methodCall and methodResponse
# 
# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)
#
# $Id: marshal.rb 11708 2007-02-12 23:01:19Z shyouhei $
#

require "xmlrpc/parser"
require "xmlrpc/create"
require "xmlrpc/config"
require "xmlrpc/utils"

module XMLRPC

  class Marshal
    include ParserWriterChooseMixin

    # class methods -------------------------------
   
    class << self

      def dump_call( methodName, *params )
        new.dump_call( methodName, *params )
      end

      def dump_response( param )
        new.dump_response( param )
      end

      def load_call( stringOrReadable )
        new.load_call( stringOrReadable )
      end

      def load_response( stringOrReadable )
        new.load_response( stringOrReadable )
      end

      alias dump dump_response
      alias load load_response

    end # class self

    # instance methods ----------------------------

    def initialize( parser = nil, writer = nil )
      set_parser( parser )
      set_writer( writer )
    end

    def dump_call( methodName, *params )
      create.methodCall( methodName, *params )
    end

    def dump_response( param ) 
      create.methodResponse( ! param.kind_of?( XMLRPC::FaultException ) , param )
    end

    ##
    # returns [ methodname, params ]
    #
    def load_call( stringOrReadable )
      parser.parseMethodCall( stringOrReadable )
    end

    ##
    # returns paramOrFault
    #
    def load_response( stringOrReadable )
      parser.parseMethodResponse( stringOrReadable )[1]
    end

  end # class Marshal

end

PK     Z\`%      xmlrpc/utils.rbnu [        #
# Defines ParserWriterChooseMixin, which makes it possible to choose a
# different XML writer and/or XML parser then the default one.
# The Mixin is used in client.rb (class Client) and server.rb (class 
# BasicServer)
# 
# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)
#
# $Id: utils.rb 13771 2007-10-24 23:04:42Z jeg2 $ 
#

module XMLRPC

  #
  # This module enables a user-class to be marshalled
  # by XML-RPC for Ruby into a Hash, with one additional
  # key/value pair "___class___" => ClassName
  # 
  module Marshallable
  end


  module ParserWriterChooseMixin

    def set_writer(writer)
      @create = Create.new(writer)
      self
    end

    def set_parser(parser)
      @parser = parser
      self
    end

    private

    def create
      # if set_writer was not already called then call it now
      if @create.nil? then
	set_writer(Config::DEFAULT_WRITER.new)
      end
      @create
    end

    def parser
      # if set_parser was not already called then call it now
      if @parser.nil? then
	set_parser(Config::DEFAULT_PARSER.new)
      end
      @parser
    end

  end # module ParserWriterChooseMixin


  module Service

  #
  # base class for Service Interface definitions, used
  # by BasicServer#add_handler
  #

  class BasicInterface
    attr_reader :prefix, :methods

    def initialize(prefix)
      @prefix = prefix
      @methods = []
    end

    def add_method(sig, help=nil, meth_name=nil)
      mname = nil
      sig = [sig] if sig.kind_of? String

      sig = sig.collect do |s| 
        name, si = parse_sig(s)
        raise "Wrong signatures!" if mname != nil and name != mname 
        mname = name
        si
      end

      @methods << [mname, meth_name || mname, sig, help]
    end

    private # ---------------------------------
  
    def parse_sig(sig)
      # sig is a String
      if sig =~ /^\s*(\w+)\s+([^(]+)(\(([^)]*)\))?\s*$/
        params = [$1]
        name   = $2.strip 
        $4.split(",").each {|i| params << i.strip} if $4 != nil
        return name, params
      else
        raise "Syntax error in signature"
      end
    end

  end # class BasicInterface

  #
  # class which wraps a Service Interface definition, used
  # by BasicServer#add_handler
  #
  class Interface < BasicInterface
    def initialize(prefix, &p)
      raise "No interface specified" if p.nil?
      super(prefix)
      instance_eval(&p)
    end

    def get_methods(obj, delim=".") 
      prefix = @prefix + delim
      @methods.collect { |name, meth, sig, help| 
        [prefix + name, obj.method(meth).to_proc, sig, help] 
      }
    end

    private # ---------------------------------

    def meth(*a)
      add_method(*a)
    end

  end # class Interface

  class PublicInstanceMethodsInterface < BasicInterface
    def initialize(prefix)
      super(prefix)
    end

    def get_methods(obj, delim=".")
      prefix = @prefix + delim
      obj.class.public_instance_methods(false).collect { |name|
        [prefix + name, obj.method(name).to_proc, nil, nil] 
      }
    end
  end


  end # module Service


  # 
  # short-form to create a Service::Interface
  #
  def self.interface(prefix, &p)
    Service::Interface.new(prefix, &p)  
  end

  # short-cut for creating a PublicInstanceMethodsInterface
  def self.iPIMethods(prefix)
    Service::PublicInstanceMethodsInterface.new(prefix) 
  end


  module ParseContentType
    def parse_content_type(str)
      a, *b = str.split(";")
      return a.strip.downcase, *b
    end
  end

end # module XMLRPC

PK     Z\K;%HW  HW    xmlrpc/server.rbnu [        =begin
= xmlrpc/server.rb
Copyright (C) 2001, 2002, 2003, 2005 by Michael Neumann (mneumann@ntecs.de)

Released under the same term of license as Ruby.

= Classes
* ((<XMLRPC::BasicServer>))
* ((<XMLRPC::CGIServer>))
* ((<XMLRPC::ModRubyServer>))
* ((<XMLRPC::Server>))
* ((<XMLRPC::WEBrickServlet>))

= XMLRPC::BasicServer
== Description
Is the base class for all XML-RPC server-types (CGI, standalone).
You can add handler and set a default handler. 
Do not use this server, as this is/should be an abstract class.

=== How the method to call is found
The arity (number of accepted arguments) of a handler (method or (({Proc})) object) is 
compared to the given arguments submitted by the client for a RPC ((-Remote Procedure Call-)). 
A handler is only called if it accepts the number of arguments, otherwise the search 
for another handler will go on. When at the end no handler was found, 
the ((<default_handler|XMLRPC::BasicServer#set_default_handler>)) will be called.
With this technique it is possible to do overloading by number of parameters, but
only for (({Proc})) handler, because you cannot define two methods of the same name in
the same class. 


== Class Methods
--- XMLRPC::BasicServer.new( class_delim="." )
    Creates a new (({XMLRPC::BasicServer})) instance, which should not be 
    done, because (({XMLRPC::BasicServer})) is an abstract class. This
    method should be called from a subclass indirectly by a (({super})) call
    in the method (({initialize})). The paramter ((|class_delim|)) is used
    in ((<add_handler|XMLRPC::BasicServer#add_handler>)) when an object is
    added as handler, to delimit the object-prefix and the method-name.

== Instance Methods
--- XMLRPC::BasicServer#add_handler( name, signature=nil, help=nil ) { aBlock }
    Adds ((|aBlock|)) to the list of handlers, with ((|name|)) as the name of the method.
    Parameters ((|signature|)) and ((|help|)) are used by the Introspection method if specified, 
    where ((|signature|)) is either an Array containing strings each representing a type of it's 
    signature (the first is the return value) or an Array of Arrays if the method has multiple 
    signatures. Value type-names are "int, boolean, double, string, dateTime.iso8601, base64, array, struct".

    Parameter ((|help|)) is a String with informations about how to call this method etc.

    A handler method or code-block can return the types listed at
    ((<XMLRPC::Client#call|URL:client.html#index:0>)). 
    When a method fails, it can tell it the client by throwing an 
    (({XMLRPC::FaultException})) like in this example:
        s.add_handler("michael.div") do |a,b|
          if b == 0
            raise XMLRPC::FaultException.new(1, "division by zero")
          else
            a / b 
          end
        end 
    The client gets in the case of (({b==0})) an object back of type
    (({XMLRPC::FaultException})) that has a ((|faultCode|)) and ((|faultString|))
    field.

--- XMLRPC::BasicServer#add_handler( prefix, obj )
    This is the second form of ((<add_handler|XMLRPC::BasicServer#add_handler>)).
    To add an object write:
        server.add_handler("michael", MyHandlerClass.new)
    All public methods of (({MyHandlerClass})) are accessible to
    the XML-RPC clients by (('michael."name of method"')). This is 
    where the ((|class_delim|)) in ((<new|XMLRPC::BasicServer.new>)) 
    has it's role, a XML-RPC method-name is defined by 
    ((|prefix|)) + ((|class_delim|)) + (('"name of method"')). 

--- XMLRPC::BasicServer#add_handler( interface, obj )
    This is the third form of ((<add_handler|XMLRPC::BasicServer#add_handler>)).

    Use (({XMLRPC::interface})) to generate an ServiceInterface object, which
    represents an interface (with signature and help text) for a handler class.

    Parameter ((|interface|)) must be of type (({XMLRPC::ServiceInterface})).
    Adds all methods of ((|obj|)) which are defined in ((|interface|)) to the
    server.

    This is the recommended way of adding services to a server!


--- XMLRPC::BasicServer#get_default_handler
    Returns the default-handler, which is called when no handler for
    a method-name is found.
    It is a (({Proc})) object or (({nil})).

--- XMLRPC::BasicServer#set_default_handler ( &handler )
    Sets ((|handler|)) as the default-handler, which is called when 
    no handler for a method-name is found. ((|handler|)) is a code-block.
    The default-handler is called with the (XML-RPC) method-name as first argument, and
    the other arguments are the parameters given by the client-call.
  
    If no block is specified the default of (({XMLRPC::BasicServer})) is used, which raises a
    XMLRPC::FaultException saying "method missing".


--- XMLRPC::BasicServer#set_writer( writer )
    Sets the XML writer to use for generating XML output.
    Should be an instance of a class from module (({XMLRPC::XMLWriter})).
    If this method is not called, then (({XMLRPC::Config::DEFAULT_WRITER})) is used. 

--- XMLRPC::BasicServer#set_parser( parser )
    Sets the XML parser to use for parsing XML documents.
    Should be an instance of a class from module (({XMLRPC::XMLParser})).
    If this method is not called, then (({XMLRPC::Config::DEFAULT_PARSER})) is used.

--- XMLRPC::BasicServer#add_introspection
    Adds the introspection handlers "system.listMethods", "system.methodSignature" and "system.methodHelp", 
    where only the first one works.

--- XMLRPC::BasicServer#add_multicall
    Adds the multi-call handler "system.multicall".

--- XMLRPC::BasicServer#get_service_hook
    Returns the service-hook, which is called on each service request (RPC) unless it's (({nil})).

--- XMLRPC::BasicServer#set_service_hook ( &handler )
    A service-hook is called for each service request (RPC).
    You can use a service-hook for example to wrap existing methods and catch exceptions of them or
    convert values to values recognized by XMLRPC. You can disable it by passing (({nil})) as parameter  
    ((|handler|)) .

    The service-hook is called with a (({Proc})) object and with the parameters for this (({Proc})).
    An example:

       server.set_service_hook {|obj, *args|
         begin
           ret = obj.call(*args)  # call the original service-method
           # could convert the return value 
         resuce
           # rescue exceptions
         end
       }

=end



require "xmlrpc/parser"
require "xmlrpc/create"
require "xmlrpc/config"
require "xmlrpc/utils"         # ParserWriterChooseMixin



module XMLRPC


class BasicServer

  include ParserWriterChooseMixin
  include ParseContentType

  ERR_METHOD_MISSING        = 1 
  ERR_UNCAUGHT_EXCEPTION    = 2
  ERR_MC_WRONG_PARAM        = 3
  ERR_MC_MISSING_PARAMS     = 4
  ERR_MC_MISSING_METHNAME   = 5
  ERR_MC_RECURSIVE_CALL     = 6
  ERR_MC_WRONG_PARAM_PARAMS = 7
  ERR_MC_EXPECTED_STRUCT    = 8


  def initialize(class_delim=".")
    @handler = []
    @default_handler = nil 
    @service_hook = nil

    @class_delim = class_delim
    @create = nil
    @parser = nil

    add_multicall     if Config::ENABLE_MULTICALL
    add_introspection if Config::ENABLE_INTROSPECTION
  end

  def add_handler(prefix, obj_or_signature=nil, help=nil, &block)
    if block_given?
      # proc-handler
      @handler << [prefix, block, obj_or_signature, help]   
    else
      if prefix.kind_of? String
        # class-handler
        raise ArgumentError, "Expected non-nil value" if obj_or_signature.nil?
        @handler << [prefix + @class_delim, obj_or_signature]
      elsif prefix.kind_of? XMLRPC::Service::BasicInterface
        # class-handler with interface
        # add all methods
        @handler += prefix.get_methods(obj_or_signature, @class_delim)
      else
        raise ArgumentError, "Wrong type for parameter 'prefix'"
      end
    end
    self
  end

  def get_service_hook
    @service_hook
  end

  def set_service_hook(&handler)
    @service_hook = handler
    self
  end
 
  def get_default_handler
    @default_handler
  end

  def set_default_handler (&handler)
    @default_handler = handler
    self
  end  

  def add_multicall
    add_handler("system.multicall", %w(array array), "Multicall Extension") do |arrStructs|
      unless arrStructs.is_a? Array 
        raise XMLRPC::FaultException.new(ERR_MC_WRONG_PARAM, "system.multicall expects an array")
      end

      arrStructs.collect {|call|
        if call.is_a? Hash
          methodName = call["methodName"]
          params     = call["params"]  

          if params.nil?
            multicall_fault(ERR_MC_MISSING_PARAMS, "Missing params")
          elsif methodName.nil?
            multicall_fault(ERR_MC_MISSING_METHNAME, "Missing methodName")
          else
            if methodName == "system.multicall"
              multicall_fault(ERR_MC_RECURSIVE_CALL, "Recursive system.multicall forbidden")
            else
              unless params.is_a? Array
                multicall_fault(ERR_MC_WRONG_PARAM_PARAMS, "Parameter params have to be an Array")
              else
                ok, val = call_method(methodName, *params)
                if ok
                  # correct return value
                  [val]
                else
                  # exception
                  multicall_fault(val.faultCode, val.faultString) 
                end
              end
            end
          end  
           
        else
          multicall_fault(ERR_MC_EXPECTED_STRUCT, "system.multicall expected struct")
        end
      } 
    end # end add_handler
    self
  end

  def add_introspection
    add_handler("system.listMethods",%w(array), "List methods available on this XML-RPC server") do
      methods = []
      @handler.each do |name, obj|
        if obj.kind_of? Proc
          methods << name
        else
          obj.class.public_instance_methods(false).each do |meth|
            methods << "#{name}#{meth}"
          end
        end
      end
      methods
    end

    add_handler("system.methodSignature", %w(array string), "Returns method signature") do |meth|
      sigs = []
      @handler.each do |name, obj, sig|
        if obj.kind_of? Proc and sig != nil and name == meth
          if sig[0].kind_of? Array
            # sig contains multiple signatures, e.g. [["array"], ["array", "string"]]
            sig.each {|s| sigs << s}
          else
            # sig is a single signature, e.g. ["array"]
            sigs << sig 
          end
        end
      end
      sigs.uniq! || sigs  # remove eventually duplicated signatures
    end

    add_handler("system.methodHelp", %w(string string), "Returns help on using this method") do |meth|
      help = nil 
      @handler.each do |name, obj, sig, hlp|
        if obj.kind_of? Proc and name == meth 
          help = hlp
          break      
        end
      end
      help || ""
    end

    self
  end


  
  def process(data)
    method, params = parser().parseMethodCall(data) 
    handle(method, *params)
  end
 
  private # --------------------------------------------------------------

  def multicall_fault(nr, str)
    {"faultCode" => nr, "faultString" => str}
  end
 
  #
  # method dispatch
  #
  def dispatch(methodname, *args)
    for name, obj in @handler
      if obj.kind_of? Proc
        next unless methodname == name
      else
        next unless methodname =~ /^#{name}(.+)$/
        next unless obj.respond_to? $1
        obj = obj.method($1)
      end

      if check_arity(obj, args.size)
        if @service_hook.nil?
          return obj.call(*args) 
        else
          return @service_hook.call(obj, *args)
        end
      end
    end 
 
    if @default_handler.nil?
      raise XMLRPC::FaultException.new(ERR_METHOD_MISSING, "Method #{methodname} missing or wrong number of parameters!")
    else
      @default_handler.call(methodname, *args) 
    end
  end


  #
  # returns true, if the arity of "obj" matches
  #
  def check_arity(obj, n_args)
    ary = obj.arity

    if ary >= 0
      n_args == ary
    else
      n_args >= (ary+1).abs 
    end
  end



  def call_method(methodname, *args)
    begin
      [true, dispatch(methodname, *args)]
    rescue XMLRPC::FaultException => e  
      [false, e]  
    rescue Exception => e
      [false, XMLRPC::FaultException.new(ERR_UNCAUGHT_EXCEPTION, "Uncaught exception #{e.message} in method #{methodname}")]
    end
  end

  #
  #
  #
  def handle(methodname, *args)
    create().methodResponse(*call_method(methodname, *args))
  end


end


=begin
= XMLRPC::CGIServer
== Synopsis
    require "xmlrpc/server"
 
    s = XMLRPC::CGIServer.new     

    s.add_handler("michael.add") do |a,b|
      a + b
    end

    s.add_handler("michael.div") do |a,b|
      if b == 0
        raise XMLRPC::FaultException.new(1, "division by zero")
      else
        a / b 
      end
    end 

    s.set_default_handler do |name, *args|
      raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
                                       " or wrong number of parameters!")
    end
  
    s.serve

== Description
Implements a CGI-based XML-RPC server.

== Superclass
((<XMLRPC::BasicServer>))

== Class Methods
--- XMLRPC::CGIServer.new( *a )
    Creates a new (({XMLRPC::CGIServer})) instance. All parameters given
    are by-passed to ((<XMLRPC::BasicServer.new>)). You can only create 
    ((*one*)) (({XMLRPC::CGIServer})) instance, because more than one makes
    no sense.

== Instance Methods
--- XMLRPC::CGIServer#serve
    Call this after you have added all you handlers to the server.
    This method processes a XML-RPC methodCall and sends the answer
    back to the client. 
    Make sure that you don't write to standard-output in a handler, or in
    any other part of your program, this would case a CGI-based server to fail!
=end

class CGIServer < BasicServer
  @@obj = nil

  def CGIServer.new(*a)
    @@obj = super(*a) if @@obj.nil?
    @@obj
  end

  def initialize(*a)
    super(*a)
  end
  
  def serve
    catch(:exit_serve) {
      length = ENV['CONTENT_LENGTH'].to_i

      http_error(405, "Method Not Allowed") unless ENV['REQUEST_METHOD'] == "POST" 
      http_error(400, "Bad Request")        unless parse_content_type(ENV['CONTENT_TYPE']).first == "text/xml"
      http_error(411, "Length Required")    unless length > 0 

      # TODO: do we need a call to binmode?
      $stdin.binmode if $stdin.respond_to? :binmode
      data = $stdin.read(length)

      http_error(400, "Bad Request")        if data.nil? or data.size != length

      http_write(process(data), "Content-type" => "text/xml; charset=utf-8")
    }
  end


  private

  def http_error(status, message)
    err = "#{status} #{message}"
    msg = <<-"MSGEND" 
      <html>
        <head>
          <title>#{err}</title>
        </head>
        <body>
          <h1>#{err}</h1>
          <p>Unexpected error occured while processing XML-RPC request!</p>
        </body>
      </html>
    MSGEND

    http_write(msg, "Status" => err, "Content-type" => "text/html")
    throw :exit_serve # exit from the #serve method
  end

  def http_write(body, header)
    h = {}
    header.each {|key, value| h[key.to_s.capitalize] = value}
    h['Status']         ||= "200 OK"
    h['Content-length'] ||= body.size.to_s 

    str = ""
    h.each {|key, value| str << "#{key}: #{value}\r\n"}
    str << "\r\n#{body}"

    print str
  end

end

=begin
= XMLRPC::ModRubyServer
== Description
Implements a XML-RPC server, which works with Apache mod_ruby.

Use it in the same way as CGIServer!

== Superclass
((<XMLRPC::BasicServer>))
=end 

class ModRubyServer < BasicServer

  def initialize(*a)
    @ap = Apache::request
    super(*a)
  end

  def serve
    catch(:exit_serve) {
      header = {}
      @ap.headers_in.each {|key, value| header[key.capitalize] = value}

      length = header['Content-length'].to_i

      http_error(405, "Method Not Allowed") unless @ap.request_method  == "POST" 
      http_error(400, "Bad Request")        unless parse_content_type(header['Content-type']).first == "text/xml"
      http_error(411, "Length Required")    unless length > 0 

      # TODO: do we need a call to binmode?
      @ap.binmode
      data = @ap.read(length)

      http_error(400, "Bad Request")        if data.nil? or data.size != length

      http_write(process(data), 200, "Content-type" => "text/xml; charset=utf-8")
    }
  end


  private

  def http_error(status, message)
    err = "#{status} #{message}"
    msg = <<-"MSGEND" 
      <html>
        <head>
          <title>#{err}</title>
        </head>
        <body>
          <h1>#{err}</h1>
          <p>Unexpected error occured while processing XML-RPC request!</p>
        </body>
      </html>
    MSGEND

    http_write(msg, status, "Status" => err, "Content-type" => "text/html")
    throw :exit_serve # exit from the #serve method
  end

  def http_write(body, status, header)
    h = {}
    header.each {|key, value| h[key.to_s.capitalize] = value}
    h['Status']         ||= "200 OK"
    h['Content-length'] ||= body.size.to_s 

    h.each {|key, value| @ap.headers_out[key] = value }
    @ap.content_type = h["Content-type"] 
    @ap.status = status.to_i 
    @ap.send_http_header 

    @ap.print body
  end

end

=begin
= XMLRPC::Server
== Synopsis
    require "xmlrpc/server"
 
    s = XMLRPC::Server.new(8080) 

    s.add_handler("michael.add") do |a,b|
      a + b
    end

    s.add_handler("michael.div") do |a,b|
      if b == 0
        raise XMLRPC::FaultException.new(1, "division by zero")
      else
        a / b 
      end
    end 

    s.set_default_handler do |name, *args|
      raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
                                       " or wrong number of parameters!")
    end
 
    s.serve

== Description
Implements a standalone XML-RPC server. The method (({serve}))) is left if a SIGHUP is sent to the
program.

== Superclass
((<XMLRPC::WEBrickServlet>))

== Class Methods
--- XMLRPC::Server.new( port=8080, host="127.0.0.1", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a )
    Creates a new (({XMLRPC::Server})) instance, which is a XML-RPC server listening on
    port ((|port|)) and accepts requests for the host ((|host|)), which is by default only the localhost. 
    The server is not started, to start it you have to call ((<serve|XMLRPC::Server#serve>)).

    Parameters ((|audit|)) and ((|debug|)) are obsolete!

    All additionally given parameters in ((|*a|)) are by-passed to ((<XMLRPC::BasicServer.new>)). 
    
== Instance Methods
--- XMLRPC::Server#serve
    Call this after you have added all you handlers to the server.
    This method starts the server to listen for XML-RPC requests and answer them.

--- XMLRPC::Server#shutdown
    Stops and shuts the server down.
    
=end

class WEBrickServlet < BasicServer; end # forward declaration

class Server < WEBrickServlet

  def initialize(port=8080, host="127.0.0.1", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a)
    super(*a)
    require 'webrick'
    @server = WEBrick::HTTPServer.new(:Port => port, :BindAddress => host, :MaxClients => maxConnections, 
                                      :Logger => WEBrick::Log.new(stdlog))
    @server.mount("/", self)
  end
  
  def serve
    if RUBY_PLATFORM =~ /mingw|mswin32/
      signals = [1]
    else
      signals = %w[INT TERM HUP]
    end
    signals.each { |signal| trap(signal) { @server.shutdown } }

    @server.start
  end
  
  def shutdown
    @server.shutdown
  end
 
end

=begin
= XMLRPC::WEBrickServlet
== Synopsis

    require "webrick"
    require "xmlrpc/server"

    s = XMLRPC::WEBrickServlet.new
    s.add_handler("michael.add") do |a,b|
      a + b
    end

    s.add_handler("michael.div") do |a,b|
      if b == 0
        raise XMLRPC::FaultException.new(1, "division by zero")
      else
        a / b 
      end
    end 

    s.set_default_handler do |name, *args|
      raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
                                       " or wrong number of parameters!")
    end

    httpserver = WEBrick::HTTPServer.new(:Port => 8080)    
    httpserver.mount("/RPC2", s)
    trap("HUP") { httpserver.shutdown }   # use 1 instead of "HUP" on Windows
    httpserver.start

== Instance Methods

--- XMLRPC::WEBrickServlet#set_valid_ip( *ip_addr )
    Specifies the valid IP addresses that are allowed to connect to the server.
    Each IP is either a (({String})) or a (({Regexp})).

--- XMLRPC::WEBrickServlet#get_valid_ip
    Return the via method ((<set_valid_ip|XMLRPC::Server#set_valid_ip>)) specified
    valid IP addresses.
 
== Description
Implements a servlet for use with WEBrick, a pure Ruby (HTTP-) server framework.

== Superclass
((<XMLRPC::BasicServer>))

=end

class WEBrickServlet < BasicServer
  def initialize(*a)
    super
    require "webrick/httpstatus"
    @valid_ip = nil
  end

  # deprecated from WEBrick/1.2.2. 
  # but does not break anything.
  def require_path_info?
    false 
  end

  def get_instance(config, *options)
    # TODO: set config & options
    self
  end

  def set_valid_ip(*ip_addr)
    if ip_addr.size == 1 and ip_addr[0].nil?
      @valid_ip = nil
    else
      @valid_ip = ip_addr
    end
  end

  def get_valid_ip
    @valid_ip
  end

  def service(request, response)

    if @valid_ip 
      raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip }
    end

    if request.request_method != "POST"
      raise WEBrick::HTTPStatus::MethodNotAllowed,
            "unsupported method `#{request.request_method}'."
    end

    if parse_content_type(request['Content-type']).first != "text/xml" 
      raise WEBrick::HTTPStatus::BadRequest
    end 

    length = (request['Content-length'] || 0).to_i

    raise WEBrick::HTTPStatus::LengthRequired unless length > 0

    data = request.body

    if data.nil? or data.size != length
      raise WEBrick::HTTPStatus::BadRequest
    end

    resp = process(data)
    if resp.nil? or resp.size <= 0  
      raise WEBrick::HTTPStatus::InternalServerError
    end

    response.status = 200
    response['Content-Length'] = resp.size
    response['Content-Type']   = "text/xml; charset=utf-8"
    response.body = resp 
  end
end


end # module XMLRPC


=begin
= History
    $Id: server.rb 22461 2009-02-20 09:06:53Z shyouhei $    
=end

PK     Z\$      xmlrpc/config.rbnu [        #
# $Id: config.rb 11708 2007-02-12 23:01:19Z shyouhei $
# Configuration file for XML-RPC for Ruby
#

module XMLRPC

  module Config

    DEFAULT_WRITER = XMLWriter::Simple            # or XMLWriter::XMLParser
    
    # available parser:
    #   * XMLParser::NQXMLTreeParser
    #   * XMLParser::NQXMLStreamParser
    #   * XMLParser::XMLTreeParser
    #   * XMLParser::XMLStreamParser (fastest)
    #   * XMLParser::REXMLStreamParser
    #   * XMLParser::XMLScanStreamParser
    DEFAULT_PARSER = XMLParser::REXMLStreamParser

    # enable <nil/> tag
    ENABLE_NIL_CREATE    = false
    ENABLE_NIL_PARSER    = false
    
    # allows integers greater than 32-bit if true
    ENABLE_BIGINT        = false

    # enable marshalling ruby objects which include XMLRPC::Marshallable
    ENABLE_MARSHALLING   = true 

    # enable multiCall extension by default
    ENABLE_MULTICALL     = false
    
    # enable Introspection extension by default
    ENABLE_INTROSPECTION = false

  end

end

PK     Z\      xmlrpc/base64.rbnu [        =begin
= xmlrpc/base64.rb
Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)

Released under the same term of license as Ruby.

= Classes
* ((<XMLRPC::Base64>))

= XMLRPC::Base64
== Description
This class is necessary for (('xmlrpc4r')) to determine that a string should 
be transmitted base64-encoded and not as a raw-string. 
You can use (({XMLRPC::Base64})) on the client and server-side as a 
parameter and/or return-value.

== Class Methods
--- XMLRPC::Base64.new( str, state = :dec )
    Creates a new (({XMLRPC::Base64})) instance with string ((|str|)) as the
    internal string. When ((|state|)) is (({:dec})) it assumes that the 
    string ((|str|)) is not in base64 format (perhaps already decoded), 
    otherwise if ((|state|)) is (({:enc})) it decodes ((|str|)) 
    and stores it as the internal string.
    
--- XMLRPC::Base64.decode( str )
    Decodes string ((|str|)) with base64 and returns that value.

--- XMLRPC::Base64.encode( str )
    Encodes string ((|str|)) with base64 and returns that value.

== Instance Methods
--- XMLRPC::Base64#decoded
    Returns the internal string decoded.

--- XMLRPC::Base64#encoded
    Returns the internal string encoded with base64.

=end

module XMLRPC

class Base64
  
  def initialize(str, state = :dec)
    case state
    when :enc
      @str = Base64.decode(str)
    when :dec
      @str = str
    else
      raise ArgumentError, "wrong argument; either :enc or :dec"
    end
  end
  
  def decoded
    @str  
  end
  
  def encoded
    Base64.encode(@str)
  end


  def Base64.decode(str)
    str.gsub(/\s+/, "").unpack("m")[0]
  end

  def Base64.encode(str)
    [str].pack("m")
  end

end


end # module XMLRPC


=begin
= History
    $Id: base64.rb 11708 2007-02-12 23:01:19Z shyouhei $
=end
PK     Z\XWH  H    xmlrpc/parser.rbnu [        #
# Parser for XML-RPC call and response
# 
# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)
#
# $Id: parser.rb 13771 2007-10-24 23:04:42Z jeg2 $
#


require "date"
require "xmlrpc/base64"
require "xmlrpc/datetime"


# add some methods to NQXML::Node
module NQXML
  class Node

    def removeChild(node)
      @children.delete(node)
    end
    def childNodes
      @children
    end
    def hasChildNodes
      not @children.empty?
    end
    def [] (index)
      @children[index]
    end

    def nodeType
      if @entity.instance_of? NQXML::Text then :TEXT
      elsif @entity.instance_of? NQXML::Comment then :COMMENT
      #elsif @entity.instance_of? NQXML::Element then :ELEMENT
      elsif @entity.instance_of? NQXML::Tag then :ELEMENT
      else :ELSE
      end
    end

    def nodeValue
      #TODO: error when wrong Entity-type
      @entity.text
    end
    def nodeName
      #TODO: error when wrong Entity-type
      @entity.name
    end
  end # class Node
end # module NQXML

module XMLRPC

  class FaultException < StandardError
    attr_reader :faultCode, :faultString

    alias message faultString

    def initialize(faultCode, faultString)
      @faultCode   = faultCode
      @faultString = faultString
    end
    
    # returns a hash
    def to_h
      {"faultCode" => @faultCode, "faultString" => @faultString}
    end
  end

  module Convert
    def self.int(str)
      str.to_i
    end

    def self.boolean(str)
      case str
      when "0" then false
      when "1" then true
      else
        raise "RPC-value of type boolean is wrong" 
      end
    end

    def self.double(str)
      str.to_f
    end

    def self.dateTime(str)
      case str
      when /^(-?\d\d\d\d)-?(\d\d)-?(\d\d)T(\d\d):(\d\d):(\d\d)(?:Z|([+-])(\d\d):?(\d\d))?$/
        a = [$1, $2, $3, $4, $5, $6].collect{|i| i.to_i}
        if $7
          ofs = $8.to_i*3600 + $9.to_i*60
          ofs = -ofs if $7=='+'
          utc = Time.utc(*a) + ofs
          a = [ utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec ]
        end
        XMLRPC::DateTime.new(*a)
      when /^(-?\d\d)-?(\d\d)-?(\d\d)T(\d\d):(\d\d):(\d\d)(Z|([+-]\d\d):(\d\d))?$/
        a = [$1, $2, $3, $4, $5, $6].collect{|i| i.to_i}
        if a[0] < 70
          a[0] += 2000
        else
          a[0] += 1900
        end
        if $7
          ofs = $8.to_i*3600 + $9.to_i*60
          ofs = -ofs if $7=='+'
          utc = Time.utc(*a) + ofs
          a = [ utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec ]
        end
        XMLRPC::DateTime.new(*a)
      else
        raise "wrong dateTime.iso8601 format " + str
      end
    end

    def self.base64(str)
      XMLRPC::Base64.decode(str)
    end

    def self.struct(hash)
      # convert to marhalled object
      klass = hash["___class___"]
      if klass.nil? or Config::ENABLE_MARSHALLING == false 
        hash
      else
        begin
          mod = Module
          klass.split("::").each {|const| mod = mod.const_get(const.strip)}

          obj = mod.allocate
          
          hash.delete "___class___"
          hash.each {|key, value| 
            obj.instance_variable_set("@#{ key }", value) if key =~ /^([\w_][\w_0-9]*)$/
          }
          obj
        rescue
          hash
        end
      end
    end

    def self.fault(hash)
      if hash.kind_of? Hash and hash.size == 2 and 
        hash.has_key? "faultCode" and hash.has_key? "faultString" and 
        hash["faultCode"].kind_of? Integer and hash["faultString"].kind_of? String

        XMLRPC::FaultException.new(hash["faultCode"], hash["faultString"]) 
      else
        raise "wrong fault-structure: #{hash.inspect}"
      end
    end

  end # module Convert

  module XMLParser

    class AbstractTreeParser

      def parseMethodResponse(str)
	methodResponse_document(createCleanedTree(str))
      end

      def parseMethodCall(str)
	methodCall_document(createCleanedTree(str))
      end

      private

      #
      # remove all whitespaces but in the tags i4, int, boolean....
      # and all comments
      #
      def removeWhitespacesAndComments(node)
	remove = []
	childs = node.childNodes.to_a
	childs.each do |nd|
	  case _nodeType(nd)
	  when :TEXT
            # TODO: add nil?
            unless %w(i4 int boolean string double dateTime.iso8601 base64).include? node.nodeName

               if node.nodeName == "value" 
                 if not node.childNodes.to_a.detect {|n| _nodeType(n) == :ELEMENT}.nil?
                   remove << nd if nd.nodeValue.strip == "" 
                 end
               else
                 remove << nd if nd.nodeValue.strip == ""
               end
	    end
	  when :COMMENT
	    remove << nd
	  else
	    removeWhitespacesAndComments(nd)
	  end 
	end

	remove.each { |i| node.removeChild(i) }
      end


      def nodeMustBe(node, name)
	cmp = case name
	when Array 
	  name.include?(node.nodeName)
	when String
	  name == node.nodeName
	else
	  raise "error"
	end  

	if not cmp then
	  raise "wrong xml-rpc (name)"
	end

	node
      end

      #
      # returns, when successfully the only child-node
      #
      def hasOnlyOneChild(node, name=nil)
	if node.childNodes.to_a.size != 1
	  raise "wrong xml-rpc (size)"
	end
	if name != nil then
	  nodeMustBe(node.firstChild, name)
	end
      end


      def assert(b)
	if not b then
	  raise "assert-fail" 
	end
      end

      # the node `node` has empty string or string
      def text_zero_one(node)
	nodes = node.childNodes.to_a.size

	if nodes == 1
	  text(node.firstChild)
	elsif nodes == 0
	  ""
	else
	  raise "wrong xml-rpc (size)"
	end
      end
     

      def integer(node)
	#TODO: check string for float because to_i returnsa
	#      0 when wrong string
	 nodeMustBe(node, %w(i4 int))    
	hasOnlyOneChild(node)
	
	Convert.int(text(node.firstChild))
      end

      def boolean(node)
	nodeMustBe(node, "boolean")    
	hasOnlyOneChild(node)
	
        Convert.boolean(text(node.firstChild))
      end

      def v_nil(node)
        nodeMustBe(node, "nil")
	assert( node.childNodes.to_a.size == 0 )
        nil
      end

      def string(node)
	nodeMustBe(node, "string")    
	text_zero_one(node)
      end

      def double(node)
	#TODO: check string for float because to_f returnsa
	#      0.0 when wrong string
	nodeMustBe(node, "double")    
	hasOnlyOneChild(node)
	
	Convert.double(text(node.firstChild))
      end

      def dateTime(node)
	nodeMustBe(node, "dateTime.iso8601")
	hasOnlyOneChild(node)
	
        Convert.dateTime( text(node.firstChild) )
      end

      def base64(node)
	nodeMustBe(node, "base64")
	#hasOnlyOneChild(node)
	 
        Convert.base64(text_zero_one(node))
      end

      def member(node)
	nodeMustBe(node, "member")
	assert( node.childNodes.to_a.size == 2 ) 

	[ name(node[0]), value(node[1]) ]
      end

      def name(node)
	nodeMustBe(node, "name")
	#hasOnlyOneChild(node)
	text_zero_one(node) 
      end

      def array(node)
	nodeMustBe(node, "array")
	hasOnlyOneChild(node, "data") 
	data(node.firstChild)  
      end

      def data(node)
	nodeMustBe(node, "data")

	node.childNodes.to_a.collect do |val|
	  value(val)
	end 
      end

      def param(node)
	nodeMustBe(node, "param")
	hasOnlyOneChild(node, "value")
	value(node.firstChild) 
      end
 
      def methodResponse(node)
	nodeMustBe(node, "methodResponse")
	hasOnlyOneChild(node, %w(params fault))
	child = node.firstChild

	case child.nodeName
	when "params"
	  [ true, params(child,false) ] 
	when "fault"
	  [ false, fault(child) ]
	else
	  raise "unexpected error"
	end

      end

      def methodName(node)
	nodeMustBe(node, "methodName")
	hasOnlyOneChild(node)
	text(node.firstChild) 
      end

      def params(node, call=true)
	nodeMustBe(node, "params")

	if call 
	  node.childNodes.to_a.collect do |n|
	    param(n)
	  end
	else # response (only one param)
	  hasOnlyOneChild(node)
	  param(node.firstChild)
	end
      end

      def fault(node)
	nodeMustBe(node, "fault")
	hasOnlyOneChild(node, "value")
	f = value(node.firstChild) 
        Convert.fault(f)
      end



      # _nodeType is defined in the subclass
      def text(node)
	assert( _nodeType(node) == :TEXT )
	assert( node.hasChildNodes == false )
	assert( node.nodeValue != nil )

	node.nodeValue.to_s
      end

      def struct(node)
	nodeMustBe(node, "struct")    

	hash = {}
	node.childNodes.to_a.each do |me|
	  n, v = member(me)  
	  hash[n] = v
	end 

        Convert.struct(hash)
     end


      def value(node)
	nodeMustBe(node, "value")
	nodes = node.childNodes.to_a.size
        if nodes == 0 
          return ""
        elsif nodes > 1 
	  raise "wrong xml-rpc (size)"
        end

	child = node.firstChild

	case _nodeType(child)
	when :TEXT
          text_zero_one(node)
	when :ELEMENT
	  case child.nodeName
	  when "i4", "int"        then integer(child)
	  when "boolean"          then boolean(child)
	  when "string"           then string(child)
	  when "double"           then double(child)
	  when "dateTime.iso8601" then dateTime(child)
	  when "base64"           then base64(child)
	  when "struct"           then struct(child)
	  when "array"            then array(child) 
          when "nil"              
            if Config::ENABLE_NIL_PARSER
              v_nil(child)
            else
              raise "wrong/unknown XML-RPC type 'nil'"
            end
	  else 
	    raise "wrong/unknown XML-RPC type"
	  end
	else
	  raise "wrong type of node"
	end

      end

      def methodCall(node)
	nodeMustBe(node, "methodCall")
	assert( (1..2).include?( node.childNodes.to_a.size ) ) 
	name = methodName(node[0])

	if node.childNodes.to_a.size == 2 then
	  pa = params(node[1])
	else # no parameters given
	  pa = []
	end
	[name, pa]
      end

    end # module TreeParserMixin

    class AbstractStreamParser
      def parseMethodResponse(str)
        parser = @parser_class.new
        parser.parse(str)
        raise "No valid method response!" if parser.method_name != nil
        if parser.fault != nil
          # is a fault structure
          [false, parser.fault] 
        else
          # is a normal return value
          raise "Missing return value!" if parser.params.size == 0
          raise "Too many return values. Only one allowed!" if parser.params.size > 1
          [true, parser.params[0]]
        end
      end

      def parseMethodCall(str)
        parser = @parser_class.new
        parser.parse(str)
        raise "No valid method call - missing method name!" if parser.method_name.nil?
        [parser.method_name, parser.params]
      end
    end

    module StreamParserMixin
      attr_reader :params
      attr_reader :method_name
      attr_reader :fault

      def initialize(*a)
        super(*a)
        @params = []
        @values = []
        @val_stack = []

        @names = []
        @name = []

        @structs = []
        @struct = {}

        @method_name = nil
        @fault = nil

        @data = nil
      end

      def startElement(name, attrs=[])
        @data = nil
        case name
        when "value"
          @value = nil
        when "nil"
          raise "wrong/unknown XML-RPC type 'nil'" unless Config::ENABLE_NIL_PARSER
          @value = :nil 
        when "array"
          @val_stack << @values
          @values = []
        when "struct"
          @names << @name
          @name = []

          @structs << @struct
          @struct = {} 
        end
      end

      def endElement(name)
        @data ||= ""
        case name
        when "string"
          @value = @data
        when "i4", "int"
          @value = Convert.int(@data)
        when "boolean"
          @value = Convert.boolean(@data)
        when "double"
          @value = Convert.double(@data)
        when "dateTime.iso8601"
          @value = Convert.dateTime(@data)
        when "base64"
          @value = Convert.base64(@data)
        when "value"
          @value = @data if @value.nil?
          @values << (@value == :nil ? nil : @value) 
        when "array"
          @value = @values
          @values = @val_stack.pop
        when "struct"
          @value = Convert.struct(@struct)

          @name = @names.pop
          @struct = @structs.pop
        when "name"
          @name[0] = @data 
        when "member"
          @struct[@name[0]] = @values.pop 

        when "param"
          @params << @values[0]
          @values = []

        when "fault"
          @fault = Convert.fault(@values[0])

        when "methodName"
          @method_name = @data 
        end

        @data = nil
      end

      def character(data)
        if @data
          @data << data
        else
          @data = data
        end
      end

    end # module StreamParserMixin

    # ---------------------------------------------------------------------------
    class XMLStreamParser < AbstractStreamParser
      def initialize
        require "xmlparser"
        @parser_class = Class.new(::XMLParser) {
          include StreamParserMixin
        }
      end
    end # class XMLStreamParser
    # ---------------------------------------------------------------------------
    class NQXMLStreamParser < AbstractStreamParser
      def initialize
        require "nqxml/streamingparser"
        @parser_class = XMLRPCParser
      end

      class XMLRPCParser 
        include StreamParserMixin

        def parse(str)
          parser = NQXML::StreamingParser.new(str)
          parser.each do |ele|
            case ele
            when NQXML::Text
              @data = ele.text
              #character(ele.text)
            when NQXML::Tag
              if ele.isTagEnd
                endElement(ele.name)
              else
                startElement(ele.name, ele.attrs)
              end
            end
          end # do
        end # method parse
      end # class XMLRPCParser

    end # class NQXMLStreamParser
    # ---------------------------------------------------------------------------
    class XMLTreeParser < AbstractTreeParser

      def initialize
        require "xmltreebuilder"

        # The new XMLParser library (0.6.2+) uses a slightly different DOM implementation. 
        # The following code removes the differences between both versions.
        if defined? XML::DOM::Builder 
          return if defined? XML::DOM::Node::DOCUMENT # code below has been already executed
          klass = XML::DOM::Node
          klass.const_set("DOCUMENT", klass::DOCUMENT_NODE)
          klass.const_set("TEXT", klass::TEXT_NODE)
          klass.const_set("COMMENT", klass::COMMENT_NODE)
          klass.const_set("ELEMENT", klass::ELEMENT_NODE)
        end
      end

      private

      def _nodeType(node)
	tp = node.nodeType
	if tp == XML::SimpleTree::Node::TEXT then :TEXT
	elsif tp == XML::SimpleTree::Node::COMMENT then :COMMENT 
	elsif tp == XML::SimpleTree::Node::ELEMENT then :ELEMENT 
	else :ELSE
	end
      end


      def methodResponse_document(node)
	assert( node.nodeType == XML::SimpleTree::Node::DOCUMENT )
	hasOnlyOneChild(node, "methodResponse")
	
	methodResponse(node.firstChild)
      end

      def methodCall_document(node)
	assert( node.nodeType == XML::SimpleTree::Node::DOCUMENT )
	hasOnlyOneChild(node, "methodCall")
	
	methodCall(node.firstChild)
      end

      def createCleanedTree(str)
	doc = XML::SimpleTreeBuilder.new.parse(str)
	doc.documentElement.normalize
	removeWhitespacesAndComments(doc)
	doc
      end

    end # class XMLParser
    # ---------------------------------------------------------------------------
    class NQXMLTreeParser < AbstractTreeParser

      def initialize
        require "nqxml/treeparser"
      end

      private

      def _nodeType(node)
	node.nodeType
      end

      def methodResponse_document(node)
	methodResponse(node)
      end

      def methodCall_document(node)
	methodCall(node)
      end

      def createCleanedTree(str)
        doc = ::NQXML::TreeParser.new(str).document.rootNode 
	removeWhitespacesAndComments(doc)
	doc
      end

    end # class NQXMLTreeParser
    # ---------------------------------------------------------------------------
    class REXMLStreamParser < AbstractStreamParser
      def initialize
        require "rexml/document"
        @parser_class = StreamListener
      end

      class StreamListener 
        include StreamParserMixin

        alias :tag_start :startElement
        alias :tag_end :endElement
        alias :text :character
        alias :cdata :character

        def method_missing(*a)
          # ignore
        end

        def parse(str)
          parser = REXML::Document.parse_stream(str, self)
       end
      end 

    end
    # ---------------------------------------------------------------------------
    class XMLScanStreamParser < AbstractStreamParser
      def initialize
        require "xmlscan/parser"
        @parser_class = XMLScanParser
      end

      class XMLScanParser
        include StreamParserMixin

        Entities = {
          "lt"   => "<",
          "gt"   => ">",
          "amp"  => "&",
          "quot" => '"',
          "apos" => "'"
        }

        def parse(str)
          parser  = XMLScan::XMLParser.new(self)
          parser.parse(str)
        end

        alias :on_stag :startElement
 	alias :on_etag :endElement

        def on_stag_end(name); end

        def on_stag_end_empty(name)
          startElement(name)
          endElement(name)
        end
       
        def on_chardata(str)
          character(str)
        end

        def on_cdata(str)
          character(str)
        end

        def on_entityref(ent)
          str = Entities[ent]
          if str
            character(str)
          else
            raise "unknown entity"
          end
        end

        def on_charref(code)
          character(code.chr)
        end

        def on_charref_hex(code)
          character(code.chr)
        end

        def method_missing(*a)
        end

        # TODO: call/implement?
        # valid_name?
        # valid_chardata?
        # valid_char?
        # parse_error  

      end
    end
    # ---------------------------------------------------------------------------
    XMLParser   = XMLTreeParser
    NQXMLParser = NQXMLTreeParser

    Classes = [XMLStreamParser, XMLTreeParser, 
               NQXMLStreamParser, NQXMLTreeParser, 
               REXMLStreamParser, XMLScanStreamParser]

    # yields an instance of each installed parser
    def self.each_installed_parser
      XMLRPC::XMLParser::Classes.each do |klass|
        begin
          yield klass.new
        rescue LoadError
        end
      end
    end

  end # module XMLParser


end # module XMLRPC

PK     Z\!{  {  	  base64.rbnu [        #
# = base64.rb: methods for base64-encoding and -decoding stings
#
# Author:: Yukihiro Matsumoto 
# Documentation:: Dave Thomas and Gavin Sinclair
#
# Until Ruby 1.8.1, these methods were defined at the top-level.  Now
# they are in the Base64 module but included in the top-level, where
# their usage is deprecated.
#
# See Base64 for documentation.
#

require "kconv"


# The Base64 module provides for the encoding (#encode64) and decoding
# (#decode64) of binary data using a Base64 representation.
# 
# The following particular features are also provided:
# - encode into lines of a given length (#b64encode)
# - decode the special format specified in RFC2047 for the
#   representation of email headers (decode_b)
#
# == Example
#
# A simple encoding and decoding. 
# 
#     require "base64"
#
#     enc   = Base64.encode64('Send reinforcements')
#                         # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n" 
#     plain = Base64.decode64(enc)
#                         # -> "Send reinforcements"
#
# The purpose of using base64 to encode data is that it translates any
# binary data into purely printable characters.  It is specified in
# RFC 2045 (http://www.faqs.org/rfcs/rfc2045.html).

module Base64
  module_function

  # Returns the Base64-decoded version of +str+.
  #
  #   require 'base64'
  #   str = 'VGhpcyBpcyBsaW5lIG9uZQpUaGlzIG' +
  #         'lzIGxpbmUgdHdvClRoaXMgaXMgbGlu' +
  #         'ZSB0aHJlZQpBbmQgc28gb24uLi4K'
  #   puts Base64.decode64(str)
  #
  # <i>Generates:</i>
  #
  #    This is line one
  #    This is line two
  #    This is line three
  #    And so on...

  def decode64(str)
    str.unpack("m")[0]
  end


  # Decodes text formatted using a subset of RFC2047 (the one used for
  # mime-encoding mail headers).
  #
  # Only supports an encoding type of 'b' (base 64), and only supports
  # the character sets ISO-2022-JP and SHIFT_JIS (so the only two
  # encoded word sequences recognized are <tt>=?ISO-2022-JP?B?...=</tt> and
  # <tt>=?SHIFT_JIS?B?...=</tt>).  Recognition of these sequences is case
  # insensitive.

  def decode_b(str)
    str.gsub!(/=\?ISO-2022-JP\?B\?([!->@-~]+)\?=/i) {
      decode64($1)
    }
    str = Kconv::toeuc(str)
    str.gsub!(/=\?SHIFT_JIS\?B\?([!->@-~]+)\?=/i) {
      decode64($1)
    }
    str = Kconv::toeuc(str)
    str.gsub!(/\n/, ' ') 
    str.gsub!(/\0/, '')
    str
  end

  # Returns the Base64-encoded version of +str+.
  #
  #    require 'base64'
  #    Base64.b64encode("Now is the time for all good coders\nto learn Ruby")
  #
  # <i>Generates:</i>
  #
  #    Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g
  #    UnVieQ==

  def encode64(bin)
    [bin].pack("m")
  end

  # _Prints_ the Base64 encoded version of +bin+ (a +String+) in lines of
  # +len+ (default 60) characters.
  #
  #    require 'base64'
  #    data = "Now is the time for all good coders\nto learn Ruby" 
  #    Base64.b64encode(data)
  #
  # <i>Generates:</i>
  #
  #    Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g
  #    UnVieQ==

  def b64encode(bin, len = 60)
    encode64(bin).scan(/.{1,#{len}}/) do
      print $&, "\n"
    end
  end 


  module Deprecated # :nodoc:
    include Base64

    for m in Base64.private_instance_methods(false)
      module_eval %{
        def #{m}(*args)
          warn("\#{caller(1)[0]}: #{m} is deprecated; use Base64.#{m} instead")
          super
        end
      }
    end
  end
end

include Base64::Deprecated
PK     Z\3d  d  
  English.rbnu [        #  Include the English library file in a Ruby script, and you can
#  reference the global variables such as \VAR{\$\_} using less
#  cryptic names, listed in the following table.% \vref{tab:english}.
#
#  Without 'English':
#
#      $\ = ' -- '
#      "waterbuffalo" =~ /buff/
#      print $", $', $$, "\n"
#
#  With English:
#
#      require "English"
#      
#      $OUTPUT_FIELD_SEPARATOR = ' -- '
#      "waterbuffalo" =~ /buff/
#      print $LOADED_FEATURES, $POSTMATCH, $PID, "\n"


# The exception object passed to +raise+.
alias $ERROR_INFO              $!

# The stack backtrace generated by the last
# exception. <tt>See Kernel.caller</tt> for details. Thread local.
alias $ERROR_POSITION          $@

# The default separator pattern used by <tt>String.split</tt>.  May be
# set from the command line using the <tt>-F</tt> flag.
alias $FS                      $;

# The default separator pattern used by <tt>String.split</tt>.  May be
# set from the command line using the <tt>-F</tt> flag.
alias $FIELD_SEPARATOR         $;

# The separator string output between the parameters to methods such
# as <tt>Kernel.print</tt> and <tt>Array.join</tt>. Defaults to +nil+,
# which adds no text.
alias $OFS                     $,

# The separator string output between the parameters to methods such
# as <tt>Kernel.print</tt> and <tt>Array.join</tt>. Defaults to +nil+,
# which adds no text.
alias $OUTPUT_FIELD_SEPARATOR  $,

# The input record separator (newline by default). This is the value
# that routines such as <tt>Kernel.gets</tt> use to determine record
# boundaries. If set to +nil+, +gets+ will read the entire file.
alias $RS                      $/

# The input record separator (newline by default). This is the value
# that routines such as <tt>Kernel.gets</tt> use to determine record
# boundaries. If set to +nil+, +gets+ will read the entire file.
alias $INPUT_RECORD_SEPARATOR  $/

# The string appended to the output of every call to methods such as
# <tt>Kernel.print</tt> and <tt>IO.write</tt>. The default value is
# +nil+.
alias $ORS                     $\

# The string appended to the output of every call to methods such as
# <tt>Kernel.print</tt> and <tt>IO.write</tt>. The default value is
# +nil+.
alias $OUTPUT_RECORD_SEPARATOR $\

# The number of the last line read from the current input file.
alias $INPUT_LINE_NUMBER       $.

# The number of the last line read from the current input file.
alias $NR                      $.

# The last line read by <tt>Kernel.gets</tt> or
# <tt>Kernel.readline</tt>. Many string-related functions in the
# +Kernel+ module operate on <tt>$_</tt> by default. The variable is
# local to the current scope. Thread local.
alias $LAST_READ_LINE          $_

# The destination of output for <tt>Kernel.print</tt>
# and <tt>Kernel.printf</tt>. The default value is
# <tt>$stdout</tt>.
alias $DEFAULT_OUTPUT          $>

# An object that provides access to the concatenation
# of the contents of all the files
# given as command-line arguments, or <tt>$stdin</tt>
# (in the case where there are no
# arguments). <tt>$<</tt> supports methods similar to a 
# +File+ object:
# +inmode+, +close+,
# <tt>closed?</tt>, +each+,
# <tt>each_byte</tt>, <tt>each_line</tt>,
# +eof+, <tt>eof?</tt>, +file+,
# +filename+, +fileno+,
# +getc+, +gets+, +lineno+,
# <tt>lineno=</tt>, +path+, 
# +pos+, <tt>pos=</tt>,
# +read+, +readchar+,
# +readline+, +readlines+,
# +rewind+, +seek+, +skip+,
# +tell+, <tt>to_a</tt>, <tt>to_i</tt>,
# <tt>to_io</tt>, <tt>to_s</tt>, along with the
# methods in +Enumerable+. The method +file+
# returns a +File+ object for the file currently
# being read. This may change as <tt>$<</tt> reads
# through the files on the command line. Read only.
alias $DEFAULT_INPUT           $<

# The process number of the program being executed. Read only.
alias $PID                     $$

# The process number of the program being executed. Read only.
alias $PROCESS_ID              $$

# The exit status of the last child process to terminate. Read
# only. Thread local.
alias $CHILD_STATUS            $?

# A +MatchData+ object that encapsulates the results of a successful
# pattern match. The variables <tt>$&</tt>, <tt>$`</tt>, <tt>$'</tt>,
# and <tt>$1</tt> to <tt>$9</tt> are all derived from
# <tt>$~</tt>. Assigning to <tt>$~</tt> changes the values of these
# derived variables.  This variable is local to the current
# scope. Thread local.
alias $LAST_MATCH_INFO         $~

# If set to any value apart from +nil+ or +false+, all pattern matches
# will be case insensitive, string comparisons will ignore case, and
# string hash values will be case insensitive. Deprecated
alias $IGNORECASE              $=

# An array of strings containing the command-line
# options from the invocation of the program. Options
# used by the Ruby interpreter will have been
# removed. Read only. Also known simply as +ARGV+.
alias $ARGV                    $*

# The string matched by the last successful pattern
# match. This variable is local to the current
# scope. Read only. Thread local.
alias $MATCH                   $&

# The string preceding the match in the last
# successful pattern match. This variable is local to 
# the current scope. Read only. Thread local.
alias $PREMATCH                $`

# The string following the match in the last
# successful pattern match. This variable is local to 
# the current scope. Read only. Thread local.
alias $POSTMATCH               $'

# The contents of the highest-numbered group matched in the last
# successful pattern match. Thus, in <tt>"cat" =~ /(c|a)(t|z)/</tt>,
# <tt>$+</tt> will be set to "t".  This variable is local to the
# current scope. Read only. Thread local.
alias $LAST_PAREN_MATCH        $+
PK     Z\Z>!      shell/filter.rbnu [        #
#   shell/filter.rb - 
#   	$Release Version: 0.6.0 $
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#   
#

class Shell
  #
  # Filter
  # A method to require
  #    each()
  #
  class Filter
    include Enumerable

    def initialize(sh)
      @shell = sh	  # parent shell
      @input = nil	  # input filter
    end

    attr_reader :input

    def input=(filter)
      @input = filter
    end
    
    def each(rs = nil)
      rs = @shell.record_separator unless rs
      if @input
	@input.each(rs){|l| yield l}
      end
    end

    def < (src)
      case src
      when String
	cat = Cat.new(@shell, src)
	cat | self
      when IO
	self.input = src
	self
      else
	Shell.Fail Error::CantApplyMethod, "<", to.class
      end
    end

    def > (to)
      case to
      when String
	dst = @shell.open(to, "w")
	begin
	  each(){|l| dst << l}
	ensure
	  dst.close
	end
      when IO
	each(){|l| to << l}
      else
	Shell.Fail Error::CantApplyMethod, ">", to.class
      end
      self
    end

    def >> (to)
      begin
	Shell.cd(@shell.pwd).append(to, self)
      rescue CantApplyMethod
	Shell.Fail Error::CantApplyMethod, ">>", to.class
      end
    end

    def | (filter)
      filter.input = self
      if active?
	@shell.process_controller.start_job filter
      end
      filter
    end

    def + (filter)
      Join.new(@shell, self, filter)
    end

    def to_a
      ary = []
      each(){|l| ary.push l}
      ary
    end

    def to_s
      str = ""
      each(){|l| str.concat l}
      str
    end

    def inspect
      if @shell.debug.kind_of?(Integer) && @shell.debug > 2
	super
      else
	to_s
      end
    end
  end
end
PK     Z\Pʷ;  ;    shell/command-processor.rbnu [        #
#   shell/command-controller.rb - 
#   	$Release Version: 0.6.0 $
#   	$Revision: 22281 $
#   	$Date: 2009-02-13 19:05:02 +0900 (Fri, 13 Feb 2009) $
#   	by Keiju ISHITSUKA(Nippon Rational Inc.)
#
# --
#
#   
#

require "e2mmap"
require "ftools"
require "thread"

require "shell/error"
require "shell/filter"
require "shell/system-command"
require "shell/builtin-command"

class Shell
  class CommandProcessor
#    include Error

    #
    # initialize of Shell and related classes.
    #
    NoDelegateMethods = ["initialize", "expand_path"]
    def self.initialize

      install_builtin_commands

      # define CommandProccessor#methods to Shell#methods and Filter#methods
      for m in CommandProcessor.instance_methods(false) - NoDelegateMethods
	add_delegate_command_to_shell(m)
      end
      
      def self.method_added(id)
	add_delegate_command_to_shell(id)
      end
    end

    #
    # include run file.
    #
    def self.run_config
      begin
	load File.expand_path("~/.rb_shell") if ENV.key?("HOME")
      rescue LoadError, Errno::ENOENT
      rescue
	print "load error: #{rc}\n"
	print $!.class, ": ", $!, "\n"
	for err in $@[0, $@.size - 2]
	  print "\t", err, "\n"
	end
      end
    end

    def initialize(shell)
      @shell = shell
      @system_commands = {}
    end

    #
    # CommandProcessor#expand_path(path)
    #	  path:	  String
    #	  return: String
    #	returns the absolute path for <path>
    #
    def expand_path(path)
      @shell.expand_path(path)
    end

    #
    # File related commands
    # Shell#foreach
    # Shell#open
    # Shell#unlink
    # Shell#test
    #
    # -
    #	
    # CommandProcessor#foreach(path, rs)
    #	  path: String
    #	  rs:	String - record separator
    #	  iterator
    #	Same as:
    #	  File#foreach (when path is file)
    #	  Dir#foreach (when path is directory)
    #	path is relative to pwd
    #
    def foreach(path = nil, *rs)
      path = "." unless path
      path = expand_path(path)

      if File.directory?(path)
	Dir.foreach(path){|fn| yield fn}
      else
	IO.foreach(path, *rs){|l| yield l}
      end
    end

    #
    # CommandProcessor#open(path, mode)
    #	  path:	  String
    #	  mode:	  String
    #	  return: File or Dir
    #	Same as:
    #	  File#open (when path is file)
    #	  Dir#open  (when path is directory)
    #	mode has an effect only when path is a file
    #
    def open(path, mode)
      path = expand_path(path)
      if File.directory?(path)
	Dir.open(path)
      else
	effect_umask do
	  File.open(path, mode)
	end
      end
    end
    #  public :open

    #
    # CommandProcessor#unlink(path)
    #	same as:
    #	  Dir#unlink  (when path is directory)
    #	  File#unlink (when path is file)
    #
    def unlink(path)
      path = expand_path(path)
      if File.directory?(path)
	Dir.unlink(path)
      else
	IO.unlink(path)
      end
    end

    #
    # CommandProcessor#test(command, file1, file2)
    # CommandProcessor#[command, file1, file2]
    #	  command: char or String or Symbol
    #	  file1:   String
    #	  file2:   String(optional)
    #	  return: Boolean
    #	same as:
    #	  test()	   (when command is char or length 1 string or symbol)
    #	  FileTest.command (others)
    #	example:
    #	  sh[?e, "foo"]
    #	  sh[:e, "foo"]
    #	  sh["e", "foo"]
    #	  sh[:exists?, "foo"]
    #	  sh["exists?", "foo"]
    #	  
    alias top_level_test test
    def test(command, file1, file2=nil)
      file1 = expand_path(file1)
      file2 = expand_path(file2) if file2
      command = command.id2name if command.kind_of?(Symbol)

      case command
      when Integer
	if file2
	  top_level_test(command, file1, file2)
	else
	  top_level_test(command, file1)
	end
      when String
	if command.size == 1
	  if file2
	    top_level_test(command, file1, file2)
	  else
	    top_level_test(command, file1)
	  end
	else
	  if file2
	    FileTest.send(command, file1, file2)
	  else
	    FileTest.send(command, file1)
	  end
	end
      end
    end
    alias [] test

    #
    # Dir related methods
    #
    # Shell#mkdir
    # Shell#rmdir
    #
    #--
    #
    # CommandProcessor#mkdir(*path)
    #	  path: String
    #	same as Dir.mkdir()
    #	  
    def mkdir(*path)
      for dir in path
	Dir.mkdir(expand_path(dir))
      end
    end

    #
    # CommandProcessor#rmdir(*path)
    #	  path: String
    #	same as Dir.rmdir()
    #	  
    def rmdir(*path)
      for dir in path
	Dir.rmdir(expand_path(dir))
      end
    end

    #
    # CommandProcessor#system(command, *opts)
    #	  command: String
    #	  opts:	   String
    #	  return:  SystemCommand
    #	Same as system() function
    #	example:
    #	  print sh.system("ls", "-l")
    #	  sh.system("ls", "-l") | sh.head > STDOUT
    # 
    def system(command, *opts)
      if opts.empty?
	if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/
	  return SystemCommand.new(@shell, find_system_command("sh"), "-c", command)
	else
	  command, *opts = command.split(/\s+/)
	end
      end
      SystemCommand.new(@shell, find_system_command(command), *opts)
    end

    #
    # ProcessCommand#rehash
    #	clear command hash table.
    #
    def rehash
      @system_commands = {}
    end

    #
    # ProcessCommand#transact
    #
    def check_point
      @shell.process_controller.wait_all_jobs_execution
    end
    alias finish_all_jobs check_point

    def transact(&block)
      begin
	@shell.instance_eval(&block)
      ensure
	check_point
      end
    end

    #
    # internal commands
    #
    def out(dev = STDOUT, &block)
      dev.print transact(&block)
    end

    def echo(*strings)
      Echo.new(@shell, *strings)
    end

    def cat(*filenames)
      Cat.new(@shell, *filenames)
    end

    #   def sort(*filenames)
    #     Sort.new(self, *filenames)
    #   end

    def glob(pattern)
      Glob.new(@shell, pattern)
    end

    def append(to, filter)
      case to
      when String
	AppendFile.new(@shell, to, filter)
      when IO
	AppendIO.new(@shell, to, filter)
      else
	Shell.Fail Error::CantApplyMethod, "append", to.class
      end
    end

    def tee(file)
      Tee.new(@shell, file)
    end

    def concat(*jobs)
      Concat.new(@shell, *jobs)
    end

    # %pwd, %cwd -> @pwd
    def notify(*opts, &block)
      Thread.exclusive do
	Shell.notify(*opts) {|mes|
	  yield mes if iterator?
	
	  mes.gsub!("%pwd", "#{@cwd}")
	  mes.gsub!("%cwd", "#{@cwd}")
	}
      end
    end

    #
    # private functions
    #
    def effect_umask
      if @shell.umask
	Thread.critical = true
	save = File.umask
	begin
	  yield
	ensure
	  File.umask save
	  Thread.critical = false
	end
      else
	yield
      end
    end
    private :effect_umask

    def find_system_command(command)
      return command if /^\// =~ command
      case path = @system_commands[command]
      when String
	if exists?(path)
	  return path
	else
	  Shell.Fail Error::CommandNotFound, command
	end
      when false
	Shell.Fail Error::CommandNotFound, command
      end

      for p in @shell.system_path
	path = join(p, command)
	if FileTest.exists?(path)
	  @system_commands[command] = path
	  return path
	end
      end
      @system_commands[command] = false
      Shell.Fail Error::CommandNotFound, command
    end

    #
    # CommandProcessor.def_system_command(command, path)
    #	  command:  String
    #	  path:	    String
    #	define 'command()' method as method.
    #
    def self.def_system_command(command, path = command)
      begin
	eval((d = %Q[def #{command}(*opts)
     	          SystemCommand.new(@shell, '#{path}', *opts)
               end]), nil, __FILE__, __LINE__ - 1)
      rescue SyntaxError
	Shell.notify "warn: Can't define #{command} path: #{path}." 
      end
      Shell.notify "Define #{command} path: #{path}.", Shell.debug?
      Shell.notify("Definition of #{command}: ", d, 
	     Shell.debug.kind_of?(Integer) && Shell.debug > 1)
    end

    def self.undef_system_command(command)
      command = command.id2name if command.kind_of?(Symbol)
      remove_method(command)
      Shell.module_eval{remove_method(command)}
      Filter.module_eval{remove_method(command)}
      self
    end

    # define command alias
    # ex)
    # def_alias_command("ls_c", "ls", "-C", "-F")
    # def_alias_command("ls_c", "ls"){|*opts| ["-C", "-F", *opts]}
    #
    @alias_map = {}
    def self.alias_map
      @alias_map
    end
    def self.alias_command(ali, command, *opts, &block)
      ali = ali.id2name if ali.kind_of?(Symbol)
      command = command.id2name if command.kind_of?(Symbol)
      begin
	if iterator?
	  @alias_map[ali.intern] = proc

	  eval((d = %Q[def #{ali}(*opts)
                          @shell.__send__(:#{command},
                                          *(CommandProcessor.alias_map[:#{ali}].call *opts))
	                end]), nil, __FILE__, __LINE__ - 1)
    
	else
           args = opts.collect{|opt| '"' + opt + '"'}.join(",")
           eval((d = %Q[def #{ali}(*opts)
                          @shell.__send__(:#{command}, #{args}, *opts)
                        end]), nil, __FILE__, __LINE__ - 1)
	end
      rescue SyntaxError
	Shell.notify "warn: Can't alias #{ali} command: #{command}." 
	Shell.notify("Definition of #{ali}: ", d)
	raise
      end
      Shell.notify "Define #{ali} command: #{command}.", Shell.debug?
      Shell.notify("Definition of #{ali}: ", d, 
	     Shell.debug.kind_of?(Integer) && Shell.debug > 1)
      self
    end
   
    def self.unalias_command(ali)
      ali = ali.id2name if ali.kind_of?(Symbol)
      @alias_map.delete ali.intern
      undef_system_command(ali)
    end
   
    #
    # CommandProcessor.def_builtin_commands(delegation_class, command_specs)
    #	  delegation_class: Class or Module
    #	  command_specs: [[command_name, [argument,...]],...]
    #	     command_name: String
    #	     arguments:	   String
    #		FILENAME?? -> expand_path(filename??)
    #		*FILENAME?? -> filename??.collect{|f|expand_path(f)}.join(", ")
    #	define command_name(argument,...) as
    #	    delegation_class.command_name(argument,...)
    #
    def self.def_builtin_commands(delegation_class, command_specs)
      for meth, args in command_specs
	arg_str = args.collect{|arg| arg.downcase}.join(", ")
	call_arg_str = args.collect{
	  |arg|
	  case arg
	  when /^(FILENAME.*)$/
	    format("expand_path(%s)", $1.downcase)
	  when /^(\*FILENAME.*)$/
	    # \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ")
	    $1.downcase + '.collect{|fn| expand_path(fn)}'
	  else
	    arg
	  end
	}.join(", ")
	d = %Q[def #{meth}(#{arg_str})
		    #{delegation_class}.#{meth}(#{call_arg_str})
		 end]
	Shell.notify "Define #{meth}(#{arg_str})", Shell.debug?
	Shell.notify("Definition of #{meth}: ", d, 
	     Shell.debug.kind_of?(Integer) && Shell.debug > 1)
	eval d
      end
    end

    #
    # CommandProcessor.install_system_commands(pre)
    #	    pre: String - command name prefix
    # defines every command which belongs in default_system_path via
    # CommandProcessor.command().  It doesn't define already defined
    # methods twice.  By default, "pre_" is prefixes to each method
    # name.  Characters that may not be used in a method name are
    # all converted to '_'.  Definition errors are just ignored.
    #
    def self.install_system_commands(pre = "sys_")
      defined_meth = {}
      for m in Shell.methods
	defined_meth[m] = true
      end
      sh = Shell.new
      for path in Shell.default_system_path
	next unless sh.directory? path
	sh.cd path
	sh.foreach do
	  |cn|
	  if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn)
	    command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1')
	    begin
	      def_system_command(command, sh.expand_path(cn))
	    rescue
	      Shell.notify "warn: Can't define #{command} path: #{cn}"
	    end
	    defined_meth[command] = command
	  end
	end
      end
    end

    #----------------------------------------------------------------------
    #
    #  class initializing methods  - 
    #
    #----------------------------------------------------------------------
    def self.add_delegate_command_to_shell(id)
      id = id.intern if id.kind_of?(String)
      name = id.id2name
      if Shell.method_defined?(id)
	Shell.notify "warn: override definnition of Shell##{name}."
	Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n"
	Shell.module_eval "alias #{name}_org #{name}"
      end
      Shell.notify "method added: Shell##{name}.", Shell.debug?
      Shell.module_eval(%Q[def #{name}(*args, &block)
			    begin
			      @command_processor.__send__(:#{name}, *args, &block)
			    rescue Exception
			      $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
	                      $@.delete_if{|s| /^\\(eval\\):/ =~ s}
			    raise
			    end
                          end], __FILE__, __LINE__)

      if Shell::Filter.method_defined?(id)
	Shell.notify "warn: override definnition of Shell::Filter##{name}."
	Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org."
	Filter.module_eval "alias #{name}_org #{name}"
      end
      Shell.notify "method added: Shell::Filter##{name}.", Shell.debug?
      Filter.module_eval(%Q[def #{name}(*args, &block)
			    begin
			      self | @shell.__send__(:#{name}, *args, &block)
			    rescue Exception
			      $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
	                      $@.delete_if{|s| /^\\(eval\\):/ =~ s}
			    raise
			    end
                          end], __FILE__, __LINE__)
    end

    #
    # define default builtin commands
    #
    def self.install_builtin_commands
      # method related File.
      #	(exclude open/foreach/unlink)
      normal_delegation_file_methods = [
	["atime", ["FILENAME"]],
	["basename", ["fn", "*opts"]],
	["chmod", ["mode", "*FILENAMES"]], 
	["chown", ["owner", "group", "*FILENAME"]],
	["ctime", ["FILENAMES"]],
	["delete", ["*FILENAMES"]],
	["dirname", ["FILENAME"]],
	["ftype", ["FILENAME"]],
	["join", ["*items"]],
	["link", ["FILENAME_O", "FILENAME_N"]],
	["lstat", ["FILENAME"]],
	["mtime", ["FILENAME"]],
	["readlink", ["FILENAME"]],
	["rename", ["FILENAME_FROM", "FILENAME_TO"]],
	#      ["size", ["FILENAME"]],
	["split", ["pathname"]],
	["stat", ["FILENAME"]],
	["symlink", ["FILENAME_O", "FILENAME_N"]],
	["truncate", ["FILENAME", "length"]],
	["utime", ["atime", "mtime", "*FILENAMES"]]]

      def_builtin_commands(File, normal_delegation_file_methods)
      alias_method :rm, :delete

      # method related FileTest
      def_builtin_commands(FileTest, 
		   FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]})

      # method related ftools
      normal_delegation_ftools_methods = [
	["syscopy", ["FILENAME_FROM", "FILENAME_TO"]],
	["copy", ["FILENAME_FROM", "FILENAME_TO"]],
	["move", ["FILENAME_FROM", "FILENAME_TO"]],
	["compare", ["FILENAME_FROM", "FILENAME_TO"]],
	["safe_unlink", ["*FILENAMES"]],
	["makedirs", ["*FILENAMES"]],
	#    ["chmod", ["mode", "*FILENAMES"]],
	["install", ["FILENAME_FROM", "FILENAME_TO", "mode"]],
      ]
      def_builtin_commands(File,
		   normal_delegation_ftools_methods)
      alias_method :cmp, :compare
      alias_method :mv, :move
      alias_method :cp, :copy
      alias_method :rm_f, :safe_unlink
      alias_method :mkpath, :makedirs
    end

  end
end
PK     Z\n  n    shell/system-command.rbnu [        #
#   shell/system-command.rb - 
#   	$Release Version: 0.6.0 $
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#   
#

require "shell/filter"

class Shell
  class SystemCommand < Filter
    def initialize(sh, command, *opts)
      if t = opts.find{|opt| !opt.kind_of?(String) && opt.class}
	Shell.Fail Error::TypeError, t.class, "String"
      end
      super(sh)
      @command = command
      @opts = opts
      
      @input_queue = Queue.new
      @pid = nil

      sh.process_controller.add_schedule(self)
    end

    attr_reader :command
    alias name command

    def wait?
      @shell.process_controller.waiting_job?(self)
    end

    def active?
      @shell.process_controller.active_job?(self)
    end

    def input=(inp)
      super
      if active?
	start_export
      end
    end

    def start
      @pid, @pipe_in, @pipe_out = @shell.process_controller.sfork(self) {
	Dir.chdir @shell.pwd
	exec(@command, *@opts)
      }
      if @input
	start_export
      end
      start_import
    end

    def flush
      @pipe_out.flush if @pipe_out and !@pipe_out.closed?
    end

    def terminate
      begin
	@pipe_in.close
      rescue IOError
      end
      begin
	@pipe_out.close
      rescue IOError
      end
    end

    def kill(sig)
      if @pid
	Process.kill(sig, @pid)
      end
    end


    def start_import
#      Thread.critical = true
      notify "Job(%id) start imp-pipe.", @shell.debug?
      rs = @shell.record_separator unless rs
      _eop = true
#      Thread.critical = false
      th = Thread.start {
	Thread.critical = true
	begin
	  Thread.critical = false
	  while l = @pipe_in.gets
	    @input_queue.push l
	  end
	  _eop = false
	rescue Errno::EPIPE
	  _eop = false
	ensure
	  if _eop
	    notify("warn: Process finishing...",
		   "wait for Job[%id] to finish pipe importing.",
		   "You can use Shell#transact or Shell#check_point for more safe execution.")
#	    Tracer.on
	    Thread.current.run
	    redo
	  end
	  Thread.exclusive do
	    notify "job(%id}) close imp-pipe.", @shell.debug?
	    @input_queue.push :EOF
	    @pipe_in.close
	  end
	end
      }
    end

    def start_export
      notify "job(%id) start exp-pipe.", @shell.debug?
      _eop = true
      th = Thread.start{
	Thread.critical = true
	begin
	  Thread.critical = false
	  @input.each{|l| @pipe_out.print l}
	  _eop = false
	rescue Errno::EPIPE
	  _eop = false
	ensure
	  if _eop
	    notify("shell: warn: Process finishing...",
		   "wait for Job(%id) to finish pipe exporting.",
		   "You can use Shell#transact or Shell#check_point for more safe execution.")
#	    Tracer.on
	    redo
	  end
	  Thread.exclusive do
	    notify "job(%id) close exp-pipe.", @shell.debug?
	    @pipe_out.close
	  end
	end
      }
    end

    alias super_each each
    def each(rs = nil)
      while (l = @input_queue.pop) != :EOF
	yield l
      end
    end

    # ex)
    #    if you wish to output: 
    #	    "shell: job(#{@command}:#{@pid}) close pipe-out."
    #	 then 
    #	    mes: "job(%id) close pipe-out."
    #    yorn: Boolean(@shell.debug? or @shell.verbose?)
    def notify(*opts, &block)
      Thread.exclusive do
	@shell.notify(*opts) {|mes|
	  yield mes if iterator?

	  mes.gsub!("%id", "#{@command}:##{@pid}")
	  mes.gsub!("%name", "#{@command}")
	  mes.gsub!("%pid", "#{@pid}")
	}
      end
    end
  end
end
PK     Z\Ro	  	    shell/builtin-command.rbnu [        #
#   shell/builtin-command.rb - 
#   	$Release Version: 0.6.0 $
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#   
#

require "shell/filter"

class Shell
  class BuiltInCommand<Filter
    def wait?
      false
    end
    def active?
      true
    end
  end

  class Echo < BuiltInCommand
    def initialize(sh, *strings)
      super sh
      @strings = strings
    end
    
    def each(rs = nil)
      rs =  @shell.record_separator unless rs
      for str  in @strings
	yield str + rs
      end
    end
  end

  class Cat < BuiltInCommand
    def initialize(sh, *filenames)
      super sh
      @cat_files = filenames
    end

    def each(rs = nil)
      if @cat_files.empty?
	super
      else
	for src in @cat_files
	  @shell.foreach(src, rs){|l| yield l}
	end
      end
    end
  end

  class Glob < BuiltInCommand
    def initialize(sh, pattern)
      super sh

      @pattern = pattern
      Thread.critical = true
      back = Dir.pwd
      begin
	Dir.chdir @shell.cwd
	@files = Dir[pattern]
      ensure
	Dir.chdir back
	Thread.critical = false
      end
    end

    def each(rs = nil)
      rs =  @shell.record_separator unless rs
      for f  in @files
	yield f+rs
      end
    end
  end

#   class Sort < Cat
#     def initialize(sh, *filenames)
#       super
#     end
#
#     def each(rs = nil)
#       ary = []
#       super{|l|	ary.push l}
#       for l in ary.sort!
# 	yield l
#       end
#     end
#   end

  class AppendIO < BuiltInCommand
    def initialize(sh, io, filter)
      super sh
      @input = filter
      @io = io
    end

    def input=(filter)
      @input.input=filter
      for l in @input
	@io << l
      end
    end

  end

  class AppendFile < AppendIO
    def initialize(sh, to_filename, filter)
      @file_name = to_filename
      io = sh.open(to_filename, "a")
      super(sh, io, filter)
    end

    def input=(filter)
      begin
	super
      ensure
	@io.close
      end
    end
  end

  class Tee < BuiltInCommand
    def initialize(sh, filename)
      super sh
      @to_filename = filename
    end

    def each(rs = nil)
      to = @shell.open(@to_filename, "w")
      begin
	super{|l| to << l; yield l}
      ensure
	to.close
      end
    end
  end

  class Concat < BuiltInCommand
    def initialize(sh, *jobs)
      super(sh)
      @jobs = jobs
    end

    def each(rs = nil)
      while job = @jobs.shift
	job.each{|l| yield l}
      end
    end
  end
end
PK     Z\i  i    shell/process-controller.rbnu [        #
#   shell/process-controller.rb - 
#   	$Release Version: 0.6.0 $
#   	$Revision: 12006 $
#   	$Date: 2007-03-06 18:59:25 +0900 (Tue, 06 Mar 2007) $
#   	by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#   
#

require "mutex_m"
require "monitor"
require "sync"

class Shell
  class ProcessController

    @ProcessControllers = {}
    @ProcessControllers.extend Mutex_m

    class<<self

      def process_controllers_exclusive
	begin
	  @ProcessControllers.lock unless Thread.critical 
	  yield
	ensure
	  @ProcessControllers.unlock unless Thread.critical 
	end
      end

      def activate(pc)
	process_controllers_exclusive do
	  @ProcessControllers[pc] ||= 0
	  @ProcessControllers[pc] += 1
	end
      end

      def inactivate(pc)
	process_controllers_exclusive do
	  if @ProcessControllers[pc]
	    if (@ProcessControllers[pc] -= 1) == 0
	      @ProcessControllers.delete(pc)
	    end
	  end
	end
      end

      def each_active_object
	process_controllers_exclusive do
	  for ref in @ProcessControllers.keys
	    yield ref
	  end
	end
      end
    end

    def initialize(shell)
      @shell = shell
      @waiting_jobs = []
      @active_jobs = []
      @jobs_sync = Sync.new

      @job_monitor = Mutex.new
      @job_condition = ConditionVariable.new
    end

    def jobs
      jobs = []
      @jobs_sync.synchronize(:SH) do
	jobs.concat @waiting_jobs
	jobs.concat @active_jobs
      end
      jobs
    end

    def active_jobs
      @active_jobs
    end

    def waiting_jobs
      @waiting_jobs
    end
    
    def jobs_exist?
      @jobs_sync.synchronize(:SH) do
	@active_jobs.empty? or @waiting_jobs.empty?
      end
    end

    def active_jobs_exist?
      @jobs_sync.synchronize(:SH) do
	@active_jobs.empty?
      end
    end

    def waiting_jobs_exist?
      @jobs_sync.synchronize(:SH) do
	@waiting_jobs.empty?
      end
    end

    # schedule a command
    def add_schedule(command)
      @jobs_sync.synchronize(:EX) do
	ProcessController.activate(self)
	if @active_jobs.empty?
	  start_job command
	else
	  @waiting_jobs.push(command)
	end
      end
    end

    # start a job
    def start_job(command = nil)
      @jobs_sync.synchronize(:EX) do
	if command
	  return if command.active?
	  @waiting_jobs.delete command
	else
	  command = @waiting_jobs.shift
	  return unless command
	end
	@active_jobs.push command
	command.start

	# start all jobs that input from the job
	for job in @waiting_jobs
	  start_job(job) if job.input == command
	end
      end
    end

    def waiting_job?(job)
      @jobs_sync.synchronize(:SH) do
	@waiting_jobs.include?(job)
      end
    end

    def active_job?(job)
      @jobs_sync.synchronize(:SH) do
	@active_jobs.include?(job)
      end
    end

    # terminate a job
    def terminate_job(command)
      @jobs_sync.synchronize(:EX) do
	@active_jobs.delete command
	ProcessController.inactivate(self)
	if @active_jobs.empty?
	  start_job
	end
      end
    end

    # kill a job
    def kill_job(sig, command)
      @jobs_sync.synchronize(:SH) do
	if @waiting_jobs.delete command
	  ProcessController.inactivate(self)
	  return
	elsif @active_jobs.include?(command)
	  begin
	    r = command.kill(sig)
	    ProcessController.inactivate(self)
	  rescue
	    print "Shell: Warn: $!\n" if @shell.verbose?
	    return nil
	  end
	  @active_jobs.delete command
	  r
	end
      end
    end

    # wait for all jobs to terminate
    def wait_all_jobs_execution
      @job_monitor.synchronize do
	begin
	  while !jobs.empty?
	    @job_condition.wait(@job_monitor)
	  end
	ensure
	  redo unless jobs.empty?
	end
      end
    end

    # simple fork
    def sfork(command, &block)
      pipe_me_in, pipe_peer_out = IO.pipe
      pipe_peer_in, pipe_me_out = IO.pipe
      Thread.critical = true

      STDOUT.flush
      ProcessController.each_active_object do |pc|
	for jobs in pc.active_jobs
	  jobs.flush
	end
      end
      
      pid = fork {
	Thread.critical = true

	Thread.list.each do |th| 
	  th.kill unless [Thread.main, Thread.current].include?(th)
	end

	STDIN.reopen(pipe_peer_in)
	STDOUT.reopen(pipe_peer_out)

	ObjectSpace.each_object(IO) do |io| 
	  if ![STDIN, STDOUT, STDERR].include?(io)
	    io.close unless io.closed?
	  end
	end
	yield
      }

      pipe_peer_in.close
      pipe_peer_out.close
      command.notify "job(%name:##{pid}) start", @shell.debug?
      Thread.critical = false

      th = Thread.start {
	Thread.critical = true
	begin
	  _pid = nil
	  command.notify("job(%id) start to waiting finish.", @shell.debug?)
	  Thread.critical = false
	  _pid = Process.waitpid(pid, nil)
	rescue Errno::ECHILD
	  command.notify "warn: job(%id) was done already waitipd."
	  _pid = true
	ensure
	  # when the process ends, wait until the command termintes
	  if _pid
	  else
	    command.notify("notice: Process finishing...",
			   "wait for Job[%id] to finish.",
			   "You can use Shell#transact or Shell#check_point for more safe execution.")
	    redo
	  end
	  Thread.exclusive do
	    @job_monitor.synchronize do 
	      terminate_job(command)
	      @job_condition.signal
	      command.notify "job(%id) finish.", @shell.debug?
	    end
	  end
	end
      }
      return pid, pipe_me_in, pipe_me_out
    end
  end
end
PK     Z\_      shell/error.rbnu [        #
#   shell/error.rb - 
#   	$Release Version: 0.6.0 $
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#   
#

require "e2mmap"

class Shell
  module Error
    extend Exception2MessageMapper
    def_e2message TypeError, "wrong argument type %s (expected %s)"

    def_exception :DirStackEmpty, "Directory stack empty."
    def_exception :CantDefine, "Can't define method(%s, %s)."
    def_exception :CantApplyMethod, "This method(%s) does not apply to this type(%s)."
    def_exception :CommandNotFound, "Command not found(%s)."
  end
end

PK     Z\DN_:  :    shell/version.rbnu [        #
#   version.rb - shell version definition file
#   	$Release Version: 0.6.0$
#   	$Revision: 11708 $
#   	$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
#   	by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#   
#

class Shell
  @RELEASE_VERSION = "0.6.0"
  @LAST_UPDATE_DATE = "01/03/19"
end
PK     Z\!  !    rdoc/rdoc.rbnu [        # See README.
#
 

VERSION_STRING = %{RDoc V1.0.1 - 20041108}


require 'rdoc/parsers/parse_rb.rb'
require 'rdoc/parsers/parse_c.rb'
require 'rdoc/parsers/parse_f95.rb'

require 'rdoc/parsers/parse_simple.rb'
require 'rdoc/options'

require 'rdoc/diagram'

require 'find'
require 'ftools'
require 'time'

# We put rdoc stuff in the RDoc module to avoid namespace
# clutter.
#
# ToDo: This isn't universally true.
#
# :include: README

module RDoc

  # Name of the dotfile that contains the description of files to be
  # processed in the current directory
  DOT_DOC_FILENAME = ".document"

  # Simple stats collector
  class Stats
    attr_accessor :num_files, :num_classes, :num_modules, :num_methods
    def initialize
      @num_files = @num_classes = @num_modules = @num_methods = 0
      @start = Time.now
    end
    def print
      puts "Files:   #@num_files"
      puts "Classes: #@num_classes"
      puts "Modules: #@num_modules"
      puts "Methods: #@num_methods"
      puts "Elapsed: " + sprintf("%0.3fs", Time.now - @start)
    end
  end


  # Exception thrown by any rdoc error. Only the #message part is
  # of use externally.

  class RDocError < Exception
  end

  # Encapsulate the production of rdoc documentation. Basically
  # you can use this as you would invoke rdoc from the command
  # line:
  #
  #    rdoc = RDoc::RDoc.new
  #    rdoc.document(args)
  #
  # where _args_ is an array of strings, each corresponding to
  # an argument you'd give rdoc on the command line. See rdoc/rdoc.rb 
  # for details.
  
  class RDoc

    ##
    # This is the list of output generators that we
    # support
    
    Generator = Struct.new(:file_name, :class_name, :key)
    
    GENERATORS = {}
    $:.collect {|d|
      File::expand_path(d)
    }.find_all {|d|
      File::directory?("#{d}/rdoc/generators")
    }.each {|dir|
      Dir::entries("#{dir}/rdoc/generators").each {|gen|
        next unless /(\w+)_generator.rb$/ =~ gen
        type = $1
        unless GENERATORS.has_key? type
          GENERATORS[type] = Generator.new("rdoc/generators/#{gen}",
                                           "#{type.upcase}Generator".intern,
                                           type)
        end
      }
    }                                                    

    #######
    private
    #######

    ##
    # Report an error message and exit
    
    def error(msg)
      raise RDocError.new(msg)
    end
    
    ##
    # Create an output dir if it doesn't exist. If it does
    # exist, but doesn't contain the flag file <tt>created.rid</tt>
    # then we refuse to use it, as we may clobber some
    # manually generated documentation
    
    def setup_output_dir(op_dir, force)
      flag_file = output_flag_file(op_dir)
      if File.exist?(op_dir)
        unless File.directory?(op_dir)
          error "'#{op_dir}' exists, and is not a directory" 
        end
        begin
          created = File.read(flag_file)
        rescue SystemCallError
          error "\nDirectory #{op_dir} already exists, but it looks like it\n" +
            "isn't an RDoc directory. Because RDoc doesn't want to risk\n" +
            "destroying any of your existing files, you'll need to\n" +
            "specify a different output directory name (using the\n" +
            "--op <dir> option).\n\n"
        else
          last = (Time.parse(created) unless force rescue nil)
        end
      else
        File.makedirs(op_dir)
      end
      last
    end

    # Update the flag file in an output directory.
    def update_output_dir(op_dir, time)
      File.open(output_flag_file(op_dir), "w") {|f| f.puts time.rfc2822 }
    end

    # Return the path name of the flag file in an output directory.
    def output_flag_file(op_dir)
      File.join(op_dir, "created.rid")
    end

    # The .document file contains a list of file and directory name
    # patterns, representing candidates for documentation. It may
    # also contain comments (starting with '#')
    def parse_dot_doc_file(in_dir, filename, options)
      # read and strip comments
      patterns = File.read(filename).gsub(/#.*/, '')

      result = []

      patterns.split.each do |patt|
        candidates = Dir.glob(File.join(in_dir, patt))
        result.concat(normalized_file_list(options,  candidates))
      end
      result
    end


    # Given a list of files and directories, create a list
    # of all the Ruby files they contain. 
    #
    # If +force_doc+ is true, we always add the given files.
    # If false, only add files that we guarantee we can parse
    # It is true when looking at files given on the command line,
    # false when recursing through subdirectories. 
    #
    # The effect of this is that if you want a file with a non-
    # standard extension parsed, you must name it explicity.
    #

    def normalized_file_list(options, relative_files, force_doc = false, exclude_pattern=nil)
      file_list = []

      relative_files.each do |rel_file_name|
        next if exclude_pattern && exclude_pattern =~ rel_file_name
        stat = File.stat(rel_file_name)
        case type = stat.ftype
        when "file"
          next if @last_created and stat.mtime < @last_created
          file_list << rel_file_name.sub(/^\.\//, '') if force_doc || ParserFactory.can_parse(rel_file_name)
        when "directory"
          next if rel_file_name == "CVS" || rel_file_name == ".svn"
          dot_doc = File.join(rel_file_name, DOT_DOC_FILENAME)
          if File.file?(dot_doc)
            file_list.concat(parse_dot_doc_file(rel_file_name, dot_doc, options))
          else
            file_list.concat(list_files_in_directory(rel_file_name, options))
          end
        else
          raise RDocError.new("I can't deal with a #{type} #{rel_file_name}")
        end
      end
      file_list
    end

    # Return a list of the files to be processed in
    # a directory. We know that this directory doesn't have
    # a .document file, so we're looking for real files. However
    # we may well contain subdirectories which must
    # be tested for .document files
    def list_files_in_directory(dir, options)
      normalized_file_list(options, Dir.glob(File.join(dir, "*")), false, options.exclude)
    end


    # Parse each file on the command line, recursively entering
    # directories

    def parse_files(options)
 
      file_info = []

      files = options.files
      files = ["."] if files.empty?

      file_list = normalized_file_list(options, files, true)

      file_list.each do |fn|
        $stderr.printf("\n%35s: ", File.basename(fn)) unless options.quiet
        
        content = File.open(fn, "r") {|f| f.read}

        top_level = TopLevel.new(fn)
        parser = ParserFactory.parser_for(top_level, fn, content, options, @stats)
        file_info << parser.scan
        @stats.num_files += 1
      end

      file_info
    end


    public

    ###################################################################
    #
    # Format up one or more files according to the given arguments.
    # For simplicity, _argv_ is an array of strings, equivalent to the
    # strings that would be passed on the command line. (This isn't a
    # coincidence, as we _do_ pass in ARGV when running
    # interactively). For a list of options, see rdoc/rdoc.rb. By
    # default, output will be stored in a directory called +doc+ below
    # the current directory, so make sure you're somewhere writable
    # before invoking.
    #
    # Throws: RDocError on error

    def document(argv)

      TopLevel::reset

      @stats = Stats.new

      options = Options.instance
      options.parse(argv, GENERATORS)

      @last_created = nil
      unless options.all_one_file
        @last_created = setup_output_dir(options.op_dir, options.force_update)
      end
      start_time = Time.now

      file_info = parse_files(options)

      if file_info.empty?
        $stderr.puts "\nNo newer files." unless options.quiet
      else
        gen = options.generator

        $stderr.puts "\nGenerating #{gen.key.upcase}..." unless options.quiet

        require gen.file_name

        gen_class = Generators.const_get(gen.class_name)
        gen = gen_class.for(options)

        pwd = Dir.pwd

        Dir.chdir(options.op_dir)  unless options.all_one_file

        begin
          Diagram.new(file_info, options).draw if options.diagram
          gen.generate(file_info)
          update_output_dir(".", start_time)
        ensure
          Dir.chdir(pwd)
        end
      end

      unless options.quiet
        puts
        @stats.print
      end
    end
  end
end

PK     Z\%#H  #H    rdoc/code_objects.rbnu [        # We represent the various high-level code constructs that appear
# in Ruby programs: classes, modules, methods, and so on.

require 'rdoc/tokenstream'

module RDoc


  # We contain the common stuff for contexts (which are containers)
  # and other elements (methods, attributes and so on)
  #
  class CodeObject

    attr_accessor :parent

    # We are the model of the code, but we know that at some point
    # we will be worked on by viewers. By implementing the Viewable
    # protocol, viewers can associated themselves with these objects.

    attr_accessor :viewer

    # are we done documenting (ie, did we come across a :enddoc:)?

    attr_accessor :done_documenting

    # Which section are we in

    attr_accessor :section

    # do we document ourselves?

    attr_reader :document_self

    def document_self=(val)
      @document_self = val
      if !val
	remove_methods_etc
      end
    end

    # set and cleared by :startdoc: and :enddoc:, this is used to toggle
    # the capturing of documentation
    def start_doc
      @document_self = true
      @document_children = true
    end

    def stop_doc
      @document_self = false
      @document_children = false
    end

    # do we document ourselves and our children

    attr_reader :document_children

    def document_children=(val)
      @document_children = val
      if !val
	remove_classes_and_modules
      end
    end

    # Do we _force_ documentation, even is we wouldn't normally show the entity
    attr_accessor :force_documentation

    # Default callbacks to nothing, but this is overridden for classes
    # and modules
    def remove_classes_and_modules
    end

    def remove_methods_etc
    end

    def initialize
      @document_self = true
      @document_children = true
      @force_documentation = false
      @done_documenting = false
    end

    # Access the code object's comment
    attr_reader :comment

    # Update the comment, but don't overwrite a real comment
    # with an empty one
    def comment=(comment)
      @comment = comment unless comment.empty?
    end

    # There's a wee trick we pull. Comment blocks can have directives that
    # override the stuff we extract during the parse. So, we have a special
    # class method, attr_overridable, that lets code objects list
    # those directives. Wehn a comment is assigned, we then extract
    # out any matching directives and update our object

    def CodeObject.attr_overridable(name, *aliases)
      @overridables ||= {}

      attr_accessor name

      aliases.unshift name
      aliases.each do |directive_name|
        @overridables[directive_name.to_s] = name
      end
    end

  end

  # A Context is something that can hold modules, classes, methods, 
  # attributes, aliases, requires, and includes. Classes, modules, and
  # files are all Contexts.

  class Context < CodeObject
    attr_reader   :name, :method_list, :attributes, :aliases, :constants
    attr_reader   :requires, :includes, :in_files, :visibility

    attr_reader   :sections

    class Section
      attr_reader :title, :comment, :sequence

      @@sequence = "SEC00000"

      def initialize(title, comment)
        @title = title
        @@sequence.succ!
        @sequence = @@sequence.dup
        set_comment(comment)
      end

      private

      # Set the comment for this section from the original comment block
      # If the first line contains :section:, strip it and use the rest. Otherwise
      # remove lines up to the line containing :section:, and look for 
      # those lines again at the end and remove them. This lets us write
      #
      #   # ---------------------
      #   # :SECTION: The title
      #   # The body
      #   # ---------------------

      def set_comment(comment)
        return unless comment

        if comment =~ /^.*?:section:.*$/
          start = $`
          rest = $'
          if start.empty?
            @comment = rest
          else
            @comment = rest.sub(/#{start.chomp}\Z/, '')
          end
        else
          @comment = comment
        end
        @comment = nil if @comment.empty?
      end
    end


    def initialize
      super()

      @in_files    = []

      @name    ||= "unknown"
      @comment ||= ""
      @parent  = nil
      @visibility = :public

      @current_section = Section.new(nil, nil)
      @sections = [ @current_section ]

      initialize_methods_etc
      initialize_classes_and_modules
    end

    # map the class hash to an array externally
    def classes
      @classes.values
    end

    # map the module hash to an array externally
    def modules
      @modules.values
    end

    # Change the default visibility for new methods
    def ongoing_visibility=(vis)
      @visibility = vis
    end

    # Given an array +methods+ of method names, set the
    # visibility of the corresponding AnyMethod object

    def set_visibility_for(methods, vis, singleton=false)
      count = 0
      @method_list.each do |m|
        if methods.include?(m.name) && m.singleton == singleton
          m.visibility = vis
          count += 1
        end
      end

      return if count == methods.size || singleton

      # perhaps we need to look at attributes

      @attributes.each do |a|
        if methods.include?(a.name)
          a.visibility = vis
          count += 1
        end
      end
    end

    # Record the file that we happen to find it in
    def record_location(toplevel)
      @in_files << toplevel unless @in_files.include?(toplevel)
    end

    # Return true if at least part of this thing was defined in +file+
    def defined_in?(file)
      @in_files.include?(file)
    end

    def add_class(class_type, name, superclass)
      add_class_or_module(@classes, class_type, name, superclass)
    end

    def add_module(class_type, name)
      add_class_or_module(@modules, class_type, name, nil)
    end

    def add_method(a_method)
      puts "Adding #@visibility method #{a_method.name} to #@name" if $DEBUG
      a_method.visibility = @visibility
      add_to(@method_list, a_method)
    end

    def add_attribute(an_attribute)
      add_to(@attributes, an_attribute)
    end

    def add_alias(an_alias)
      meth = find_instance_method_named(an_alias.old_name)
      if meth
        new_meth = AnyMethod.new(an_alias.text, an_alias.new_name)
        new_meth.is_alias_for = meth
        new_meth.singleton    = meth.singleton
        new_meth.params       = meth.params
        new_meth.comment = "Alias for \##{meth.name}"
        meth.add_alias(new_meth)
        add_method(new_meth)
      else
        add_to(@aliases, an_alias)
      end
    end

    def add_include(an_include)
      add_to(@includes, an_include)
    end

    def add_constant(const)
      add_to(@constants, const)
    end

    # Requires always get added to the top-level (file) context
    def add_require(a_require)
      if self.kind_of? TopLevel
        add_to(@requires, a_require)
      else
        parent.add_require(a_require)
      end
    end

    def add_class_or_module(collection, class_type, name, superclass=nil)
      cls = collection[name]
      if cls
        puts "Reusing class/module #{name}" if $DEBUG
      else
        cls = class_type.new(name, superclass)
        puts "Adding class/module #{name} to #@name" if $DEBUG
#        collection[name] = cls if @document_self  && !@done_documenting
        collection[name] = cls if !@done_documenting
        cls.parent = self
        cls.section = @current_section
      end
      cls
    end

    def add_to(array, thing)
      array <<  thing if @document_self  && !@done_documenting
      thing.parent = self
      thing.section = @current_section
    end

    # If a class's documentation is turned off after we've started
    # collecting methods etc., we need to remove the ones
    # we have

    def remove_methods_etc
      initialize_methods_etc
    end

    def initialize_methods_etc
      @method_list = []
      @attributes  = []
      @aliases     = []
      @requires    = []
      @includes    = []
      @constants   = []
    end

    # and remove classes and modules when we see a :nodoc: all
    def remove_classes_and_modules
      initialize_classes_and_modules
    end

    def initialize_classes_and_modules
      @classes     = {}
      @modules     = {}
    end

    # Find a named module
    def find_module_named(name)
      return self if self.name == name
      res = @modules[name] || @classes[name]
      return res if res
      find_enclosing_module_named(name)
    end

    # find a module at a higher scope
    def find_enclosing_module_named(name)
      parent && parent.find_module_named(name)
    end

    # Iterate over all the classes and modules in
    # this object

    def each_classmodule
      @modules.each_value {|m| yield m}
      @classes.each_value {|c| yield c}
    end

    def each_method
      @method_list.each {|m| yield m}
    end

    def each_attribute 
      @attributes.each {|a| yield a}
    end

    def each_constant
      @constants.each {|c| yield c}
    end

    # Return the toplevel that owns us

    def toplevel
      return @toplevel if defined? @toplevel
      @toplevel = self
      @toplevel = @toplevel.parent until TopLevel === @toplevel
      @toplevel
    end

    # allow us to sort modules by name
    def <=>(other)
      name <=> other.name
    end

    # Look up the given symbol. If method is non-nil, then
    # we assume the symbol references a module that
    # contains that method
    def find_symbol(symbol, method=nil)
      result = nil
      case symbol
      when /^::(.*)/
        result = toplevel.find_symbol($1)
      when /::/
        modules = symbol.split(/::/)
        unless modules.empty?
          module_name = modules.shift
          result = find_module_named(module_name)
          if result
            modules.each do |module_name|
              result = result.find_module_named(module_name)
              break unless result
            end
          end
        end
      else
        # if a method is specified, then we're definitely looking for
        # a module, otherwise it could be any symbol
        if method
          result = find_module_named(symbol)
        else
          result = find_local_symbol(symbol)
          if result.nil?
            if symbol =~ /^[A-Z]/
              result = parent
              while result && result.name != symbol
                result = result.parent
              end
            end
          end
        end
      end
      if result && method
        if !result.respond_to?(:find_local_symbol)
          p result.name
          p method
          fail
        end
        result = result.find_local_symbol(method)
      end
      result
    end
           
    def find_local_symbol(symbol)
      res = find_method_named(symbol) ||
            find_constant_named(symbol) ||
            find_attribute_named(symbol) ||
            find_module_named(symbol) 
    end

    # Handle sections

    def set_current_section(title, comment)
      @current_section = Section.new(title, comment)
      @sections << @current_section
    end

    private

    # Find a named method, or return nil
    def find_method_named(name)
      @method_list.find {|meth| meth.name == name}
    end

    # Find a named instance method, or return nil
    def find_instance_method_named(name)
      @method_list.find {|meth| meth.name == name && !meth.singleton}
    end

    # Find a named constant, or return nil
    def find_constant_named(name)
      @constants.find {|m| m.name == name}
    end

    # Find a named attribute, or return nil
    def find_attribute_named(name)
      @attributes.find {|m| m.name == name}
    end
    
  end


  # A TopLevel context is a source file

  class TopLevel < Context
    attr_accessor :file_stat
    attr_accessor :file_relative_name
    attr_accessor :file_absolute_name
    attr_accessor :diagram
    
    @@all_classes = {}
    @@all_modules = {}

    def TopLevel::reset
      @@all_classes = {}
      @@all_modules = {}
    end

    def initialize(file_name)
      super()
      @name = "TopLevel"
      @file_relative_name = file_name
      @file_absolute_name = file_name
      @file_stat          = File.stat(file_name)
      @diagram            = nil
    end

    def full_name
      nil
    end

    # Adding a class or module to a TopLevel is special, as we only
    # want one copy of a particular top-level class. For example,
    # if both file A and file B implement class C, we only want one
    # ClassModule object for C. This code arranges to share
    # classes and modules between files.

    def add_class_or_module(collection, class_type, name, superclass)
      cls = collection[name]
      if cls
        puts "Reusing class/module #{name}" if $DEBUG
      else
        if class_type == NormalModule
          all = @@all_modules
        else
          all = @@all_classes
        end
        cls = all[name]
        if !cls
          cls = class_type.new(name, superclass)
          all[name] = cls  unless @done_documenting
        end
        puts "Adding class/module #{name} to #@name" if $DEBUG
        collection[name] = cls unless @done_documenting
        cls.parent = self
      end
      cls
    end

    def TopLevel.all_classes_and_modules
      @@all_classes.values + @@all_modules.values
    end

    def TopLevel.find_class_named(name)
     @@all_classes.each_value do |c|
        res = c.find_class_named(name) 
        return res if res
      end
      nil
    end

    def find_local_symbol(symbol)
      find_class_or_module_named(symbol) || super
    end

    def find_class_or_module_named(symbol)
      @@all_classes.each_value {|c| return c if c.name == symbol}
      @@all_modules.each_value {|m| return m if m.name == symbol}
      nil
    end

    # Find a named module
    def find_module_named(name)
      find_class_or_module_named(name) || find_enclosing_module_named(name)
    end


  end

  # ClassModule is the base class for objects representing either a
  # class or a module.

  class ClassModule < Context

    attr_reader   :superclass
    attr_accessor :diagram

    def initialize(name, superclass = nil)
      @name       = name
      @diagram    = nil
      @superclass = superclass
      @comment    = ""
      super()
    end

    # Return the fully qualified name of this class or module
    def full_name
      if @parent && @parent.full_name
        @parent.full_name + "::" + @name
      else
        @name
      end
    end

    def http_url(prefix)
      path = full_name.split("::")
      File.join(prefix, *path) + ".html"
    end

    # Return +true+ if this object represents a module
    def is_module?
      false
    end

    # to_s is simply for debugging
    def to_s
      res = self.class.name + ": " + @name 
      res << @comment.to_s
      res << super
      res
    end

    def find_class_named(name)
      return self if full_name == name
      @classes.each_value {|c| return c if c.find_class_named(name) }
      nil
    end
  end

  # Anonymous classes
  class AnonClass < ClassModule
  end

  # Normal classes
  class NormalClass < ClassModule
  end

  # Singleton classes
  class SingleClass < ClassModule
  end

  # Module
  class NormalModule < ClassModule
    def is_module?
      true
    end
  end


  # AnyMethod is the base class for objects representing methods

  class AnyMethod < CodeObject
    attr_accessor :name
    attr_accessor :visibility
    attr_accessor :block_params
    attr_accessor :dont_rename_initialize
    attr_accessor :singleton
    attr_reader   :aliases           # list of other names for this method
    attr_accessor :is_alias_for      # or a method we're aliasing

    attr_overridable :params, :param, :parameters, :parameter

    attr_accessor :call_seq


    include TokenStream

    def initialize(text, name)
      super()
      @text = text
      @name = name
      @token_stream  = nil
      @visibility    = :public
      @dont_rename_initialize = false
      @block_params  = nil
      @aliases       = []
      @is_alias_for  = nil
      @comment = ""
      @call_seq = nil
    end

    def <=>(other)
      @name <=> other.name
    end

    def to_s
      res = self.class.name + ": " + @name + " (" + @text + ")\n"
      res << @comment.to_s
      res
    end

    def param_seq
      p = params.gsub(/\s*\#.*/, '')
      p = p.tr("\n", " ").squeeze(" ")
      p = "(" + p + ")" unless p[0] == ?(

      if (block = block_params)
        # If this method has explicit block parameters, remove any
        # explicit &block
$stderr.puts p
        p.sub!(/,?\s*&\w+/)
$stderr.puts p

        block.gsub!(/\s*\#.*/, '')
        block = block.tr("\n", " ").squeeze(" ")
        if block[0] == ?(
          block.sub!(/^\(/, '').sub!(/\)/, '')
        end
        p << " {|#{block}| ...}"
      end
      p
    end

    def add_alias(method)
      @aliases << method
    end
  end


  # Represent an alias, which is an old_name/ new_name pair associated
  # with a particular context
  class Alias < CodeObject
    attr_accessor :text, :old_name, :new_name, :comment
    
    def initialize(text, old_name, new_name, comment)
      super()
      @text = text
      @old_name = old_name
      @new_name = new_name
      self.comment = comment
    end

    def to_s
      "alias: #{self.old_name} ->  #{self.new_name}\n#{self.comment}"
    end
  end

  # Represent a constant
  class Constant < CodeObject
    attr_accessor :name, :value

    def initialize(name, value, comment)
      super()
      @name = name
      @value = value
      self.comment = comment
    end
  end

  # Represent attributes
  class Attr < CodeObject
    attr_accessor :text, :name, :rw, :visibility

    def initialize(text, name, rw, comment)
      super()
      @text = text
      @name = name
      @rw = rw
      @visibility = :public
      self.comment = comment
    end

    def to_s
      "attr: #{self.name} #{self.rw}\n#{self.comment}"
    end

    def <=>(other)
      self.name <=> other.name
    end
  end

  # a required file

  class Require < CodeObject
    attr_accessor :name

    def initialize(name, comment)
      super()
      @name = name.gsub(/'|"/, "") #'
      self.comment = comment
    end

  end

  # an included module
  class Include < CodeObject
    attr_accessor :name

    def initialize(name, comment)
      super()
      @name = name
      self.comment = comment
    end

  end

end
PK     Z\sp-  -  $  rdoc/markup/simple_markup/to_html.rbnu [        require 'rdoc/markup/simple_markup/fragments'
require 'rdoc/markup/simple_markup/inline'

require 'cgi'

module SM

  class ToHtml

    LIST_TYPE_TO_HTML = {
      ListBase::BULLET =>  [ "<ul>", "</ul>" ],
      ListBase::NUMBER =>  [ "<ol>", "</ol>" ],
      ListBase::UPPERALPHA =>  [ "<ol>", "</ol>" ],
      ListBase::LOWERALPHA =>  [ "<ol>", "</ol>" ],
      ListBase::LABELED => [ "<dl>", "</dl>" ],
      ListBase::NOTE    => [ "<table>", "</table>" ],
    }

    InlineTag = Struct.new(:bit, :on, :off)

    def initialize
      init_tags
    end

    ##
    # Set up the standard mapping of attributes to HTML tags
    #
    def init_tags
      @attr_tags = [
        InlineTag.new(SM::Attribute.bitmap_for(:BOLD), "<b>", "</b>"),
        InlineTag.new(SM::Attribute.bitmap_for(:TT),   "<tt>", "</tt>"),
        InlineTag.new(SM::Attribute.bitmap_for(:EM),   "<em>", "</em>"),
      ]
    end

    ##
    # Add a new set of HTML tags for an attribute. We allow
    # separate start and end tags for flexibility
    #
    def add_tag(name, start, stop)
      @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop)
    end

    ##
    # Given an HTML tag, decorate it with class information
    # and the like if required. This is a no-op in the base
    # class, but is overridden in HTML output classes that
    # implement style sheets

    def annotate(tag)
      tag
    end

    ## 
    # Here's the client side of the visitor pattern

    def start_accepting
      @res = ""
      @in_list_entry = []
    end

    def end_accepting
      @res
    end

    def accept_paragraph(am, fragment)
      @res << annotate("<p>") + "\n"
      @res << wrap(convert_flow(am.flow(fragment.txt)))
      @res << annotate("</p>") + "\n"
    end

    def accept_verbatim(am, fragment)
      @res << annotate("<pre>") + "\n"
      @res << CGI.escapeHTML(fragment.txt)
      @res << annotate("</pre>") << "\n"
    end

    def accept_rule(am, fragment)
      size = fragment.param
      size = 10 if size > 10
      @res << "<hr size=\"#{size}\"></hr>"
    end

    def accept_list_start(am, fragment)
      @res << html_list_name(fragment.type, true) <<"\n"
      @in_list_entry.push false
    end

    def accept_list_end(am, fragment)
      if tag = @in_list_entry.pop
        @res << annotate(tag) << "\n"
      end
      @res << html_list_name(fragment.type, false) <<"\n"
    end

    def accept_list_item(am, fragment)
      if tag = @in_list_entry.last
        @res << annotate(tag) << "\n"
      end
      @res << list_item_start(am, fragment)
      @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n"
      @in_list_entry[-1] = list_end_for(fragment.type)
    end

    def accept_blank_line(am, fragment)
      # @res << annotate("<p />") << "\n"
    end

    def accept_heading(am, fragment)
      @res << convert_heading(fragment.head_level, am.flow(fragment.txt))
    end

    # This is a higher speed (if messier) version of wrap

    def wrap(txt, line_len = 76)
      res = ""
      sp = 0
      ep = txt.length
      while sp < ep
        # scan back for a space
        p = sp + line_len - 1
        if p >= ep
          p = ep
        else
          while p > sp and txt[p] != ?\s
            p -= 1
          end
          if p <= sp
            p = sp + line_len
            while p < ep and txt[p] != ?\s
              p += 1
            end
          end
        end
        res << txt[sp...p] << "\n"
        sp = p
        sp += 1 while sp < ep and txt[sp] == ?\s
      end
      res
    end

    #######################################################################

    private

    #######################################################################

    def on_tags(res, item)
      attr_mask = item.turn_on
      return if attr_mask.zero?

      @attr_tags.each do |tag|
        if attr_mask & tag.bit != 0
          res << annotate(tag.on)
        end
      end
    end

    def off_tags(res, item)
      attr_mask = item.turn_off
      return if attr_mask.zero?

      @attr_tags.reverse_each do |tag|
        if attr_mask & tag.bit != 0
          res << annotate(tag.off)
        end
      end
    end

    def convert_flow(flow)
      res = ""
      flow.each do |item|
        case item
        when String
          res << convert_string(item)
        when AttrChanger
          off_tags(res, item)
          on_tags(res,  item)
        when Special
          res << convert_special(item)
        else
          raise "Unknown flow element: #{item.inspect}"
        end
      end
      res
    end

    # some of these patterns are taken from SmartyPants...

    def convert_string(item)
      CGI.escapeHTML(item).
      
      
      # convert -- to em-dash, (-- to en-dash)
        gsub(/---?/, '&#8212;'). #gsub(/--/, '&#8211;').

      # convert ... to elipsis (and make sure .... becomes .<elipsis>)
        gsub(/\.\.\.\./, '.&#8230;').gsub(/\.\.\./, '&#8230;').

      # convert single closing quote
        gsub(%r{([^ \t\r\n\[\{\(])\'}) { "#$1&#8217;" }.
        gsub(%r{\'(?=\W|s\b)}) { "&#8217;" }.

      # convert single opening quote
        gsub(/'/, '&#8216;').

      # convert double closing quote
        gsub(%r{([^ \t\r\n\[\{\(])\'(?=\W)}) { "#$1&#8221;" }.

      # convert double opening quote
        gsub(/'/, '&#8220;').

      # convert copyright
        gsub(/\(c\)/, '&#169;').

      # convert and registered trademark
        gsub(/\(r\)/, '&#174;')

    end

    def convert_special(special)
      handled = false
      Attribute.each_name_of(special.type) do |name|
        method_name = "handle_special_#{name}"
        if self.respond_to? method_name
          special.text = send(method_name, special)
          handled = true
        end
      end
      raise "Unhandled special: #{special}" unless handled
      special.text
    end

    def convert_heading(level, flow)
      res =
        annotate("<h#{level}>") + 
        convert_flow(flow) + 
        annotate("</h#{level}>\n")
    end

    def html_list_name(list_type, is_open_tag)
      tags = LIST_TYPE_TO_HTML[list_type] || raise("Invalid list type: #{list_type.inspect}")
      annotate(tags[ is_open_tag ? 0 : 1])
    end

    def list_item_start(am, fragment)
      case fragment.type
      when ListBase::BULLET, ListBase::NUMBER
        annotate("<li>")

      when ListBase::UPPERALPHA
	annotate("<li type=\"A\">")

      when ListBase::LOWERALPHA
	annotate("<li type=\"a\">")

      when ListBase::LABELED
        annotate("<dt>") +
          convert_flow(am.flow(fragment.param)) + 
          annotate("</dt>") +
          annotate("<dd>")

      when ListBase::NOTE
        annotate("<tr>") +
          annotate("<td valign=\"top\">") +
          convert_flow(am.flow(fragment.param)) + 
          annotate("</td>") +
          annotate("<td>")
      else
        raise "Invalid list type"
      end
    end

    def list_end_for(fragment_type)
      case fragment_type
      when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA, ListBase::LOWERALPHA
        "</li>"
      when ListBase::LABELED
        "</dd>"
      when ListBase::NOTE
        "</td></tr>"
      else
        raise "Invalid list type"
      end
    end

  end

end
PK     Z\)    &  rdoc/markup/simple_markup/fragments.rbnu [        require 'rdoc/markup/simple_markup/lines.rb'
#require 'rdoc/markup/simple_markup/to_flow.rb'

module SM

  ##
  # A Fragment is a chunk of text, subclassed as a paragraph, a list
  # entry, or verbatim text

  class Fragment
    attr_reader   :level, :param, :txt
    attr_accessor :type

    def initialize(level, param, type, txt)
      @level = level
      @param = param
      @type  = type
      @txt   = ""
      add_text(txt) if txt
    end

    def add_text(txt)
      @txt << " " if @txt.length > 0
      @txt << txt.tr_s("\n ", "  ").strip
    end

    def to_s
      "L#@level: #{self.class.name.split('::')[-1]}\n#@txt"
    end

    ######
    # This is a simple factory system that lets us associate fragement
    # types (a string) with a subclass of fragment

    TYPE_MAP = {}

    def Fragment.type_name(name)
      TYPE_MAP[name] = self
    end

    def Fragment.for(line)
      klass =  TYPE_MAP[line.type] ||
        raise("Unknown line type: '#{line.type.inspect}:' '#{line.text}'")
      return klass.new(line.level, line.param, line.flag, line.text)
    end
  end

  ##
  # A paragraph is a fragment which gets wrapped to fit. We remove all
  # newlines when we're created, and have them put back on output

  class Paragraph < Fragment
    type_name Line::PARAGRAPH
  end

  class BlankLine < Paragraph
    type_name Line::BLANK
  end

  class Heading < Paragraph
    type_name Line::HEADING

    def head_level
      @param.to_i
    end
  end

  ##
  # A List is a fragment with some kind of label
  #

  class ListBase < Paragraph
    # List types
    BULLET  = :BULLET
    NUMBER  = :NUMBER
    UPPERALPHA  = :UPPERALPHA
    LOWERALPHA  = :LOWERALPHA
    LABELED = :LABELED
    NOTE    = :NOTE
  end

  class ListItem < ListBase
    type_name Line::LIST

    #  def label
    #    am = AttributeManager.new(@param)
    #    am.flow
    #  end
  end

  class ListStart < ListBase
    def initialize(level, param, type)
      super(level, param, type, nil)
    end
  end

  class ListEnd < ListBase
    def initialize(level, type)
      super(level, "", type, nil)
    end
  end

  ##
  # Verbatim code contains lines that don't get wrapped.

  class Verbatim < Fragment
    type_name  Line::VERBATIM

    def add_text(txt)
      @txt << txt.chomp << "\n"
    end

  end

  ##
  # A horizontal rule
  class Rule < Fragment
    type_name Line::RULE
  end


  # Collect groups of lines together. Each group
  # will end up containing a flow of text

  class LineCollection
    
    def initialize
      @fragments = []
    end

    def add(fragment)
      @fragments << fragment
    end

    def each(&b)
      @fragments.each(&b)
    end

    # For testing
    def to_a
      @fragments.map {|fragment| fragment.to_s}
    end

    # Factory for different fragment types
    def fragment_for(*args)
      Fragment.for(*args)
    end

    # tidy up at the end
    def normalize
      change_verbatim_blank_lines
      add_list_start_and_ends
      add_list_breaks
      tidy_blank_lines
    end

    def to_s
      @fragments.join("\n----\n")
    end

    def accept(am, visitor)

      visitor.start_accepting

      @fragments.each do |fragment|
        case fragment
        when Verbatim
          visitor.accept_verbatim(am, fragment)
        when Rule
          visitor.accept_rule(am, fragment)
        when ListStart
          visitor.accept_list_start(am, fragment)
        when ListEnd
          visitor.accept_list_end(am, fragment)
        when ListItem
          visitor.accept_list_item(am, fragment)
        when BlankLine
          visitor.accept_blank_line(am, fragment)
        when Heading
          visitor.accept_heading(am, fragment)
        when Paragraph
          visitor.accept_paragraph(am, fragment)
        end
      end

      visitor.end_accepting
    end
    #######
    private
    #######

    # If you have:
    #
    #    normal paragraph text.
    #
    #       this is code
    #   
    #       and more code
    #
    # You'll end up with the fragments Paragraph, BlankLine, 
    # Verbatim, BlankLine, Verbatim, BlankLine, etc
    #
    # The BlankLine in the middle of the verbatim chunk needs to
    # be changed to a real verbatim newline, and the two
    # verbatim blocks merged
    #
    #    
    def change_verbatim_blank_lines
      frag_block = nil
      blank_count = 0
      @fragments.each_with_index do |frag, i|
        if frag_block.nil?
          frag_block = frag if Verbatim === frag
        else
          case frag
          when Verbatim
            blank_count.times { frag_block.add_text("\n") }
            blank_count = 0
            frag_block.add_text(frag.txt)
            @fragments[i] = nil    # remove out current fragment
          when BlankLine
            if frag_block
              blank_count += 1
              @fragments[i] = nil
            end
          else
            frag_block = nil
            blank_count = 0
          end
        end
      end
      @fragments.compact!
    end

    # List nesting is implicit given the level of
    # Make it explicit, just to make life a tad
    # easier for the output processors

    def add_list_start_and_ends
      level = 0
      res = []
      type_stack = []

      @fragments.each do |fragment|
        # $stderr.puts "#{level} : #{fragment.class.name} : #{fragment.level}"
        new_level = fragment.level
        while (level < new_level)
          level += 1
          type = fragment.type
          res << ListStart.new(level, fragment.param, type) if type
          type_stack.push type
          # $stderr.puts "Start: #{level}"
        end

        while level > new_level
          type = type_stack.pop
          res << ListEnd.new(level, type) if type
          level -= 1
          # $stderr.puts "End: #{level}, #{type}"
        end

        res << fragment
        level = fragment.level
      end
      level.downto(1) do |i|
        type = type_stack.pop
        res << ListEnd.new(i, type) if type
      end

      @fragments = res
    end

    # now insert start/ends between list entries at the
    # same level that have different element types

    def add_list_breaks
      res = @fragments

      @fragments = []
      list_stack = []

      res.each do |fragment|
        case fragment
        when ListStart
          list_stack.push fragment
        when ListEnd
          start = list_stack.pop
          fragment.type = start.type
        when ListItem
          l = list_stack.last
          if fragment.type != l.type
            @fragments << ListEnd.new(l.level, l.type)
            start = ListStart.new(l.level, fragment.param, fragment.type)
            @fragments << start
            list_stack.pop
            list_stack.push start
          end
        else
          ;
        end
        @fragments << fragment
      end
    end

    # Finally tidy up the blank lines:
    # * change Blank/ListEnd into ListEnd/Blank
    # * remove blank lines at the front

    def tidy_blank_lines
      (@fragments.size - 1).times do |i|
        if @fragments[i].kind_of?(BlankLine) and 
            @fragments[i+1].kind_of?(ListEnd)
          @fragments[i], @fragments[i+1] = @fragments[i+1], @fragments[i] 
        end
      end

      # remove leading blanks
      @fragments.each_with_index do |f, i|
        break unless f.kind_of? BlankLine
        @fragments[i] = nil
      end

      @fragments.compact!
    end

  end
  
end
PK     Z\ "   "  #  rdoc/markup/simple_markup/inline.rbnu [        module SM

  # We manage a set of attributes. Each attribute has a symbol name
  # and a bit value

  class Attribute
    SPECIAL = 1

    @@name_to_bitmap = { :_SPECIAL_ => SPECIAL }
    @@next_bitmap = 2

    def Attribute.bitmap_for(name)
      bitmap = @@name_to_bitmap[name]
      if !bitmap
        bitmap = @@next_bitmap
        @@next_bitmap <<= 1
        @@name_to_bitmap[name] = bitmap
      end
      bitmap
    end

    def Attribute.as_string(bitmap)
      return "none" if bitmap.zero?
      res = []
      @@name_to_bitmap.each do |name, bit|
        res << name if (bitmap & bit) != 0
      end
      res.join(",")
    end

    def Attribute.each_name_of(bitmap)
      @@name_to_bitmap.each do |name, bit|
        next if bit == SPECIAL
        yield name.to_s if (bitmap & bit) != 0
      end
    end
  end


  # An AttrChanger records a change in attributes. It contains
  # a bitmap of the attributes to turn on, and a bitmap of those to
  # turn off

  AttrChanger = Struct.new(:turn_on, :turn_off)
  class AttrChanger
    def to_s
      "Attr: +#{Attribute.as_string(@turn_on)}/-#{Attribute.as_string(@turn_on)}"
    end
  end

  # An array of attributes which parallels the characters in a string
  class AttrSpan
    def initialize(length)
      @attrs = Array.new(length, 0)
    end

    def set_attrs(start, length, bits)
      for i in start ... (start+length)
        @attrs[i] |= bits
      end
    end

    def [](n)
      @attrs[n]
    end
  end

  ##
  # Hold details of a special sequence

  class Special
    attr_reader   :type
    attr_accessor :text

    def initialize(type, text)
      @type, @text = type, text
    end

    def ==(o)
      self.text == o.text && self.type == o.type
    end

    def to_s
      "Special: type=#{type}, text=#{text.dump}"
    end
  end
  
  class AttributeManager

    NULL = "\000".freeze

    ##
    # We work by substituting non-printing characters in to the
    # text. For now I'm assuming that I can substitute
    # a character in the range 0..8 for a 7 bit character
    # without damaging the encoded string, but this might
    # be optimistic
    #

    A_PROTECT  = 004
    PROTECT_ATTR  = A_PROTECT.chr

    # This maps delimiters that occur around words (such as
    # *bold* or +tt+) where the start and end delimiters
    # and the same. This lets us optimize the regexp
    MATCHING_WORD_PAIRS = {}

    # And this is used when the delimiters aren't the same. In this
    # case the hash maps a pattern to the attribute character
    WORD_PAIR_MAP = {}

    # This maps HTML tags to the corresponding attribute char
    HTML_TAGS = {}

    # And this maps _special_ sequences to a name. A special sequence
    # is something like a WikiWord
    SPECIAL = {}

    # Return an attribute object with the given turn_on
    # and turn_off bits set

    def attribute(turn_on, turn_off)
      AttrChanger.new(turn_on, turn_off)
    end


    def change_attribute(current, new)
      diff = current ^ new
      attribute(new & diff, current & diff)
    end

    def changed_attribute_by_name(current_set, new_set)
      current = new = 0
      current_set.each {|name| current |= Attribute.bitmap_for(name) }
      new_set.each {|name| new |= Attribute.bitmap_for(name) }
      change_attribute(current, new)
    end

    def copy_string(start_pos, end_pos)
      res = @str[start_pos...end_pos]
      res.gsub!(/\000/, '')
      res
    end

    # Map attributes like <b>text</b>to the sequence \001\002<char>\001\003<char>,
    # where <char> is a per-attribute specific character

    def convert_attrs(str, attrs)
      # first do matching ones
      tags = MATCHING_WORD_PAIRS.keys.join("")
      re = "(^|\\W)([#{tags}])([A-Za-z_]+?)\\2(\\W|\$)"
#      re = "(^|\\W)([#{tags}])(\\S+?)\\2(\\W|\$)"
      1 while str.gsub!(Regexp.new(re)) {
        attr = MATCHING_WORD_PAIRS[$2];
        attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr)
        $1 + NULL*$2.length + $3 + NULL*$2.length + $4
      }

      # then non-matching
      unless WORD_PAIR_MAP.empty?
        WORD_PAIR_MAP.each do |regexp, attr|
          str.gsub!(regexp) { 
            attrs.set_attrs($`.length + $1.length, $2.length, attr)
            NULL*$1.length + $2 + NULL*$3.length
          }
        end
      end
    end

    def convert_html(str, attrs)
      tags = HTML_TAGS.keys.join("|")
      re = "<(#{tags})>(.*?)</\\1>"
      1 while str.gsub!(Regexp.new(re, Regexp::IGNORECASE)) {
        attr = HTML_TAGS[$1.downcase]
        html_length = $1.length + 2
        seq = NULL * html_length
        attrs.set_attrs($`.length + html_length, $2.length, attr)
        seq + $2 + seq + NULL
      }
    end

    def convert_specials(str, attrs)
      unless SPECIAL.empty?
        SPECIAL.each do |regexp, attr|
          str.scan(regexp) do
            attrs.set_attrs($`.length, $&.length, attr | Attribute::SPECIAL)
          end
        end
      end
    end

    # A \ in front of a character that would normally be
    # processed turns off processing. We do this by turning
    # \< into <#{PROTECT}
    
    PROTECTABLE = [ "<" << "\\" ]  #"


    def mask_protected_sequences
      protect_pattern = Regexp.new("\\\\([#{Regexp.escape(PROTECTABLE.join(''))}])")
      @str.gsub!(protect_pattern, "\\1#{PROTECT_ATTR}")
    end

    def unmask_protected_sequences
      @str.gsub!(/(.)#{PROTECT_ATTR}/, "\\1\000")
    end

    def initialize
      add_word_pair("*", "*", :BOLD)
      add_word_pair("_", "_", :EM)
      add_word_pair("+", "+", :TT)
      
      add_html("em", :EM)
      add_html("i",  :EM)
      add_html("b",  :BOLD)
      add_html("tt",   :TT)
      add_html("code", :TT)

      add_special(/<!--(.*?)-->/, :COMMENT)
    end

    def add_word_pair(start, stop, name)
      raise "Word flags may not start '<'" if start[0] == ?<
      bitmap = Attribute.bitmap_for(name)
      if start == stop
        MATCHING_WORD_PAIRS[start] = bitmap
      else
        pattern = Regexp.new("(" + Regexp.escape(start) + ")" +
#                             "([A-Za-z]+)" +
                             "(\\S+)" +
                             "(" + Regexp.escape(stop) +")")
        WORD_PAIR_MAP[pattern] = bitmap
      end
      PROTECTABLE << start[0,1]
      PROTECTABLE.uniq!
    end

    def add_html(tag, name)
      HTML_TAGS[tag.downcase] = Attribute.bitmap_for(name)
    end

    def add_special(pattern, name)
      SPECIAL[pattern] = Attribute.bitmap_for(name)
    end

    def flow(str)
      @str = str

      puts("Before flow, str='#{@str.dump}'") if $DEBUG
      mask_protected_sequences
 
      @attrs = AttrSpan.new(@str.length)

      puts("After protecting, str='#{@str.dump}'") if $DEBUG
      convert_attrs(@str, @attrs)
      convert_html(@str, @attrs)
      convert_specials(str, @attrs)
      unmask_protected_sequences
      puts("After flow, str='#{@str.dump}'") if $DEBUG
      return split_into_flow
    end

    def display_attributes
      puts
      puts @str.tr(NULL, "!")
      bit = 1
      16.times do |bno|
        line = ""
        @str.length.times do |i|
          if (@attrs[i] & bit) == 0
            line << " "
          else
            if bno.zero?
              line << "S"
            else
              line << ("%d" % (bno+1))
            end
          end
        end
        puts(line) unless line =~ /^ *$/
        bit <<= 1
      end
    end

    def split_into_flow

      display_attributes if $DEBUG

      res = []
      current_attr = 0
      str = ""

      
      str_len = @str.length

      # skip leading invisible text
      i = 0
      i += 1 while i < str_len and @str[i].zero?
      start_pos = i

      # then scan the string, chunking it on attribute changes
      while i < str_len
        new_attr = @attrs[i]
        if new_attr != current_attr
          if i > start_pos
            res << copy_string(start_pos, i)
            start_pos = i
          end

          res << change_attribute(current_attr, new_attr)
          current_attr = new_attr

          if (current_attr & Attribute::SPECIAL) != 0
            i += 1 while i < str_len and (@attrs[i] & Attribute::SPECIAL) != 0
            res << Special.new(current_attr, copy_string(start_pos, i))
            start_pos = i
            next
          end
        end

        # move on, skipping any invisible characters
        begin
          i += 1
        end while i < str_len and @str[i].zero?
      end
      
      # tidy up trailing text
      if start_pos < str_len
        res << copy_string(start_pos, str_len)
      end

      # and reset to all attributes off
      res << change_attribute(current_attr, 0) if current_attr != 0

      return res
    end

  end

end
PK     Z\Vڹ    '  rdoc/markup/simple_markup/preprocess.rbnu [        module SM

  ## 
  # Handle common directives that can occur in a block of text:
  #
  # : include : filename
  #

  class PreProcess

    def initialize(input_file_name, include_path)
      @input_file_name = input_file_name
      @include_path = include_path
    end

    # Look for common options in a chunk of text. Options that
    # we don't handle are passed back to our caller
    # as |directive, param| 

    def handle(text)
      text.gsub!(/^([ \t#]*):(\w+):\s*(.+)?\n/) do 
        prefix    = $1
        directive = $2.downcase
        param     = $3

        case directive
        when "include"
          filename = param.split[0]
          include_file(filename, prefix)

        else
          yield(directive, param)
        end
      end
    end

    #######
    private
    #######

    # Include a file, indenting it correctly

    def include_file(name, indent)
      if (full_name = find_include_file(name))
        content = File.open(full_name) {|f| f.read}
        # strip leading '#'s, but only if all lines start with them
        if content =~ /^[^#]/
          content.gsub(/^/, indent)
        else
          content.gsub(/^#?/, indent)
        end
      else
        $stderr.puts "Couldn't find file to include: '#{name}'"
        ''
      end
    end

    # Look for the given file in the directory containing the current
    # file, and then in each of the directories specified in the
    # RDOC_INCLUDE path

    def find_include_file(name)
      to_search = [ File.dirname(@input_file_name) ].concat @include_path
      to_search.each do |dir|
        full_name = File.join(dir, name)
        stat = File.stat(full_name) rescue next
        return full_name if stat.readable?
      end
      nil
    end

  end
end
PK     Z\k    "  rdoc/markup/simple_markup/lines.rbnu [        ##########################################################################
#
# We store the lines we're working on as objects of class Line.
# These contain the text of the line, along with a flag indicating the
# line type, and an indentation level

module SM

  class Line
    INFINITY = 9999

    BLANK     = :BLANK
    HEADING   = :HEADING
    LIST      = :LIST
    RULE      = :RULE
    PARAGRAPH = :PARAGRAPH
    VERBATIM  = :VERBATIM
    
    # line type
    attr_accessor :type

    # The indentation nesting level
    attr_accessor :level

    # The contents
    attr_accessor :text

    # A prefix or parameter. For LIST lines, this is
    # the text that introduced the list item (the label)
    attr_accessor  :param

    # A flag. For list lines, this is the type of the list
    attr_accessor :flag

    # the number of leading spaces
    attr_accessor :leading_spaces

    # true if this line has been deleted from the list of lines
    attr_accessor :deleted
    

    def initialize(text)
      @text    = text.dup
      @deleted = false

      # expand tabs
      1 while @text.gsub!(/\t+/) { ' ' * (8*$&.length - $`.length % 8)}  && $~ #`

      # Strip trailing whitespace
      @text.sub!(/\s+$/, '')

      # and look for leading whitespace
      if @text.length > 0
        @text =~ /^(\s*)/
        @leading_spaces = $1.length
      else
        @leading_spaces = INFINITY
      end
    end

    # Return true if this line is blank
    def isBlank?
      @text.length.zero?
    end

    # stamp a line with a type, a level, a prefix, and a flag
    def stamp(type, level, param="", flag=nil)
      @type, @level, @param, @flag = type, level, param, flag
    end

    ##
    # Strip off the leading margin
    #

    def strip_leading(size)
      if @text.size > size
        @text[0,size] = ""
      else
        @text = ""
      end
    end

    def to_s
      "#@type#@level: #@text"
    end
  end

  ###############################################################################
  #
  # A container for all the lines
  #

  class Lines
    include Enumerable

    attr_reader :lines   # for debugging

    def initialize(lines)
      @lines = lines
      rewind
    end

    def empty?
      @lines.size.zero?
    end

    def each
      @lines.each do |line|
        yield line unless line.deleted
      end
    end

#    def [](index)
#      @lines[index]
#    end

    def rewind
      @nextline = 0
    end

    def next
      begin
        res = @lines[@nextline]
        @nextline += 1 if @nextline < @lines.size
      end while res and res.deleted and @nextline < @lines.size
      res
    end

    def unget
      @nextline -= 1
    end

    def delete(a_line)
      a_line.deleted = true
    end

    def normalize
      margin = @lines.collect{|l| l.leading_spaces}.min
      margin = 0 if margin == Line::INFINITY
      @lines.each {|line| line.strip_leading(margin) } if margin > 0
    end

    def as_text
      @lines.map {|l| l.text}.join("\n")
    end

    def line_types
      @lines.map {|l| l.type }
    end
  end
end
PK     Z\8a U~  ~  $  rdoc/markup/simple_markup/to_flow.rbnu [        require 'rdoc/markup/simple_markup/fragments'
require 'rdoc/markup/simple_markup/inline'
require 'cgi'

module SM

  module Flow
    P = Struct.new(:body)
    VERB = Struct.new(:body)
    RULE = Struct.new(:width)
    class LIST
      attr_reader :type, :contents
      def initialize(type)
        @type = type
        @contents = []
      end
      def <<(stuff)
        @contents << stuff
      end
    end
    LI = Struct.new(:label, :body)
    H = Struct.new(:level, :text)
  end

  class ToFlow
    LIST_TYPE_TO_HTML = {
      SM::ListBase::BULLET     =>  [ "<ul>", "</ul>" ],
      SM::ListBase::NUMBER     =>  [ "<ol>", "</ol>" ],
      SM::ListBase::UPPERALPHA =>  [ "<ol>", "</ol>" ],
      SM::ListBase::LOWERALPHA =>  [ "<ol>", "</ol>" ],
      SM::ListBase::LABELED    =>  [ "<dl>", "</dl>" ],
      SM::ListBase::NOTE       =>  [ "<table>", "</table>" ],
    }

    InlineTag = Struct.new(:bit, :on, :off)

    def initialize
      init_tags
    end

    ##
    # Set up the standard mapping of attributes to HTML tags
    #
    def init_tags
      @attr_tags = [
        InlineTag.new(SM::Attribute.bitmap_for(:BOLD), "<b>", "</b>"),
        InlineTag.new(SM::Attribute.bitmap_for(:TT),   "<tt>", "</tt>"),
        InlineTag.new(SM::Attribute.bitmap_for(:EM),   "<em>", "</em>"),
      ]
    end

    ##
    # Add a new set of HTML tags for an attribute. We allow
    # separate start and end tags for flexibility
    #
    def add_tag(name, start, stop)
      @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop)
    end

    ##
    # Given an HTML tag, decorate it with class information
    # and the like if required. This is a no-op in the base
    # class, but is overridden in HTML output classes that
    # implement style sheets

    def annotate(tag)
      tag
    end

    ## 
    # Here's the client side of the visitor pattern

    def start_accepting
      @res = []
      @list_stack = []
    end

    def end_accepting
      @res
    end

    def accept_paragraph(am, fragment)
      @res << Flow::P.new((convert_flow(am.flow(fragment.txt))))
    end

    def accept_verbatim(am, fragment)
      @res << Flow::VERB.new((convert_flow(am.flow(fragment.txt))))
    end

    def accept_rule(am, fragment)
      size = fragment.param
      size = 10 if size > 10
      @res << Flow::RULE.new(size)
    end

    def accept_list_start(am, fragment)
      @list_stack.push(@res)
      list = Flow::LIST.new(fragment.type)
      @res << list
      @res = list
    end

    def accept_list_end(am, fragment)
      @res = @list_stack.pop
    end

    def accept_list_item(am, fragment)
      @res << Flow::LI.new(fragment.param, convert_flow(am.flow(fragment.txt)))
    end

    def accept_blank_line(am, fragment)
      # @res << annotate("<p />") << "\n"
    end

    def accept_heading(am, fragment)
      @res << Flow::H.new(fragment.head_level, convert_flow(am.flow(fragment.txt)))
    end


    #######################################################################

    private

    #######################################################################

    def on_tags(res, item)
      attr_mask = item.turn_on
      return if attr_mask.zero?

      @attr_tags.each do |tag|
        if attr_mask & tag.bit != 0
          res << annotate(tag.on)
        end
      end
    end

    def off_tags(res, item)
      attr_mask = item.turn_off
      return if attr_mask.zero?

      @attr_tags.reverse_each do |tag|
        if attr_mask & tag.bit != 0
          res << annotate(tag.off)
        end
      end
    end

    def convert_flow(flow)
      res = ""
      flow.each do |item|
        case item
        when String
          res << convert_string(item)
        when AttrChanger
          off_tags(res, item)
          on_tags(res,  item)
        when Special
          res << convert_special(item)
        else
          raise "Unknown flow element: #{item.inspect}"
        end
      end
      res
    end

    # some of these patterns are taken from SmartyPants...

    def convert_string(item)
      CGI.escapeHTML(item)
    end

    def convert_special(special)
      handled = false
      Attribute.each_name_of(special.type) do |name|
        method_name = "handle_special_#{name}"
        if self.respond_to? method_name
          special.text = send(method_name, special)
          handled = true
        end
      end
      raise "Unhandled special: #{special}" unless handled
      special.text
    end


  end

end
PK     Z\7^!  !  %  rdoc/markup/simple_markup/to_latex.rbnu [        require 'rdoc/markup/simple_markup/fragments'
require 'rdoc/markup/simple_markup/inline'

require 'cgi'

module SM

  # Convert SimpleMarkup to basic LaTeX report format

  class ToLaTeX

    BS = "\020"   # \
    OB = "\021"   # {
    CB = "\022"   # }
    DL = "\023"   # Dollar

    BACKSLASH   = "#{BS}symbol#{OB}92#{CB}"
    HAT         = "#{BS}symbol#{OB}94#{CB}"
    BACKQUOTE   = "#{BS}symbol#{OB}0#{CB}"
    TILDE       = "#{DL}#{BS}sim#{DL}"
    LESSTHAN    = "#{DL}<#{DL}"
    GREATERTHAN = "#{DL}>#{DL}"

    def self.l(str)
      str.tr('\\', BS).tr('{', OB).tr('}', CB).tr('$', DL)
    end

    def l(arg)
      SM::ToLaTeX.l(arg)
    end

    LIST_TYPE_TO_LATEX = {
      ListBase::BULLET =>  [ l("\\begin{itemize}"), l("\\end{itemize}") ],
      ListBase::NUMBER =>  [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\arabic" ],
      ListBase::UPPERALPHA =>  [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\Alph" ],
      ListBase::LOWERALPHA =>  [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\alph" ],
      ListBase::LABELED => [ l("\\begin{description}"), l("\\end{description}") ],
      ListBase::NOTE    => [
        l("\\begin{tabularx}{\\linewidth}{@{} l X @{}}"), 
        l("\\end{tabularx}") ],
    }

    InlineTag = Struct.new(:bit, :on, :off)

    def initialize
      init_tags
      @list_depth = 0
      @prev_list_types = []
    end

    ##
    # Set up the standard mapping of attributes to LaTeX
    #
    def init_tags
      @attr_tags = [
        InlineTag.new(SM::Attribute.bitmap_for(:BOLD), l("\\textbf{"), l("}")),
        InlineTag.new(SM::Attribute.bitmap_for(:TT),   l("\\texttt{"), l("}")),
        InlineTag.new(SM::Attribute.bitmap_for(:EM),   l("\\emph{"), l("}")),
      ]
    end

    ##
    # Escape a LaTeX string
    def escape(str)
# $stderr.print "FE: ", str
      s = str.
#        sub(/\s+$/, '').
        gsub(/([_\${}&%#])/, "#{BS}\\1").
        gsub(/\\/, BACKSLASH).
        gsub(/\^/, HAT).
        gsub(/~/,  TILDE).
        gsub(/</,  LESSTHAN).
        gsub(/>/,  GREATERTHAN).
        gsub(/,,/, ",{},").
        gsub(/\`/,  BACKQUOTE)
# $stderr.print "-> ", s, "\n"
      s
    end

    ##
    # Add a new set of LaTeX tags for an attribute. We allow
    # separate start and end tags for flexibility
    #
    def add_tag(name, start, stop)
      @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop)
    end


    ## 
    # Here's the client side of the visitor pattern

    def start_accepting
      @res = ""
      @in_list_entry = []
    end

    def end_accepting
      @res.tr(BS, '\\').tr(OB, '{').tr(CB, '}').tr(DL, '$')
    end

    def accept_paragraph(am, fragment)
      @res << wrap(convert_flow(am.flow(fragment.txt)))
      @res << "\n"
    end

    def accept_verbatim(am, fragment)
      @res << "\n\\begin{code}\n"
      @res << fragment.txt.sub(/[\n\s]+\Z/, '')
      @res << "\n\\end{code}\n\n"
    end

    def accept_rule(am, fragment)
      size = fragment.param
      size = 10 if size > 10
      @res << "\n\n\\rule{\\linewidth}{#{size}pt}\n\n"
    end

    def accept_list_start(am, fragment)
      @res << list_name(fragment.type, true) <<"\n"
      @in_list_entry.push false
    end

    def accept_list_end(am, fragment)
      if tag = @in_list_entry.pop
        @res << tag << "\n"
      end
      @res << list_name(fragment.type, false) <<"\n"
    end

    def accept_list_item(am, fragment)
      if tag = @in_list_entry.last
        @res << tag << "\n"
      end
      @res << list_item_start(am, fragment)
      @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n"
      @in_list_entry[-1] = list_end_for(fragment.type)
    end

    def accept_blank_line(am, fragment)
      # @res << "\n"
    end

    def accept_heading(am, fragment)
      @res << convert_heading(fragment.head_level, am.flow(fragment.txt))
    end

    # This is a higher speed (if messier) version of wrap

    def wrap(txt, line_len = 76)
      res = ""
      sp = 0
      ep = txt.length
      while sp < ep
        # scan back for a space
        p = sp + line_len - 1
        if p >= ep
          p = ep
        else
          while p > sp and txt[p] != ?\s
            p -= 1
          end
          if p <= sp
            p = sp + line_len
            while p < ep and txt[p] != ?\s
              p += 1
            end
          end
        end
        res << txt[sp...p] << "\n"
        sp = p
        sp += 1 while sp < ep and txt[sp] == ?\s
      end
      res
    end

    #######################################################################

    private

    #######################################################################

    def on_tags(res, item)
      attr_mask = item.turn_on
      return if attr_mask.zero?

      @attr_tags.each do |tag|
        if attr_mask & tag.bit != 0
          res << tag.on
        end
      end
    end

    def off_tags(res, item)
      attr_mask = item.turn_off
      return if attr_mask.zero?

      @attr_tags.reverse_each do |tag|
        if attr_mask & tag.bit != 0
          res << tag.off
        end
      end
    end

    def convert_flow(flow)
      res = ""
      flow.each do |item|
        case item
        when String
#          $stderr.puts "Converting '#{item}'"
          res << convert_string(item)
        when AttrChanger
          off_tags(res, item)
          on_tags(res,  item)
        when Special
          res << convert_special(item)
        else
          raise "Unknown flow element: #{item.inspect}"
        end
      end
      res
    end

    # some of these patterns are taken from SmartyPants...

    def convert_string(item)

      escape(item).
      
      
      # convert ... to elipsis (and make sure .... becomes .<elipsis>)
        gsub(/\.\.\.\./, '.\ldots{}').gsub(/\.\.\./, '\ldots{}').

      # convert single closing quote
        gsub(%r{([^ \t\r\n\[\{\(])\'}) { "#$1'" }.
        gsub(%r{\'(?=\W|s\b)}) { "'" }.

      # convert single opening quote
        gsub(/'/, '`').

      # convert double closing quote
        gsub(%r{([^ \t\r\n\[\{\(])\"(?=\W)}) { "#$1''" }.

      # convert double opening quote
        gsub(/"/, "``").

      # convert copyright
        gsub(/\(c\)/, '\copyright{}')

    end

    def convert_special(special)
      handled = false
      Attribute.each_name_of(special.type) do |name|
        method_name = "handle_special_#{name}"
        if self.respond_to? method_name
          special.text = send(method_name, special)
          handled = true
        end
      end
      raise "Unhandled special: #{special}" unless handled
      special.text
    end

    def convert_heading(level, flow)
      res =
        case level
        when 1 then "\\chapter{"
        when 2 then "\\section{"
        when 3 then "\\subsection{"
        when 4 then "\\subsubsection{"
        else  "\\paragraph{"
        end +
        convert_flow(flow) + 
        "}\n"
    end

    def list_name(list_type, is_open_tag)
      tags = LIST_TYPE_TO_LATEX[list_type] || raise("Invalid list type: #{list_type.inspect}")
      if tags[2] # enumerate
        if is_open_tag
          @list_depth += 1
          if @prev_list_types[@list_depth] != tags[2]
            case @list_depth
            when 1
              roman = "i"
            when 2
              roman = "ii"
            when 3
              roman = "iii"
            when 4
              roman = "iv"
            else
              raise("Too deep list: level #{@list_depth}")
            end
            @prev_list_types[@list_depth] = tags[2]
            return l("\\renewcommand{\\labelenum#{roman}}{#{tags[2]}{enum#{roman}}}") + "\n" + tags[0]
          end
        else
          @list_depth -= 1
        end
      end
      tags[ is_open_tag ? 0 : 1]
    end

    def list_item_start(am, fragment)
      case fragment.type
      when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA, ListBase::LOWERALPHA
        "\\item "

      when ListBase::LABELED
        "\\item[" + convert_flow(am.flow(fragment.param)) + "] "

      when ListBase::NOTE
          convert_flow(am.flow(fragment.param)) + " & "
      else
        raise "Invalid list type"
      end
    end

    def list_end_for(fragment_type)
      case fragment_type
      when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA, ListBase::LOWERALPHA, ListBase::LABELED
        ""
      when ListBase::NOTE
        "\\\\\n"
      else
        raise "Invalid list type"
      end
    end

  end

end
PK     Z\8TR8  R8    rdoc/markup/simple_markup.rbnu [        # = Introduction
#
# SimpleMarkup parses plain text documents and attempts to decompose
# them into their constituent parts. Some of these parts are high-level:
# paragraphs, chunks of verbatim text, list entries and the like. Other
# parts happen at the character level: a piece of bold text, a word in
# code font. This markup is similar in spirit to that used on WikiWiki
# webs, where folks create web pages using a simple set of formatting
# rules.
#
# SimpleMarkup itself does no output formatting: this is left to a
# different set of classes.
#
# SimpleMarkup is extendable at runtime: you can add new markup
# elements to be recognised in the documents that SimpleMarkup parses.
#
# SimpleMarkup is intended to be the basis for a family of tools which
# share the common requirement that simple, plain-text should be
# rendered in a variety of different output formats and media. It is
# envisaged that SimpleMarkup could be the basis for formating RDoc
# style comment blocks, Wiki entries, and online FAQs.
#
# = Basic Formatting
#
# * SimpleMarkup looks for a document's natural left margin. This is
#   used as the initial margin for the document.
#
# * Consecutive lines starting at this margin are considered to be a
#   paragraph.
#
# * If a paragraph starts with a "*", "-", or with "<digit>.", then it is
#   taken to be the start of a list. The margin in increased to be the
#   first non-space following the list start flag. Subsequent lines
#   should be indented to this new margin until the list ends. For
#   example:
#
#      * this is a list with three paragraphs in
#        the first item. This is the first paragraph.
#
#        And this is the second paragraph.
#
#        1. This is an indented, numbered list.
#        2. This is the second item in that list
#
#        This is the third conventional paragraph in the
#        first list item.
#
#      * This is the second item in the original list
#
# * You can also construct labeled lists, sometimes called description
#   or definition lists. Do this by putting the label in square brackets
#   and indenting the list body:
#
#       [cat]  a small furry mammal
#              that seems to sleep a lot
#
#       [ant]  a little insect that is known
#              to enjoy picnics
#
#   A minor variation on labeled lists uses two colons to separate the
#   label from the list body:
#
#       cat::  a small furry mammal
#              that seems to sleep a lot
#
#       ant::  a little insect that is known
#              to enjoy picnics
#     
#   This latter style guarantees that the list bodies' left margins are
#   aligned: think of them as a two column table.
#
# * Any line that starts to the right of the current margin is treated
#   as verbatim text. This is useful for code listings. The example of a
#   list above is also verbatim text.
#
# * A line starting with an equals sign (=) is treated as a
#   heading. Level one headings have one equals sign, level two headings
#   have two,and so on.
#
# * A line starting with three or more hyphens (at the current indent)
#   generates a horizontal rule. THe more hyphens, the thicker the rule
#   (within reason, and if supported by the output device)
#
# * You can use markup within text (except verbatim) to change the
#   appearance of parts of that text. Out of the box, SimpleMarkup
#   supports word-based and general markup.
#
#   Word-based markup uses flag characters around individual words:
#
#   [\*word*]  displays word in a *bold* font
#   [\_word_]  displays word in an _emphasized_ font
#   [\+word+]  displays word in a +code+ font
#
#   General markup affects text between a start delimiter and and end
#   delimiter. Not surprisingly, these delimiters look like HTML markup.
#
#   [\<b>text...</b>]    displays word in a *bold* font
#   [\<em>text...</em>]  displays word in an _emphasized_ font
#   [\<i>text...</i>]    displays word in an _emphasized_ font
#   [\<tt>text...</tt>]  displays word in a +code+ font
#
#   Unlike conventional Wiki markup, general markup can cross line
#   boundaries. You can turn off the interpretation of markup by
#   preceding the first character with a backslash, so \\\<b>bold
#   text</b> and \\\*bold* produce \<b>bold text</b> and \*bold
#   respectively.
#
# = Using SimpleMarkup
#
# For information on using SimpleMarkup programatically, 
# see SM::SimpleMarkup.
#
# Author::   Dave Thomas,  dave@pragmaticprogrammer.com
# Version::  0.0
# License::  Ruby license



require 'rdoc/markup/simple_markup/fragments'
require 'rdoc/markup/simple_markup/lines.rb'

module SM  #:nodoc:

  # == Synopsis
  #
  # This code converts <tt>input_string</tt>, which is in the format
  # described in markup/simple_markup.rb, to HTML. The conversion
  # takes place in the +convert+ method, so you can use the same
  # SimpleMarkup object to convert multiple input strings.
  #
  #   require 'rdoc/markup/simple_markup'
  #   require 'rdoc/markup/simple_markup/to_html'
  #
  #   p = SM::SimpleMarkup.new
  #   h = SM::ToHtml.new
  #
  #   puts p.convert(input_string, h)
  #
  # You can extend the SimpleMarkup parser to recognise new markup
  # sequences, and to add special processing for text that matches a
  # regular epxression. Here we make WikiWords significant to the parser,
  # and also make the sequences {word} and \<no>text...</no> signify
  # strike-through text. When then subclass the HTML output class to deal
  # with these:
  #
  #   require 'rdoc/markup/simple_markup'
  #   require 'rdoc/markup/simple_markup/to_html'
  #
  #   class WikiHtml < SM::ToHtml
  #     def handle_special_WIKIWORD(special)
  #       "<font color=red>" + special.text + "</font>"
  #     end
  #   end
  #
  #   p = SM::SimpleMarkup.new
  #   p.add_word_pair("{", "}", :STRIKE)
  #   p.add_html("no", :STRIKE)
  #
  #   p.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
  #
  #   h = WikiHtml.new
  #   h.add_tag(:STRIKE, "<strike>", "</strike>")
  #
  #   puts "<body>" + p.convert(ARGF.read, h) + "</body>"
  #
  # == Output Formatters
  #
  # _missing_
  #
  #

  class SimpleMarkup

    SPACE = ?\s

    # List entries look like:
    #  *       text
    #  1.      text
    #  [label] text
    #  label:: text
    #
    # Flag it as a list entry, and
    # work out the indent for subsequent lines

    SIMPLE_LIST_RE = /^(
                  (  \*          (?# bullet)
                    |-           (?# bullet)
                    |\d+\.       (?# numbered )
                    |[A-Za-z]\.  (?# alphabetically numbered )
                  )
                  \s+
                )\S/x

    LABEL_LIST_RE = /^(
                        (  \[.*?\]    (?# labeled  )
                          |\S.*::     (?# note     )
                        )(?:\s+|$)
                      )/x


    ##
    # take a block of text and use various heuristics to determine
    # it's structure (paragraphs, lists, and so on). Invoke an
    # event handler as we identify significant chunks.
    #

    def initialize
      @am = AttributeManager.new
      @output = nil
    end

    ##
    # Add to the sequences used to add formatting to an individual word 
    # (such as *bold*). Matching entries will generate attibutes
    # that the output formatters can recognize by their +name+

    def add_word_pair(start, stop, name)
      @am.add_word_pair(start, stop, name)
    end

    ##
    # Add to the sequences recognized as general markup
    #

    def add_html(tag, name)
      @am.add_html(tag, name)
    end

    ##
    # Add to other inline sequences. For example, we could add
    # WikiWords using something like:
    #
    #    parser.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
    #
    # Each wiki word will be presented to the output formatter 
    # via the accept_special method
    #

    def add_special(pattern, name)
      @am.add_special(pattern, name)
    end


    # We take a string, split it into lines, work out the type of
    # each line, and from there deduce groups of lines (for example
    # all lines in a paragraph). We then invoke the output formatter
    # using a Visitor to display the result

    def convert(str, op)
      @lines = Lines.new(str.split(/\r?\n/).collect { |aLine| 
                           Line.new(aLine) })
      return "" if @lines.empty?
      @lines.normalize
      assign_types_to_lines
      group = group_lines
      # call the output formatter to handle the result
      #      group.to_a.each {|i| p i}
      group.accept(@am, op)
    end


    #######
    private
    #######


    ##
    # Look through the text at line indentation. We flag each line as being
    # Blank, a paragraph, a list element, or verbatim text
    #

    def assign_types_to_lines(margin = 0, level = 0)

      while line = @lines.next
        if line.isBlank?
          line.stamp(Line::BLANK, level)
          next
        end
        
        # if a line contains non-blanks before the margin, then it must belong
        # to an outer level

        text = line.text
        
        for i in 0...margin
          if text[i] != SPACE
            @lines.unget
            return
          end
        end

        active_line = text[margin..-1]

        # Rules (horizontal lines) look like
        #
        #  ---   (three or more hyphens)
        #
        # The more hyphens, the thicker the rule
        #

        if /^(---+)\s*$/ =~ active_line
          line.stamp(Line::RULE, level, $1.length-2)
          next
        end

        # Then look for list entries. First the ones that have to have
        # text following them (* xxx, - xxx, and dd. xxx)

        if SIMPLE_LIST_RE =~ active_line

          offset = margin + $1.length
          prefix = $2
          prefix_length = prefix.length

          flag = case prefix
                 when "*","-" then ListBase::BULLET
                 when /^\d/   then ListBase::NUMBER
                 when /^[A-Z]/ then ListBase::UPPERALPHA
                 when /^[a-z]/ then ListBase::LOWERALPHA
                 else raise "Invalid List Type: #{self.inspect}"
                 end

          line.stamp(Line::LIST, level+1, prefix, flag)
          text[margin, prefix_length] = " " * prefix_length
          assign_types_to_lines(offset, level + 1)
          next
        end


        if LABEL_LIST_RE =~ active_line
          offset = margin + $1.length
          prefix = $2
          prefix_length = prefix.length

          next if handled_labeled_list(line, level, margin, offset, prefix)
        end

        # Headings look like
        # = Main heading
        # == Second level
        # === Third
        #
        # Headings reset the level to 0

        if active_line[0] == ?= and active_line =~ /^(=+)\s*(.*)/
          prefix_length = $1.length
          prefix_length = 6 if prefix_length > 6
          line.stamp(Line::HEADING, 0, prefix_length)
          line.strip_leading(margin + prefix_length)
          next
        end
        
        # If the character's a space, then we have verbatim text,
        # otherwise 

        if active_line[0] == SPACE
          line.strip_leading(margin) if margin > 0
          line.stamp(Line::VERBATIM, level)
        else
          line.stamp(Line::PARAGRAPH, level)
        end
      end
    end

    # Handle labeled list entries, We have a special case
    # to deal with. Because the labels can be long, they force
    # the remaining block of text over the to right:
    #
    # this is a long label that I wrote:: and here is the
    #                                     block of text with
    #                                     a silly margin
    #
    # So we allow the special case. If the label is followed
    # by nothing, and if the following line is indented, then
    # we take the indent of that line as the new margin
    #
    # this is a long label that I wrote::
    #     here is a more reasonably indented block which
    #     will ab attached to the label.
    #
    
    def handled_labeled_list(line, level, margin, offset, prefix)
      prefix_length = prefix.length
      text = line.text
      flag = nil
      case prefix
      when /^\[/
        flag = ListBase::LABELED
        prefix = prefix[1, prefix.length-2]
      when /:$/
        flag = ListBase::NOTE
        prefix.chop!
      else raise "Invalid List Type: #{self.inspect}"
      end
      
      # body is on the next line
      
      if text.length <= offset
        original_line = line
        line = @lines.next
        return(false) unless line
        text = line.text
        
        for i in 0..margin
          if text[i] != SPACE
            @lines.unget
            return false
          end
        end
        i = margin
        i += 1 while text[i] == SPACE
        if i >= text.length
          @lines.unget
          return false
        else
          offset = i
          prefix_length = 0
          @lines.delete(original_line)
        end
      end
      
      line.stamp(Line::LIST, level+1, prefix, flag)
      text[margin, prefix_length] = " " * prefix_length
      assign_types_to_lines(offset, level + 1)
      return true
    end

    # Return a block consisting of fragments which are
    # paragraphs, list entries or verbatim text. We merge consecutive
    # lines of the same type and level together. We are also slightly
    # tricky with lists: the lines following a list introduction
    # look like paragraph lines at the next level, and we remap them
    # into list entries instead

    def group_lines
      @lines.rewind

      inList = false
      wantedType = wantedLevel = nil

      block = LineCollection.new
      group = nil

      while line = @lines.next
        if line.level == wantedLevel and line.type == wantedType
          group.add_text(line.text)
        else
          group = block.fragment_for(line)
          block.add(group)
          if line.type == Line::LIST
            wantedType = Line::PARAGRAPH
          else
            wantedType = line.type
          end
          wantedLevel = line.type == Line::HEADING ? line.param : line.level
        end
      end

      block.normalize
      block
    end

    ## for debugging, we allow access to our line contents as text
    def content
      @lines.as_text
    end
    public :content

    ## for debugging, return the list of line types
    def get_line_types
      @lines.line_types
    end
    public :get_line_types
  end

end
PK     Z\^       rdoc/markup/sample/rdoc2latex.rbnu [        #!/usr/local/bin/ruby
# Illustration of a script to convert an RDoc-style file to a LaTeX
# document

require 'rdoc/markup/simple_markup'
require 'rdoc/markup/simple_markup/to_latex'

p = SM::SimpleMarkup.new
h = SM::ToLaTeX.new

#puts "\\documentclass{report}"
#puts "\\usepackage{tabularx}"
#puts "\\usepackage{parskip}"
#puts "\\begin{document}"
puts p.convert(ARGF.read, h)
#puts "\\end{document}"
PK     Z\v?  ?    rdoc/markup/sample/sample.rbnu [        # This program illustrates the basic use of the SimpleMarkup
# class. It extracts the first comment block from the 
# simple_markup.rb file and converts it into HTML on
# standard output. Run it using
#
#  % ruby sample.rb
#
# You should be in the sample/ directory when you do this,
# as it hardwires the path to the files it needs to require.
# This isn't necessary in the code you write once you've 
# installed the package.
#
# For a better way of formatting code comment blocks (and more)
# see the rdoc package.
#

$:.unshift "../../.."

require 'rdoc/markup/simple_markup'
require 'rdoc/markup/simple_markup/to_html'

# Extract the comment block from the source file

input_string = ""

File.foreach("../simple_markup.rb") do |line|
  break unless line.gsub!(/^\# ?/, '')
  input_string << line
end

# Create a markup object
markup = SM::SimpleMarkup.new

# Attach it to an HTML formatter
h = SM::ToHtml.new

# And convert out comment block to html. Wrap it a body
# tag pair to let browsers view it

puts "<html><body>"
puts markup.convert(input_string, h)
puts "</body></html>"
PK     Z\=        rdoc/markup/test/TestInline.rbnu [        require "test/unit"

$:.unshift "../../.."

require "rdoc/markup/simple_markup/inline"

class TestInline < Test::Unit::TestCase


  def setup
    @am = SM::AttributeManager.new

    @bold_on  = @am.changed_attribute_by_name([], [:BOLD])
    @bold_off = @am.changed_attribute_by_name([:BOLD], [])
    
    @tt_on    = @am.changed_attribute_by_name([], [:TT])
    @tt_off   = @am.changed_attribute_by_name([:TT], [])
    
    @em_on    = @am.changed_attribute_by_name([], [:EM])
    @em_off   = @am.changed_attribute_by_name([:EM], [])
    
    @bold_em_on   = @am.changed_attribute_by_name([], [:BOLD] | [:EM])
    @bold_em_off  = @am.changed_attribute_by_name([:BOLD] | [:EM], [])
    
    @em_then_bold = @am.changed_attribute_by_name([:EM], [:EM] | [:BOLD])
    
    @em_to_bold   = @am.changed_attribute_by_name([:EM], [:BOLD])
    
    @am.add_word_pair("{", "}", :WOMBAT)
    @wombat_on    = @am.changed_attribute_by_name([], [:WOMBAT])
    @wombat_off   = @am.changed_attribute_by_name([:WOMBAT], [])
  end

  def crossref(text)
    [ @am.changed_attribute_by_name([], [:CROSSREF] | [:_SPECIAL_]),
      SM::Special.new(33, text),
      @am.changed_attribute_by_name([:CROSSREF] | [:_SPECIAL_], [])
    ]
  end

  def test_special
    # class names, variable names, file names, or instance variables
    @am.add_special(/(
                       \b([A-Z]\w+(::\w+)*)
                       | \#\w+[!?=]?
                       | \b\w+([_\/\.]+\w+)+[!?=]?
                      )/x, 
                    :CROSSREF)
    
    assert_equal(["cat"], @am.flow("cat"))

    assert_equal(["cat ", crossref("#fred"), " dog"].flatten,
                  @am.flow("cat #fred dog"))

    assert_equal([crossref("#fred"), " dog"].flatten,
                  @am.flow("#fred dog"))

    assert_equal(["cat ", crossref("#fred")].flatten, @am.flow("cat #fred"))
  end

  def test_basic
    assert_equal(["cat"], @am.flow("cat"))

    assert_equal(["cat ", @bold_on, "and", @bold_off, " dog"],
                  @am.flow("cat *and* dog"))

    assert_equal(["cat ", @bold_on, "AND", @bold_off, " dog"],
                  @am.flow("cat *AND* dog"))

    assert_equal(["cat ", @em_on, "And", @em_off, " dog"],
                  @am.flow("cat _And_ dog"))

    assert_equal(["cat *and dog*"], @am.flow("cat *and dog*"))

    assert_equal(["*cat and* dog"], @am.flow("*cat and* dog"))

    assert_equal(["cat *and ", @bold_on, "dog", @bold_off],
                  @am.flow("cat *and *dog*"))

    assert_equal(["cat ", @em_on, "and", @em_off, " dog"],
                  @am.flow("cat _and_ dog"))

    assert_equal(["cat_and_dog"],
                  @am.flow("cat_and_dog"))

    assert_equal(["cat ", @tt_on, "and", @tt_off, " dog"],
                  @am.flow("cat +and+ dog"))

    assert_equal(["cat ", @bold_on, "a_b_c", @bold_off, " dog"],
                  @am.flow("cat *a_b_c* dog"))

    assert_equal(["cat __ dog"],
                  @am.flow("cat __ dog"))

    assert_equal(["cat ", @em_on, "_", @em_off, " dog"],
                  @am.flow("cat ___ dog"))

  end

  def test_combined
    assert_equal(["cat ", @em_on, "and", @em_off, " ", @bold_on, "dog", @bold_off],
                  @am.flow("cat _and_ *dog*"))

    assert_equal(["cat ", @em_on, "a__nd", @em_off, " ", @bold_on, "dog", @bold_off], 
                  @am.flow("cat _a__nd_ *dog*"))
  end

  def test_html_like
    assert_equal(["cat ", @tt_on, "dog", @tt_off], @am.flow("cat <tt>dog</Tt>"))

    assert_equal(["cat ", @em_on, "and", @em_off, " ", @bold_on, "dog", @bold_off], 
                  @am.flow("cat <i>and</i> <B>dog</b>"))
    
    assert_equal(["cat ", @em_on, "and ", @em_then_bold, "dog", @bold_em_off], 
                  @am.flow("cat <i>and <B>dog</B></I>"))
    
    assert_equal(["cat ", @em_on, "and ", @em_to_bold, "dog", @bold_off], 
                  @am.flow("cat <i>and </i><b>dog</b>"))
    
    assert_equal(["cat ", @em_on, "and ", @em_to_bold, "dog", @bold_off], 
                  @am.flow("cat <i>and <b></i>dog</b>"))
    
    assert_equal([@tt_on, "cat", @tt_off, " ", @em_on, "and ", @em_to_bold, "dog", @bold_off], 
                  @am.flow("<tt>cat</tt> <i>and <b></i>dog</b>"))

    assert_equal(["cat ", @em_on, "and ", @em_then_bold, "dog", @bold_em_off], 
                  @am.flow("cat <i>and <b>dog</b></i>"))
    
    assert_equal(["cat ", @bold_em_on, "and", @bold_em_off, " dog"], 
                  @am.flow("cat <i><b>and</b></i> dog"))
    
    
  end

  def test_protect
    assert_equal(['cat \\ dog'], @am.flow('cat \\ dog'))

    assert_equal(["cat <tt>dog</Tt>"], @am.flow("cat \\<tt>dog</Tt>"))

    assert_equal(["cat ", @em_on, "and", @em_off, " <B>dog</b>"], 
                  @am.flow("cat <i>and</i> \\<B>dog</b>"))
    
    assert_equal(["*word* or <b>text</b>"], @am.flow("\\*word* or \\<b>text</b>"))

    assert_equal(["_cat_", @em_on, "dog", @em_off], 
                  @am.flow("\\_cat_<i>dog</i>"))
  end

  def test_adding
    assert_equal(["cat ", @wombat_on, "and", @wombat_off, " dog" ],
                  @am.flow("cat {and} dog"))
#    assert_equal(["cat {and} dog" ], @am.flow("cat \\{and} dog"))
  end
end
PK     Z\w4,  ,    rdoc/markup/test/TestParse.rbnu [        require 'test/unit'

$:.unshift "../../.."

require 'rdoc/markup/simple_markup'

include SM

class TestParse < Test::Unit::TestCase

  class MockOutput
    def start_accepting
      @res = []
      end
    
    def end_accepting
      @res
    end

    def accept_paragraph(am, fragment)
      @res << fragment.to_s
    end

    def accept_verbatim(am, fragment)
      @res << fragment.to_s
    end

    def accept_list_start(am, fragment)
      @res << fragment.to_s
    end

    def accept_list_end(am, fragment)
      @res << fragment.to_s
    end

    def accept_list_item(am, fragment)
      @res << fragment.to_s
    end

    def accept_blank_line(am, fragment)
      @res << fragment.to_s
    end

    def accept_heading(am, fragment)
      @res << fragment.to_s
    end

    def accept_rule(am, fragment)
      @res << fragment.to_s
    end

  end

  def basic_conv(str)
    sm = SimpleMarkup.new
    mock = MockOutput.new
    sm.convert(str, mock)
    sm.content
  end

  def line_types(str, expected)
    p = SimpleMarkup.new
    mock = MockOutput.new
    p.convert(str, mock)
    assert_equal(expected, p.get_line_types.map{|type| type.to_s[0,1]}.join(''))
  end

  def line_groups(str, expected)
    p = SimpleMarkup.new
    mock = MockOutput.new

    block = p.convert(str, mock)

    if block != expected
      rows = (0...([expected.size, block.size].max)).collect{|i|
        [expected[i]||"nil", block[i]||"nil"] 
      }
      printf "\n\n%35s %35s\n", "Expected", "Got"
      rows.each {|e,g| printf "%35s %35s\n", e.dump, g.dump }
    end

    assert_equal(expected, block)
  end

  def test_tabs
    str = "hello\n  dave"
    assert_equal(str, basic_conv(str))
    str = "hello\n\tdave"
    assert_equal("hello\n        dave", basic_conv(str))
    str = "hello\n \tdave"
    assert_equal("hello\n        dave", basic_conv(str))
    str = "hello\n  \tdave"
    assert_equal("hello\n        dave", basic_conv(str))
    str = "hello\n   \tdave"
    assert_equal("hello\n        dave", basic_conv(str))
    str = "hello\n    \tdave"
    assert_equal("hello\n        dave", basic_conv(str))
    str = "hello\n     \tdave"
    assert_equal("hello\n        dave", basic_conv(str))
    str = "hello\n      \tdave"
    assert_equal("hello\n        dave", basic_conv(str))
    str = "hello\n       \tdave"
    assert_equal("hello\n        dave", basic_conv(str))
    str = "hello\n        \tdave"
    assert_equal("hello\n                dave", basic_conv(str))
    str = ".\t\t."
    assert_equal(".               .", basic_conv(str))
  end

  def test_whitespace
    assert_equal("hello", basic_conv("hello"))
    assert_equal("hello", basic_conv(" hello "))
    assert_equal("hello", basic_conv(" \t \t hello\t\t"))

    assert_equal("1\n 2\n  3", basic_conv("1\n 2\n  3"))
    assert_equal("1\n 2\n  3", basic_conv("  1\n   2\n    3"))

    assert_equal("1\n 2\n  3\n1\n 2", basic_conv("1\n 2\n  3\n1\n 2"))
    assert_equal("1\n 2\n  3\n1\n 2", basic_conv("  1\n   2\n    3\n  1\n   2"))

    assert_equal("1\n 2\n\n  3", basic_conv("  1\n   2\n\n    3"))
  end

  def test_types
    str = "now is the time"
    line_types(str, 'P')

    str = "now is the time\nfor all good men"
    line_types(str, 'PP')

    str = "now is the time\n  code\nfor all good men"
    line_types(str, 'PVP')

    str = "now is the time\n  code\n more code\nfor all good men"
    line_types(str, 'PVVP')

    str = "now is\n---\nthe time"
    line_types(str, 'PRP')

    str = %{\
       now is
       * l1
       * l2
       the time}
    line_types(str, 'PLLP')

    str = %{\
       now is
       * l1
         l1+
       * l2
       the time}
    line_types(str, 'PLPLP')

    str = %{\
       now is
       * l1
         * l1.1
       * l2
       the time}
    line_types(str, 'PLLLP')

    str = %{\
       now is
       * l1
         * l1.1
           text
             code
             code

           text
       * l2
       the time}
    line_types(str, 'PLLPVVBPLP')

    str = %{\
       now is
       1. l1
          * l1.1
       2. l2
       the time}
    line_types(str, 'PLLLP')

    str = %{\
       now is
       [cat] l1
             * l1.1
       [dog] l2
       the time}
    line_types(str, 'PLLLP')

    str = %{\
       now is
       [cat] l1
             continuation
       [dog] l2
       the time}
    line_types(str, 'PLPLP')
  end

  def test_groups
    str = "now is the time"
    line_groups(str, ["L0: Paragraph\nnow is the time"] )

    str = "now is the time\nfor all good men"
    line_groups(str, ["L0: Paragraph\nnow is the time for all good men"] )

    str = %{\
      now is the time
        code _line_ here
      for all good men}

    line_groups(str,
                [ "L0: Paragraph\nnow is the time",
                  "L0: Verbatim\n  code _line_ here\n",
                  "L0: Paragraph\nfor all good men"
                ] )

    str = "now is the time\n  code\n more code\nfor all good men"
    line_groups(str,
                [ "L0: Paragraph\nnow is the time",
                  "L0: Verbatim\n  code\n more code\n",
                  "L0: Paragraph\nfor all good men"
                ] )

    str = %{\
       now is
       * l1
       * l2
       the time}
    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L1: ListStart\n",
                  "L1: ListItem\nl1",
                  "L1: ListItem\nl2",
                  "L1: ListEnd\n",
                  "L0: Paragraph\nthe time"
                ])

    str = %{\
       now is
       * l1
         l1+
       * l2
       the time}
    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L1: ListStart\n",
                  "L1: ListItem\nl1 l1+",
                  "L1: ListItem\nl2",
                  "L1: ListEnd\n",
                  "L0: Paragraph\nthe time"
                ])

    str = %{\
       now is
       * l1
         * l1.1
       * l2
       the time}
    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L1: ListStart\n",
                  "L1: ListItem\nl1",
                  "L2: ListStart\n",
                  "L2: ListItem\nl1.1",
                  "L2: ListEnd\n",
                  "L1: ListItem\nl2",
                  "L1: ListEnd\n",
                  "L0: Paragraph\nthe time"
                ])


    str = %{\
       now is
       * l1
         * l1.1
           text
             code
               code

           text
       * l2
       the time}
    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L1: ListStart\n",
                  "L1: ListItem\nl1",
                  "L2: ListStart\n",
                  "L2: ListItem\nl1.1 text",
                  "L2: Verbatim\n  code\n    code\n",
                  "L2: Paragraph\ntext",
                  "L2: ListEnd\n",
                  "L1: ListItem\nl2",
                  "L1: ListEnd\n",
                  "L0: Paragraph\nthe time"
                ])


    str = %{\
       now is
       1. l1
          * l1.1
       2. l2
       the time}
    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L1: ListStart\n",
                  "L1: ListItem\nl1",
                  "L2: ListStart\n",
                  "L2: ListItem\nl1.1",
                  "L2: ListEnd\n",
                  "L1: ListItem\nl2",
                  "L1: ListEnd\n",
                  "L0: Paragraph\nthe time"
                ])

    str = %{\
       now is
       [cat] l1
             * l1.1
       [dog] l2
       the time}
    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L1: ListStart\n",
                  "L1: ListItem\nl1",
                  "L2: ListStart\n",
                  "L2: ListItem\nl1.1",
                  "L2: ListEnd\n",
                  "L1: ListItem\nl2",
                  "L1: ListEnd\n",
                  "L0: Paragraph\nthe time"
                ])

    str = %{\
       now is
       [cat] l1
             continuation
       [dog] l2
       the time}
    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L1: ListStart\n",
                  "L1: ListItem\nl1 continuation",
                  "L1: ListItem\nl2",
                  "L1: ListEnd\n",
                  "L0: Paragraph\nthe time"
                ])

    
  end

  def test_verbatim_merge
    str = %{\
       now is
          code
       the time}

    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L0: Verbatim\n   code\n",
                  "L0: Paragraph\nthe time"
                ])


    str = %{\
       now is
          code
          code1
       the time}

    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L0: Verbatim\n   code\n   code1\n",
                  "L0: Paragraph\nthe time"
                ])


    str = %{\
       now is
          code

          code1
       the time}

    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L0: Verbatim\n   code\n\n   code1\n",
                  "L0: Paragraph\nthe time"
                ])


    str = %{\
       now is
          code

          code1

       the time}

    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L0: Verbatim\n   code\n\n   code1\n",
                  "L0: Paragraph\nthe time"
                ])


    str = %{\
       now is
          code

          code1

          code2
       the time}

    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L0: Verbatim\n   code\n\n   code1\n\n   code2\n",
                  "L0: Paragraph\nthe time"
                ])


    # Folds multiple blank lines
    str = %{\
       now is
          code


          code1

       the time}

    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L0: Verbatim\n   code\n\n   code1\n",
                  "L0: Paragraph\nthe time"
                ])


  end
 
  def test_list_split
    str = %{\
       now is
       * l1
       1. n1
       2. n2
       * l2
       the time}
    line_groups(str,
                [ "L0: Paragraph\nnow is",
                  "L1: ListStart\n",
                  "L1: ListItem\nl1",
                  "L1: ListEnd\n",
                  "L1: ListStart\n",
                  "L1: ListItem\nn1",
                  "L1: ListItem\nn2",
                  "L1: ListEnd\n",
                  "L1: ListStart\n",
                  "L1: ListItem\nl2",
                  "L1: ListEnd\n",
                  "L0: Paragraph\nthe time"
                ])

  end


  def test_headings
    str = "= heading one"
    line_groups(str, 
                [ "L0: Heading\nheading one"
                ])

    str = "=== heading three"
    line_groups(str, 
                [ "L0: Heading\nheading three"
                ])

    str = "text\n   === heading three"
    line_groups(str, 
                [ "L0: Paragraph\ntext",
                  "L0: Verbatim\n   === heading three\n"
                ])

    str = "text\n   code\n   === heading three"
    line_groups(str, 
                [ "L0: Paragraph\ntext",
                  "L0: Verbatim\n   code\n   === heading three\n"
                ])

    str = "text\n   code\n=== heading three"
    line_groups(str, 
                [ "L0: Paragraph\ntext",
                  "L0: Verbatim\n   code\n",
                  "L0: Heading\nheading three"
                ])

  end

  
end
PK     Z\Z	/   /     rdoc/markup/test/AllTests.rbnu [        require 'TestParse.rb'
require 'TestInline.rb'
PK     Z\;gD  D    rdoc/options.rbnu [        # We handle the parsing of options, and subsequently as a singleton
# object to be queried for option values

require "rdoc/ri/ri_paths"

class Options

  require 'singleton'
  require 'getoptlong'

  include Singleton

  # files matching this pattern will be excluded
  attr_accessor :exclude

  # the name of the output directory
  attr_accessor :op_dir
  
  # the name to use for the output
  attr_reader :op_name

  # include private and protected methods in the
  # output
  attr_accessor :show_all
  
  # name of the file, class or module to display in
  # the initial index page (if not specified
  # the first file we encounter is used)
  attr_accessor :main_page

  # merge into classes of the name name when generating ri
  attr_reader :merge

  # Don't display progress as we process the files
  attr_reader :quiet

  # description of the output generator (set with the <tt>-fmt</tt>
  # option
  attr_accessor :generator

  # and the list of files to be processed
  attr_reader :files

  # array of directories to search for files to satisfy an :include:
  attr_reader :rdoc_include

  # title to be used out the output
  #attr_writer :title

  # template to be used when generating output
  attr_reader :template

  # should diagrams be drawn
  attr_reader :diagram

  # should we draw fileboxes in diagrams
  attr_reader :fileboxes

  # include the '#' at the front of hyperlinked instance method names
  attr_reader :show_hash

  # image format for diagrams
  attr_reader :image_format

  # character-set
  attr_reader :charset

  # should source code be included inline, or displayed in a popup
  attr_reader :inline_source

  # should the output be placed into a single file
  attr_reader :all_one_file

  # the number of columns in a tab
  attr_reader :tab_width

  # include line numbers in the source listings
  attr_reader :include_line_numbers

  # pattern for additional attr_... style methods
  attr_reader :extra_accessors
  attr_reader :extra_accessor_flags

  # URL of stylesheet
  attr_reader :css

  # URL of web cvs frontend
  attr_reader :webcvs

  # Are we promiscuous about showing module contents across
  # multiple files
  attr_reader :promiscuous

  # scan newer sources than the flag file if true.
  attr_reader :force_update

  module OptionList

    OPTION_LIST = [
      [ "--accessor",      "-A",   "accessorname[,..]",
        "comma separated list of additional class methods\n" +
        "that should be treated like 'attr_reader' and\n" +
        "friends. Option may be repeated. Each accessorname\n" +
        "may have '=text' appended, in which case that text\n" +
        "appears where the r/w/rw appears for normal accessors."],
                                                                   
      [ "--all",           "-a",   nil,
        "include all methods (not just public)\nin the output" ],

      [ "--charset",       "-c",   "charset",
        "specifies HTML character-set" ],

      [ "--debug",         "-D",   nil,
        "displays lots on internal stuff" ],

      [ "--diagram",       "-d",   nil,
        "Generate diagrams showing modules and classes.\n" +
        "You need dot V1.8.6 or later to use the --diagram\n" +
        "option correctly. Dot is available from\n"+
        "http://www.research.att.com/sw/tools/graphviz/" ],

      [ "--exclude",       "-x",   "pattern",
        "do not process files or directories matching\n" +
        "pattern. Files given explicitly on the command\n" +
        "line will never be excluded." ],

      [ "--extension",     "-E",   "new=old",
        "Treat files ending with .new as if they ended with\n" +
        ".old. Using '-E cgi=rb' will cause xxx.cgi to be\n" +
        "parsed as a Ruby file"],

      [ "--fileboxes",     "-F",   nil,
        "classes are put in boxes which represents\n" +
        "files, where these classes reside. Classes\n" +
        "shared between more than one file are\n" +
        "shown with list of files that sharing them.\n" +
        "Silently discarded if --diagram is not given\n" +
        "Experimental." ],

      [ "--force-update",  "-U",   nil,
        "forces to scan all sources even if newer than\n" +
        "the flag file." ],

      [ "--fmt",           "-f",   "format name",
        "set the output formatter (see below)" ],

      [ "--help",          "-h",   nil,
        "you're looking at it" ],

      [ "--help-output",   "-O",   nil,
        "explain the various output options" ],

      [ "--image-format",  "-I",   "gif/png/jpg/jpeg",
        "Sets output image format for diagrams. Can\n" +
        "be png, gif, jpeg, jpg. If this option is\n" +
        "omitted, png is used. Requires --diagram." ],

      [ "--include",       "-i",   "dir[,dir...]",
        "set (or add to) the list of directories\n" +
        "to be searched when satisfying :include:\n" +
        "requests. Can be used more than once." ],

      [ "--inline-source", "-S",   nil,
        "Show method source code inline, rather\n" +
        "than via a popup link" ],

      [ "--line-numbers", "-N", nil,
        "Include line numbers in the source code" ],

      [ "--main",          "-m",   "name",
        "'name' will be the initial page displayed" ],

      [ "--merge",         "-M",   nil,
        "when creating ri output, merge processed classes\n" +
        "into previously documented classes of the name name"],

      [ "--one-file",      "-1",   nil,
        "put all the output into a single file" ],

      [ "--op",            "-o",   "dir",
        "set the output directory" ],

      [ "--opname",       "-n",    "name",
        "Set the 'name' of the output. Has no\n" +
        "effect for HTML." ],

      [ "--promiscuous",   "-p",   nil,
        "When documenting a file that contains a module\n" +
        "or class also defined in other files, show\n" +
        "all stuff for that module/class in each files\n" +
        "page. By default, only show stuff defined in\n" +
        "that particular file." ],

      [ "--quiet",         "-q",   nil,
        "don't show progress as we parse" ],

      [ "--ri",            "-r",   nil,
       "generate output for use by 'ri.' The files are\n" +
       "stored in the '.rdoc' directory under your home\n"+
       "directory unless overridden by a subsequent\n" +
       "--op parameter, so no special privileges are needed." ],

      [ "--ri-site",       "-R",   nil,
       "generate output for use by 'ri.' The files are\n" +
       "stored in a site-wide directory, making them accessible\n"+
       "to others, so special privileges are needed." ],

      [ "--ri-system",     "-Y",   nil,
       "generate output for use by 'ri.' The files are\n" +
       "stored in a system-level directory, making them accessible\n"+
       "to others, so special privileges are needed. This option\n"+
       "is intended to be used during Ruby installations" ],

      [ "--show-hash",     "-H",   nil,
        "A name of the form #name in a comment\n" +
        "is a possible hyperlink to an instance\n" +
        "method name. When displayed, the '#' is\n" +
        "removed unless this option is specified" ],

      [ "--style",         "-s",   "stylesheet url",
        "specifies the URL of a separate stylesheet." ],

      [ "--tab-width",     "-w",   "n",
        "Set the width of tab characters (default 8)"],

      [ "--template",      "-T",   "template name",
        "Set the template used when generating output" ],

      [ "--title",         "-t",   "text",
        "Set 'txt' as the title for the output" ],

      [ "--version",       "-v",   nil,
        "display  RDoc's version" ],

      [ "--webcvs",        "-W",   "url",
        "Specify a URL for linking to a web frontend\n" +
        "to CVS. If the URL contains a '\%s', the\n" +
        "name of the current file will be substituted;\n" +
        "if the URL doesn't contain a '\%s', the\n" +
        "filename will be appended to it." ],
    ]

    def OptionList.options
      OPTION_LIST.map do |long, short, arg,|
        [ long, 
          short, 
          arg ? GetoptLong::REQUIRED_ARGUMENT : GetoptLong::NO_ARGUMENT 
        ]
      end
    end


    def OptionList.strip_output(text)
      text =~ /^\s+/
      leading_spaces = $&
      text.gsub!(/^#{leading_spaces}/, '')
      $stdout.puts text
    end


    # Show an error and exit

    def OptionList.error(msg)
      $stderr.puts
      $stderr.puts msg
      $stderr.puts "\nFor help on options, try 'rdoc --help'\n\n"
      exit 1
    end

    # Show usage and exit
    
    def OptionList.usage(generator_names)
      
      puts
      puts(VERSION_STRING)
      puts

      name = File.basename($0)
      OptionList.strip_output(<<-EOT)
          Usage:

            #{name} [options]  [names...]

          Files are parsed, and the information they contain
          collected, before any output is produced. This allows cross
          references between all files to be resolved. If a name is a
          directory, it is traversed. If no names are specified, all
          Ruby files in the current directory (and subdirectories) are
          processed.

          Options:

      EOT

      OPTION_LIST.each do |long, short, arg, desc|
        opt = sprintf("%20s", "#{long}, #{short}")
        oparg = sprintf("%-7s", arg)
        print "#{opt} #{oparg}"
        desc = desc.split("\n")
        if arg.nil? || arg.length < 7
          puts desc.shift
        else
          puts
        end
        desc.each do |line|
          puts(" "*28 + line)
        end
        puts
      end

      puts "\nAvailable output formatters: " +
        generator_names.sort.join(', ') + "\n\n"

      puts "For information on where the output goes, use\n\n"
      puts "   rdoc --help-output\n\n"

      exit 0
    end

    def OptionList.help_output
      OptionList.strip_output(<<-EOT)
      How RDoc generates output depends on the output formatter being
      used, and on the options you give.

      - HTML output is normally produced into a number of separate files
        (one per class, module, and file, along with various indices). 
        These files will appear in the directory given by the --op
        option (doc/ by default).

      - XML output by default is written to standard output. If a
        --opname option is given, the output will instead be written
        to a file with that name in the output directory.

      - .chm files (Windows help files) are written in the --op directory.
        If an --opname parameter is present, that name is used, otherwise
        the file will be called rdoc.chm.

      For information on other RDoc options, use "rdoc --help".
      EOT
      exit 0
    end
  end

  # Parse command line options. We're passed a hash containing
  # output generators, keyed by the generator name

  def parse(argv, generators)
    old_argv = ARGV.dup
    begin
      ARGV.replace(argv)
      @op_dir = "doc"
      @op_name = nil
      @show_all = false
      @main_page = nil
      @marge     = false
      @exclude   = []
      @quiet = false
      @generator_name = 'html'
      @generator = generators[@generator_name]
      @rdoc_include = []
      @title = nil
      @template = nil
      @diagram = false
      @fileboxes = false
      @show_hash = false
      @image_format = 'png'
      @inline_source = false
      @all_one_file  = false
      @tab_width = 8
      @include_line_numbers = false
      @extra_accessor_flags = {}
      @promiscuous = false
      @force_update = false

      @css = nil
      @webcvs = nil

      @charset = case $KCODE
                 when /^S/i
                   'Shift_JIS'
                 when /^E/i
                   'EUC-JP'
                 else
                   'iso-8859-1'
                 end

      accessors = []

      go = GetoptLong.new(*OptionList.options)
      go.quiet = true

      go.each do |opt, arg|
	case opt
        when "--all"           then @show_all      = true
        when "--charset"       then @charset       = arg
        when "--debug"         then $DEBUG         = true
        when "--exclude"       then @exclude       << Regexp.new(arg)
        when "--inline-source" then @inline_source = true
        when "--line-numbers"  then @include_line_numbers = true
        when "--main"          then @main_page     = arg
        when "--merge"         then @merge         = true
        when "--one-file"      then @all_one_file  = @inline_source = true
        when "--op"            then @op_dir        = arg
        when "--opname"        then @op_name       = arg
        when "--promiscuous"   then @promiscuous   = true
        when "--quiet"         then @quiet         = true
        when "--show-hash"     then @show_hash     = true
        when "--style"         then @css           = arg
        when "--template"      then @template      = arg
        when "--title"         then @title         = arg
        when "--webcvs"        then @webcvs        = arg

        when "--accessor" 
          arg.split(/,/).each do |accessor|
            if accessor =~ /^(\w+)(=(.*))?$/
              accessors << $1
              @extra_accessor_flags[$1] = $3
            end
          end

        when "--diagram"
          check_diagram
          @diagram = true

        when "--fileboxes"
          @fileboxes = true if @diagram

	when "--fmt"
          @generator_name = arg.downcase
          setup_generator(generators)

        when "--help"      
          OptionList.usage(generators.keys)

        when "--help-output"      
          OptionList.help_output

        when "--image-format"
          if ['gif', 'png', 'jpeg', 'jpg'].include?(arg)
            @image_format = arg
          else
            raise GetoptLong::InvalidOption.new("unknown image format: #{arg}")
          end

        when "--include"   
          @rdoc_include.concat arg.split(/\s*,\s*/)

        when "--ri", "--ri-site", "--ri-system"
          @generator_name = "ri"
          @op_dir = case opt
                    when "--ri" then RI::Paths::HOMEDIR 
                    when "--ri-site" then RI::Paths::SITEDIR
                    when "--ri-system" then RI::Paths::SYSDIR
                    else fail opt
                    end
          setup_generator(generators)

        when "--tab-width"
          begin
            @tab_width     = Integer(arg)
          rescue 
            $stderr.puts "Invalid tab width: '#{arg}'"
            exit 1
          end

        when "--extension"
          new, old = arg.split(/=/, 2)
          OptionList.error("Invalid parameter to '-E'") unless new && old
          unless RDoc::ParserFactory.alias_extension(old, new)
            OptionList.error("Unknown extension .#{old} to -E")
          end

        when "--force-update"
          @force_update = true

	when "--version"
	  puts VERSION_STRING
	  exit
	end

      end

      @files = ARGV.dup

      @rdoc_include << "." if @rdoc_include.empty?

      if @exclude.empty?
        @exclude = nil
      else
        @exclude = Regexp.new(@exclude.join("|"))
      end

      check_files

      # If no template was specified, use the default
      # template for the output formatter

      @template ||= @generator_name

      # Generate a regexp from the accessors
      unless accessors.empty?
        re = '^(' + accessors.map{|a| Regexp.quote(a)}.join('|') + ')$' 
        @extra_accessors = Regexp.new(re)
      end

    rescue GetoptLong::InvalidOption, GetoptLong::MissingArgument => error
      OptionList.error(error.message)

    ensure
      ARGV.replace(old_argv)
    end
  end


  def title
    @title ||= "RDoc Documentation"
  end
  
  # Set the title, but only if not already set. This means that a title set from 
  # the command line trumps one set in a source file

  def title=(string)
    @title ||= string
  end


  private

  # Set up an output generator for the format in @generator_name
  def setup_generator(generators)
    @generator = generators[@generator_name]
    if !@generator
      OptionList.error("Invalid output formatter")
    end
    
    if @generator_name == "xml"
      @all_one_file = true
      @inline_source = true
    end
  end

  # Check that the right version of 'dot' is available.
  # Unfortuately this doesn't work correctly under Windows NT, 
  # so we'll bypass the test under Windows

  def check_diagram
    return if RUBY_PLATFORM =~ /mswin|cygwin|mingw|bccwin/

    ok = false
    ver = nil
    IO.popen("dot -V 2>&1") do |io|
      ver = io.read
      if ver =~ /dot.+version(?:\s+gviz)?\s+(\d+)\.(\d+)/
        ok = ($1.to_i > 1) || ($1.to_i == 1 && $2.to_i >= 8)
      end
    end
    unless ok
      if ver =~ /^dot.+version/
        $stderr.puts "Warning: You may need dot V1.8.6 or later to use\n",
          "the --diagram option correctly. You have:\n\n   ",
          ver,
          "\nDiagrams might have strange background colors.\n\n"
      else
        $stderr.puts "You need the 'dot' program to produce diagrams.",
          "(see http://www.research.att.com/sw/tools/graphviz/)\n\n"
        exit
      end
#      exit
    end
  end
  
  # Check that the files on the command line exist
  
  def check_files
    @files.each do |f|
      stat = File.stat f rescue error("File not found: #{f}")
      error("File '#{f}' not readable") unless stat.readable?
    end
  end

  def error(str)
    $stderr.puts str
    exit(1)
  end

end
PK     Z\G      rdoc/parsers/parse_f95.rbnu [        #= parse_f95.rb - Fortran95 Parser
#
#== Overview
#
#"parse_f95.rb" parses Fortran95 files with suffixes "f90", "F90", "f95"
#and "F95". Fortran95 files are expected to be conformed to Fortran95
#standards.
#
#== Rules
#
#Fundamental rules are same as that of the Ruby parser.
#But comment markers are '!' not '#'.
#
#=== Correspondence between RDoc documentation and Fortran95 programs
#
#"parse_f95.rb" parses main programs, modules, subroutines, functions,
#derived-types, public variables, public constants,
#defined operators and defined assignments.
#These components are described in items of RDoc documentation, as follows.
#
#Files :: Files (same as Ruby)
#Classes :: Modules
#Methods :: Subroutines, functions, variables, constants, derived-types, defined operators, defined assignments
#Required files :: Files in which imported modules, external subroutines and external functions are defined.
#Included Modules :: List of imported modules
#Attributes :: List of derived-types, List of imported modules all of whose components are published again
#
#Components listed in 'Methods' (subroutines, functions, ...)
#defined in modules are described in the item of 'Classes'.
#On the other hand, components defined in main programs or
#as external procedures are described in the item of 'Files'.
#
#=== Components parsed by default
#
#By default, documentation on public components (subroutines, functions, 
#variables, constants, derived-types, defined operators, 
#defined assignments) are generated. 
#With "--all" option, documentation on all components
#are generated (almost same as the Ruby parser).
#
#=== Information parsed automatically
#
#The following information is automatically parsed.
#
#* Types of arguments
#* Types of variables and constants
#* Types of variables in the derived types, and initial values
#* NAMELISTs and types of variables in them, and initial values
#
#Aliases by interface statement are described in the item of 'Methods'.
#
#Components which are imported from other modules and published again 
#are described in the item of 'Methods'.
#
#=== Format of comment blocks
#
#Comment blocks should be written as follows.
#Comment blocks are considered to be ended when the line without '!'
#appears.
#The indentation is not necessary.
#
#     ! (Top of file)
#     !
#     ! Comment blocks for the files.
#     !
#     !--
#     ! The comment described in the part enclosed by
#     ! "!--" and "!++" is ignored.
#     !++
#     !
#     module hogehoge
#       !
#       ! Comment blocks for the modules (or the programs).
#       !
#
#       private
#
#       logical            :: a     ! a private variable
#       real, public       :: b     ! a public variable
#       integer, parameter :: c = 0 ! a public constant
#
#       public :: c
#       public :: MULTI_ARRAY
#       public :: hoge, foo
#
#       type MULTI_ARRAY
#         !
#         ! Comment blocks for the derived-types.
#         !
#         real, pointer :: var(:) =>null() ! Comments block for the variables.
#         integer       :: num = 0
#       end type MULTI_ARRAY
#
#     contains
#
#       subroutine hoge( in,   &   ! Comment blocks between continuation lines are ignored.
#           &            out )
#         !
#         ! Comment blocks for the subroutines or functions
#         !
#         character(*),intent(in):: in ! Comment blocks for the arguments.
#         character(*),intent(out),allocatable,target  :: in
#                                      ! Comment blocks can be
#                                      ! written under Fortran statements.
#
#         character(32) :: file ! This comment parsed as a variable in below NAMELIST.
#         integer       :: id
#
#         namelist /varinfo_nml/ file, id
#                 !
#                 ! Comment blocks for the NAMELISTs.
#                 ! Information about variables are described above.
#                 !
#
#       ....
#
#       end subroutine hoge
#
#       integer function foo( in )
#         !
#         ! This part is considered as comment block.
#
#         ! Comment blocks under blank lines are ignored.
#         !
#         integer, intent(in):: inA ! This part is considered as comment block.
#
#                                   ! This part is ignored.
#
#       end function foo
#
#       subroutine hide( in,   &
#         &              out )      !:nodoc:
#         !
#         ! If "!:nodoc:" is described at end-of-line in subroutine
#         ! statement as above, the subroutine is ignored.
#         ! This assignment can be used to modules, subroutines,
#         ! functions, variables, constants, derived-types,
#         ! defined operators, defined assignments,
#         ! list of imported modules ("use" statement).
#         !
#
#       ....
#
#       end subroutine hide
#
#     end module hogehoge
#


require "rdoc/code_objects"

module RDoc

  class Token

    NO_TEXT = "??".freeze

    def initialize(line_no, char_no)
      @line_no = line_no
      @char_no = char_no
      @text    = NO_TEXT
    end
    # Because we're used in contexts that expect to return a token,
    # we set the text string and then return ourselves
    def set_text(text)
      @text = text
      self
    end

    attr_reader :line_no, :char_no, :text

  end

  # See rdoc/parsers/parse_f95.rb

  class Fortran95parser

    extend ParserFactory
    parse_files_matching(/\.((f|F)9(0|5)|F)$/)

    @@external_aliases = []
    @@public_methods   = []

    # "false":: Comments are below source code
    # "true" :: Comments are upper source code
    COMMENTS_ARE_UPPER  = false

    # Internal alias message
    INTERNAL_ALIAS_MES = "Alias for"

    # External alias message
    EXTERNAL_ALIAS_MES = "The entity is"

    # prepare to parse a Fortran 95 file
    def initialize(top_level, file_name, body, options, stats)
      @body = body
      @stats = stats
      @file_name  = file_name
      @options = options
      @top_level = top_level
      @progress = $stderr unless options.quiet
    end

    # define code constructs
    def scan

      # remove private comment
      remaining_code = remove_private_comments(@body)

      # continuation lines are united to one line
      remaining_code = united_to_one_line(remaining_code)

      # semicolons are replaced to line feed
      remaining_code = semicolon_to_linefeed(remaining_code)

      # collect comment for file entity
      whole_comment, remaining_code = collect_first_comment(remaining_code)
      @top_level.comment = whole_comment

      # String "remaining_code" is converted to Array "remaining_lines"
      remaining_lines = remaining_code.split("\n")

      # "module" or "program" parts are parsed (new)
      #
      level_depth = 0
      block_searching_flag = nil
      block_searching_lines = []
      pre_comment = []
      module_program_trailing = ""
      module_program_name = ""
      other_block_level_depth = 0
      other_block_searching_flag = nil
      remaining_lines.collect!{|line|
        if !block_searching_flag && !other_block_searching_flag
          if line =~ /^\s*?module\s+(\w+)\s*?(!.*?)?$/i
            block_searching_flag = :module
            block_searching_lines << line
            module_program_name = $1
            module_program_trailing = find_comments($2)
            next false
          elsif line =~ /^\s*?program\s+(\w+)\s*?(!.*?)?$/i ||
                 line =~ /^\s*?\w/ && !block_start?(line)
            block_searching_flag = :program
            block_searching_lines << line
            module_program_name = $1 || ""
            module_program_trailing = find_comments($2)
            next false

          elsif block_start?(line)
            other_block_searching_flag = true
            next line

          elsif line =~ /^\s*?!\s?(.*)/
            pre_comment << line
            next line
          else
            pre_comment = []
            next line
          end
        elsif other_block_searching_flag
          other_block_level_depth += 1 if block_start?(line)
          other_block_level_depth -= 1 if block_end?(line)
          if other_block_level_depth < 0
            other_block_level_depth = 0
            other_block_searching_flag = nil
          end
          next line
        end

        block_searching_lines << line
        level_depth += 1 if block_start?(line)
        level_depth -= 1 if block_end?(line)
        if level_depth >= 0
          next false
        end

        # "module_program_code" is formatted.
        # ":nodoc:" flag is checked.
        #
        module_program_code = block_searching_lines.join("\n")
        module_program_code = remove_empty_head_lines(module_program_code)
        if module_program_trailing =~ /^:nodoc:/
          # next loop to search next block
          level_depth = 0
          block_searching_flag = false
          block_searching_lines = []
          pre_comment = []
          next false
        end

        # NormalClass is created, and added to @top_level
        #
        if block_searching_flag == :module
          module_name = module_program_name
          module_code = module_program_code
          module_trailing = module_program_trailing
          progress "m"
          @stats.num_modules += 1
          f9x_module = @top_level.add_module NormalClass, module_name
          f9x_module.record_location @top_level

          f9x_comment = COMMENTS_ARE_UPPER ? 
            find_comments(pre_comment.join("\n"))  + "\n" + module_trailing :
              module_trailing + "\n" + find_comments(module_code.sub(/^.*$\n/i, ''))
          f9x_module.comment = f9x_comment
          parse_program_or_module(f9x_module, module_code)

          TopLevel.all_files.each do |name, toplevel|
            if toplevel.include_includes?(module_name, @options.ignore_case)
              if !toplevel.include_requires?(@file_name, @options.ignore_case)
                toplevel.add_require(Require.new(@file_name, ""))
              end
            end
            toplevel.each_classmodule{|m|
              if m.include_includes?(module_name, @options.ignore_case)
                if !m.include_requires?(@file_name, @options.ignore_case)
                  m.add_require(Require.new(@file_name, ""))
                end
              end
            }
          end
        elsif block_searching_flag == :program
          program_name = module_program_name
          program_code = module_program_code
          program_trailing = module_program_trailing
          progress "p"
          program_comment = COMMENTS_ARE_UPPER ? 
            find_comments(pre_comment.join("\n")) + "\n" + program_trailing : 
              program_trailing + "\n" + find_comments(program_code.sub(/^.*$\n/i, ''))
          program_comment = "\n\n= <i>Program</i> <tt>#{program_name}</tt>\n\n" \
                            + program_comment
          @top_level.comment << program_comment
          parse_program_or_module(@top_level, program_code, :private)
        end

        # next loop to search next block
        level_depth = 0
        block_searching_flag = false
        block_searching_lines = []
        pre_comment = []
        next false
      }

      remaining_lines.delete_if{ |line|
        line == false
      }

      # External subprograms and functions are parsed
      #
      parse_program_or_module(@top_level, remaining_lines.join("\n"),
                              :public, true)

      @top_level
    end  # End of scan

    private

    def parse_program_or_module(container, code,
                                visibility=:public, external=nil)
      return unless container
      return unless code
      remaining_lines = code.split("\n")
      remaining_code = "#{code}"

      #
      # Parse variables before "contains" in module
      #
      level_depth = 0
      before_contains_lines = []
      before_contains_code = nil
      before_contains_flag = nil
      remaining_lines.each{ |line|
        if !before_contains_flag
          if line =~ /^\s*?module\s+\w+\s*?(!.*?)?$/i
            before_contains_flag = true
          end
        else
          break if line =~ /^\s*?contains\s*?(!.*?)?$/i
          level_depth += 1 if block_start?(line)
          level_depth -= 1 if block_end?(line)
          break if level_depth < 0
          before_contains_lines << line
        end
      }
      before_contains_code = before_contains_lines.join("\n")
      if before_contains_code
        before_contains_code.gsub!(/^\s*?interface\s+.*?\s+end\s+interface.*?$/im, "")
        before_contains_code.gsub!(/^\s*?type[\s\,]+.*?\s+end\s+type.*?$/im, "")
      end

      #
      # Parse global "use"
      #
      use_check_code = "#{before_contains_code}"
      cascaded_modules_list = []
      while use_check_code =~ /^\s*?use\s+(\w+)(.*?)(!.*?)?$/i
        use_check_code = $~.pre_match
        use_check_code << $~.post_match
        used_mod_name = $1.strip.chomp
        used_list = $2 || ""
        used_trailing = $3 || ""
        next if used_trailing =~ /!:nodoc:/
        if !container.include_includes?(used_mod_name, @options.ignore_case)
          progress "."
          container.add_include Include.new(used_mod_name, "")
        end
        if ! (used_list =~ /\,\s*?only\s*?:/i )
          cascaded_modules_list << "\#" + used_mod_name
        end
      end

      #
      # Parse public and private, and store information.
      # This information is used when "add_method" and
      # "set_visibility_for" are called.
      #
      visibility_default, visibility_info = 
                parse_visibility(remaining_lines.join("\n"), visibility, container)
      @@public_methods.concat visibility_info
      if visibility_default == :public
        if !cascaded_modules_list.empty?
          cascaded_modules = 
            Attr.new("Cascaded Modules",
                     "Imported modules all of whose components are published again",
                     "",
                     cascaded_modules_list.join(", "))
          container.add_attribute(cascaded_modules)
        end
      end

      #
      # Check rename elements
      #
      use_check_code = "#{before_contains_code}"
      while use_check_code =~ /^\s*?use\s+(\w+)\s*?\,(.+)$/i
        use_check_code = $~.pre_match
        use_check_code << $~.post_match
        used_mod_name = $1.strip.chomp
        used_elements = $2.sub(/\s*?only\s*?:\s*?/i, '')
        used_elements.split(",").each{ |used|
          if /\s*?(\w+)\s*?=>\s*?(\w+)\s*?/ =~ used
            local = $1
            org = $2
            @@public_methods.collect!{ |pub_meth|
              if local == pub_meth["name"] ||
                  local.upcase == pub_meth["name"].upcase &&
                  @options.ignore_case
                pub_meth["name"] = org
                pub_meth["local_name"] = local
              end
              pub_meth
            }
          end
        }
      end

      #
      # Parse private "use"
      #
      use_check_code = remaining_lines.join("\n")
      while use_check_code =~ /^\s*?use\s+(\w+)(.*?)(!.*?)?$/i
        use_check_code = $~.pre_match
        use_check_code << $~.post_match
        used_mod_name = $1.strip.chomp
        used_trailing = $3 || ""
        next if used_trailing =~ /!:nodoc:/
        if !container.include_includes?(used_mod_name, @options.ignore_case)
          progress "."
          container.add_include Include.new(used_mod_name, "")
        end
      end

      container.each_includes{ |inc|
        TopLevel.all_files.each do |name, toplevel|
          indicated_mod = toplevel.find_symbol(inc.name,
                                               nil, @options.ignore_case)
          if indicated_mod
            indicated_name = indicated_mod.parent.file_relative_name
            if !container.include_requires?(indicated_name, @options.ignore_case)
              container.add_require(Require.new(indicated_name, ""))
            end
            break
          end
        end
      }

      #
      # Parse derived-types definitions
      #
      derived_types_comment = ""
      remaining_code = remaining_lines.join("\n")
      while remaining_code =~ /^\s*?
                                    type[\s\,]+(public|private)?\s*?(::)?\s*?
                                    (\w+)\s*?(!.*?)?$
                                    (.*?)
                                    ^\s*?end\s+type.*?$
                              /imx
        remaining_code = $~.pre_match
        remaining_code << $~.post_match
        typename = $3.chomp.strip
        type_elements = $5 || ""
        type_code = remove_empty_head_lines($&)
        type_trailing = find_comments($4)
        next if type_trailing =~ /^:nodoc:/
        type_visibility = $1
        type_comment = COMMENTS_ARE_UPPER ? 
          find_comments($~.pre_match) + "\n" + type_trailing :
            type_trailing + "\n" + find_comments(type_code.sub(/^.*$\n/i, ''))
        type_element_visibility_public = true
        type_code.split("\n").each{ |line|
          if /^\s*?private\s*?$/ =~ line
            type_element_visibility_public = nil
            break
          end
        } if type_code

        args_comment = ""
        type_args_info = nil

        if @options.show_all
          args_comment = find_arguments(nil, type_code, true)
        else
          type_public_args_list = []
          type_args_info = definition_info(type_code)
          type_args_info.each{ |arg|
            arg_is_public = type_element_visibility_public
            arg_is_public = true if arg.include_attr?("public")
            arg_is_public = nil if arg.include_attr?("private")
            type_public_args_list << arg.varname if arg_is_public
          }
          args_comment = find_arguments(type_public_args_list, type_code)
        end

        type = AnyMethod.new("type #{typename}", typename)
        type.singleton = false
        type.params = ""
        type.comment = "<b><em> Derived Type </em></b> :: <tt></tt>\n"
        type.comment << args_comment if args_comment
        type.comment << type_comment if type_comment
        progress "t"
        @stats.num_methods += 1
        container.add_method type

        set_visibility(container, typename, visibility_default, @@public_methods)

        if type_visibility
          type_visibility.gsub!(/\s/,'')
          type_visibility.gsub!(/\,/,'')
          type_visibility.gsub!(/:/,'')
          type_visibility.downcase!
          if type_visibility == "public"
            container.set_visibility_for([typename], :public)
          elsif type_visibility == "private"
            container.set_visibility_for([typename], :private)
          end
        end

        check_public_methods(type, container.name)

        if @options.show_all
          derived_types_comment << ", " unless derived_types_comment.empty?
          derived_types_comment << typename
        else
          if type.visibility == :public
          derived_types_comment << ", " unless derived_types_comment.empty?
          derived_types_comment << typename
          end
        end

      end

      if !derived_types_comment.empty?
        derived_types_table = 
          Attr.new("Derived Types", "Derived_Types", "", 
                   derived_types_comment)
        container.add_attribute(derived_types_table)
      end

      #
      # move interface scope
      #
      interface_code = ""
      while remaining_code =~ /^\s*?
                                   interface(
                                              \s+\w+                      |
                                              \s+operator\s*?\(.*?\)       |
                                              \s+assignment\s*?\(\s*?=\s*?\)
                                            )?\s*?$
                                   (.*?)
                                   ^\s*?end\s+interface.*?$
                              /imx
        interface_code << remove_empty_head_lines($&) + "\n"
        remaining_code = $~.pre_match
        remaining_code << $~.post_match
      end

      #
      # Parse global constants or variables in modules
      #
      const_var_defs = definition_info(before_contains_code)
      const_var_defs.each{|defitem|
        next if defitem.nodoc
        const_or_var_type = "Variable"
        const_or_var_progress = "v"
        if defitem.include_attr?("parameter")
          const_or_var_type = "Constant"
          const_or_var_progress = "c"
        end
        const_or_var = AnyMethod.new(const_or_var_type, defitem.varname)
        const_or_var.singleton = false
        const_or_var.params = ""
        self_comment = find_arguments([defitem.varname], before_contains_code)
        const_or_var.comment = "<b><em>" + const_or_var_type + "</em></b> :: <tt></tt>\n"
        const_or_var.comment << self_comment if self_comment
        progress const_or_var_progress
        @stats.num_methods += 1
        container.add_method const_or_var

        set_visibility(container, defitem.varname, visibility_default, @@public_methods)

        if defitem.include_attr?("public")
          container.set_visibility_for([defitem.varname], :public)
        elsif defitem.include_attr?("private")
          container.set_visibility_for([defitem.varname], :private)
        end

        check_public_methods(const_or_var, container.name)

      } if const_var_defs

      remaining_lines = remaining_code.split("\n")

      # "subroutine" or "function" parts are parsed (new)
      #
      level_depth = 0
      block_searching_flag = nil
      block_searching_lines = []
      pre_comment = []
      procedure_trailing = ""
      procedure_name = ""
      procedure_params = ""
      procedure_prefix = ""
      procedure_result_arg = ""
      procedure_type = ""
      contains_lines = []
      contains_flag = nil
      remaining_lines.collect!{|line|
        if !block_searching_flag
          # subroutine
          if line =~ /^\s*?
                           (recursive|pure|elemental)?\s*?
                           subroutine\s+(\w+)\s*?(\(.*?\))?\s*?(!.*?)?$
                     /ix
            block_searching_flag = :subroutine
            block_searching_lines << line

            procedure_name = $2.chomp.strip
            procedure_params = $3 || ""
            procedure_prefix = $1 || ""
            procedure_trailing = $4 || "!"
            next false

          # function
          elsif line =~ /^\s*?
                         (recursive|pure|elemental)?\s*?
                         (
                             character\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                           | type\s*?\([\w\s]+?\)\s+
                           | integer\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                           | real\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                           | double\s+precision\s+
                           | logical\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                           | complex\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                         )?
                         function\s+(\w+)\s*?
                         (\(.*?\))?(\s+result\((.*?)\))?\s*?(!.*?)?$
                        /ix
            block_searching_flag = :function
            block_searching_lines << line

            procedure_prefix = $1 || ""
            procedure_type = $2 ? $2.chomp.strip : nil
            procedure_name = $8.chomp.strip
            procedure_params = $9 || ""
            procedure_result_arg = $11 ? $11.chomp.strip : procedure_name
            procedure_trailing = $12 || "!"
            next false
          elsif line =~ /^\s*?!\s?(.*)/
            pre_comment << line
            next line
          else
            pre_comment = []
            next line
          end
        end
        contains_flag = true if line =~ /^\s*?contains\s*?(!.*?)?$/
        block_searching_lines << line
        contains_lines << line if contains_flag

        level_depth += 1 if block_start?(line)
        level_depth -= 1 if block_end?(line)
        if level_depth >= 0
          next false
        end

        # "procedure_code" is formatted.
        # ":nodoc:" flag is checked.
        #
        procedure_code = block_searching_lines.join("\n")
        procedure_code = remove_empty_head_lines(procedure_code)
        if procedure_trailing =~ /^!:nodoc:/
          # next loop to search next block
          level_depth = 0
          block_searching_flag = nil
          block_searching_lines = []
          pre_comment = []
          procedure_trailing = ""
          procedure_name = ""
          procedure_params = ""
          procedure_prefix = ""
          procedure_result_arg = ""
          procedure_type = ""
          contains_lines = []
          contains_flag = nil
          next false
        end

        # AnyMethod is created, and added to container
        #
        subroutine_function = nil
        if block_searching_flag == :subroutine
          subroutine_prefix   = procedure_prefix
          subroutine_name     = procedure_name
          subroutine_params   = procedure_params
          subroutine_trailing = procedure_trailing
          subroutine_code     = procedure_code

          subroutine_comment = COMMENTS_ARE_UPPER ? 
            pre_comment.join("\n") + "\n" + subroutine_trailing : 
              subroutine_trailing + "\n" + subroutine_code.sub(/^.*$\n/i, '')
          subroutine = AnyMethod.new("subroutine", subroutine_name)
          parse_subprogram(subroutine, subroutine_params,
                           subroutine_comment, subroutine_code,
                           before_contains_code, nil, subroutine_prefix)
          progress "s"
          @stats.num_methods += 1
          container.add_method subroutine
          subroutine_function = subroutine

        elsif block_searching_flag == :function
          function_prefix     = procedure_prefix
          function_type       = procedure_type
          function_name       = procedure_name
          function_params_org = procedure_params
          function_result_arg = procedure_result_arg
          function_trailing   = procedure_trailing
          function_code_org   = procedure_code

          function_comment = COMMENTS_ARE_UPPER ?
            pre_comment.join("\n") + "\n" + function_trailing :
              function_trailing + "\n " + function_code_org.sub(/^.*$\n/i, '')

          function_code = "#{function_code_org}"
          if function_type
            function_code << "\n" + function_type + " :: " + function_result_arg
          end

          function_params =
            function_params_org.sub(/^\(/, "\(#{function_result_arg}, ")

          function = AnyMethod.new("function", function_name)
          parse_subprogram(function, function_params,
                           function_comment, function_code,
                           before_contains_code, true, function_prefix)

          # Specific modification due to function
          function.params.sub!(/\(\s*?#{function_result_arg}\s*?,\s*?/, "\( ")
          function.params << " result(" + function_result_arg + ")"
          function.start_collecting_tokens
          function.add_token Token.new(1,1).set_text(function_code_org)

          progress "f"
          @stats.num_methods += 1
          container.add_method function
          subroutine_function = function

        end

        # The visibility of procedure is specified
        #
        set_visibility(container, procedure_name, 
                       visibility_default, @@public_methods)

        # The alias for this procedure from external modules
        #
        check_external_aliases(procedure_name,
                               subroutine_function.params,
                               subroutine_function.comment, subroutine_function) if external
        check_public_methods(subroutine_function, container.name)


        # contains_lines are parsed as private procedures
        if contains_flag
          parse_program_or_module(container,
                                  contains_lines.join("\n"), :private)
        end

        # next loop to search next block
        level_depth = 0
        block_searching_flag = nil
        block_searching_lines = []
        pre_comment = []
        procedure_trailing = ""
        procedure_name = ""
        procedure_params = ""
        procedure_prefix = ""
        procedure_result_arg = ""
        contains_lines = []
        contains_flag = nil
        next false
      } # End of remaining_lines.collect!{|line|

      # Array remains_lines is converted to String remains_code again
      #
      remaining_code = remaining_lines.join("\n")

      #
      # Parse interface
      #
      interface_scope = false
      generic_name = ""
      interface_code.split("\n").each{ |line|
        if /^\s*?
                 interface(
                            \s+\w+|
                            \s+operator\s*?\(.*?\)|
                            \s+assignment\s*?\(\s*?=\s*?\)
                          )?
                 \s*?(!.*?)?$
           /ix =~ line
          generic_name = $1 ? $1.strip.chomp : nil
          interface_trailing = $2 || "!"
          interface_scope = true
          interface_scope = false if interface_trailing =~ /!:nodoc:/
#          if generic_name =~ /operator\s*?\((.*?)\)/i
#            operator_name = $1
#            if operator_name && !operator_name.empty?
#              generic_name = "#{operator_name}"
#            end
#          end
#          if generic_name =~ /assignment\s*?\((.*?)\)/i
#            assignment_name = $1
#            if assignment_name && !assignment_name.empty?
#              generic_name = "#{assignment_name}"
#            end
#          end
        end
        if /^\s*?end\s+interface/i =~ line
          interface_scope = false
          generic_name = nil
        end
        # internal alias
        if interface_scope && /^\s*?module\s+procedure\s+(.*?)(!.*?)?$/i =~ line
          procedures = $1.strip.chomp
          procedures_trailing = $2 || "!"
          next if procedures_trailing =~ /!:nodoc:/
          procedures.split(",").each{ |proc|
            proc.strip!
            proc.chomp!
            next if generic_name == proc || !generic_name
            old_meth = container.find_symbol(proc, nil, @options.ignore_case)
            next if !old_meth
            nolink = old_meth.visibility == :private ? true : nil
            nolink = nil if @options.show_all
            new_meth = 
               initialize_external_method(generic_name, proc, 
                                          old_meth.params, nil, 
                                          old_meth.comment, 
                                          old_meth.clone.token_stream[0].text, 
                                          true, nolink)
            new_meth.singleton = old_meth.singleton

            progress "i"
            @stats.num_methods += 1
            container.add_method new_meth

            set_visibility(container, generic_name, visibility_default, @@public_methods)

            check_public_methods(new_meth, container.name)

          }
        end

        # external aliases
        if interface_scope
          # subroutine
          proc = nil
          params = nil
          procedures_trailing = nil
          if line =~ /^\s*?
                           (recursive|pure|elemental)?\s*?
                           subroutine\s+(\w+)\s*?(\(.*?\))?\s*?(!.*?)?$
                     /ix
            proc = $2.chomp.strip
            generic_name = proc unless generic_name
            params = $3 || ""
            procedures_trailing = $4 || "!"

          # function
          elsif line =~ /^\s*?
                         (recursive|pure|elemental)?\s*?
                         (
                             character\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                           | type\s*?\([\w\s]+?\)\s+
                           | integer\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                           | real\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                           | double\s+precision\s+
                           | logical\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                           | complex\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                         )?
                         function\s+(\w+)\s*?
                         (\(.*?\))?(\s+result\((.*?)\))?\s*?(!.*?)?$
                        /ix
            proc = $8.chomp.strip
            generic_name = proc unless generic_name
            params = $9 || ""
            procedures_trailing = $12 || "!"
          else
            next
          end
          next if procedures_trailing =~ /!:nodoc:/
          indicated_method = nil
          indicated_file   = nil
          TopLevel.all_files.each do |name, toplevel|
            indicated_method = toplevel.find_local_symbol(proc, @options.ignore_case)
            indicated_file = name
            break if indicated_method
          end

          if indicated_method
            external_method = 
              initialize_external_method(generic_name, proc, 
                                         indicated_method.params, 
                                         indicated_file, 
                                         indicated_method.comment)

            progress "e"
            @stats.num_methods += 1
            container.add_method external_method
            set_visibility(container, generic_name, visibility_default, @@public_methods)
            if !container.include_requires?(indicated_file, @options.ignore_case)
              container.add_require(Require.new(indicated_file, ""))
            end
            check_public_methods(external_method, container.name)

          else
            @@external_aliases << {
              "new_name"  => generic_name,
              "old_name"  => proc,
              "file_or_module" => container,
              "visibility" => find_visibility(container, generic_name, @@public_methods) || visibility_default
            }
          end
        end

      } if interface_code # End of interface_code.split("\n").each ...

      #
      # Already imported methods are removed from @@public_methods.
      # Remainders are assumed to be imported from other modules.
      #
      @@public_methods.delete_if{ |method| method["entity_is_discovered"]}

      @@public_methods.each{ |pub_meth|
        next unless pub_meth["file_or_module"].name == container.name
        pub_meth["used_modules"].each{ |used_mod|
          TopLevel.all_classes_and_modules.each{ |modules|
            if modules.name == used_mod ||
                modules.name.upcase == used_mod.upcase &&
                @options.ignore_case
              modules.method_list.each{ |meth|
                if meth.name == pub_meth["name"] ||
                    meth.name.upcase == pub_meth["name"].upcase &&
                    @options.ignore_case
                  new_meth = initialize_public_method(meth,
                                                      modules.name)
                  if pub_meth["local_name"]
                    new_meth.name = pub_meth["local_name"]
                  end
                  progress "e"
                  @stats.num_methods += 1
                  container.add_method new_meth
                end
              }
            end
          }
        }
      }

      container
    end  # End of parse_program_or_module

    #
    # Parse arguments, comment, code of subroutine and function.
    # Return AnyMethod object.
    #
    def parse_subprogram(subprogram, params, comment, code, 
                         before_contains=nil, function=nil, prefix=nil)
      subprogram.singleton = false
      prefix = "" if !prefix
      arguments = params.sub(/\(/, "").sub(/\)/, "").split(",") if params
      args_comment, params_opt = 
        find_arguments(arguments, code.sub(/^s*?contains\s*?(!.*?)?$.*/im, ""),
                       nil, nil, true)
      params_opt = "( " + params_opt + " ) " if params_opt
      subprogram.params = params_opt || ""
      namelist_comment = find_namelists(code, before_contains)

      block_comment = find_comments comment
      if function
        subprogram.comment = "<b><em> Function </em></b> :: <em>#{prefix}</em>\n"
      else
        subprogram.comment = "<b><em> Subroutine </em></b> :: <em>#{prefix}</em>\n"
      end
      subprogram.comment << args_comment if args_comment
      subprogram.comment << block_comment if block_comment
      subprogram.comment << namelist_comment if namelist_comment

      # For output source code
      subprogram.start_collecting_tokens
      subprogram.add_token Token.new(1,1).set_text(code)

      subprogram
    end

    #
    # Collect comment for file entity
    #
    def collect_first_comment(body)
      comment = ""
      not_comment = ""
      comment_start = false
      comment_end   = false
      body.split("\n").each{ |line|
        if comment_end
          not_comment << line
          not_comment << "\n"
        elsif /^\s*?!\s?(.*)$/i =~ line
          comment_start = true
          comment << $1
          comment << "\n"
        elsif /^\s*?$/i =~ line
          comment_end = true if comment_start && COMMENTS_ARE_UPPER
        else
          comment_end = true
          not_comment << line
          not_comment << "\n"
        end
      }
      return comment, not_comment
    end


    # Return comments of definitions of arguments
    #
    # If "all" argument is true, information of all arguments are returned.
    # If "modified_params" is true, list of arguments are decorated,
    # for example, optional arguments are parenthetic as "[arg]".
    #
    def find_arguments(args, text, all=nil, indent=nil, modified_params=nil)
      return unless args || all
      indent = "" unless indent
      args = ["all"] if all
      params = "" if modified_params
      comma = ""
      return unless text
      args_rdocforms = "\n"
      remaining_lines = "#{text}"
      definitions = definition_info(remaining_lines)
      args.each{ |arg|
        arg.strip!
        arg.chomp!
        definitions.each { |defitem|
          if arg == defitem.varname.strip.chomp || all
            args_rdocforms << <<-"EOF"

#{indent}<tt><b>#{defitem.varname.chomp.strip}#{defitem.arraysuffix}</b> #{defitem.inivalue}</tt> :: 
#{indent}   <tt>#{defitem.types.chomp.strip}</tt>
EOF
            if !defitem.comment.chomp.strip.empty?
              comment = ""
              defitem.comment.split("\n").each{ |line|
                comment << "       " + line + "\n"
              }
              args_rdocforms << <<-"EOF"

#{indent}   <tt></tt> :: 
#{indent}       <tt></tt>
#{indent}       #{comment.chomp.strip}
EOF
            end

            if modified_params
              if defitem.include_attr?("optional")
                params << "#{comma}[#{arg}]"
              else
                params << "#{comma}#{arg}"
              end
              comma = ", "
            end
          end
        }
      }
      if modified_params
        return args_rdocforms, params
      else
        return args_rdocforms
      end
    end

    # Return comments of definitions of namelists
    #
    def find_namelists(text, before_contains=nil)
      return nil if !text
      result = ""
      lines = "#{text}"
      before_contains = "" if !before_contains
      while lines =~ /^\s*?namelist\s+\/\s*?(\w+)\s*?\/([\s\w\,]+)$/i
        lines = $~.post_match
        nml_comment = COMMENTS_ARE_UPPER ? 
            find_comments($~.pre_match) : find_comments($~.post_match)
        nml_name = $1
        nml_args = $2.split(",")
        result << "\n\n=== NAMELIST <tt><b>" + nml_name + "</tt></b>\n\n"
        result << nml_comment + "\n" if nml_comment
        if lines.split("\n")[0] =~ /^\//i
          lines = "namelist " + lines
        end
        result << find_arguments(nml_args, "#{text}" + "\n" + before_contains)
      end
      return result
    end

    #
    # Comments just after module or subprogram, or arguments are
    # returned. If "COMMENTS_ARE_UPPER" is true, comments just before
    # modules or subprograms are returned
    #
    def find_comments text
      return "" unless text
      lines = text.split("\n")
      lines.reverse! if COMMENTS_ARE_UPPER
      comment_block = Array.new
      lines.each do |line|
        break if line =~ /^\s*?\w/ || line =~ /^\s*?$/
        if COMMENTS_ARE_UPPER
          comment_block.unshift line.sub(/^\s*?!\s?/,"")
        else
          comment_block.push line.sub(/^\s*?!\s?/,"")
        end
      end
      nice_lines = comment_block.join("\n").split "\n\s*?\n"
      nice_lines[0] ||= ""
      nice_lines.shift
    end

    def progress(char)
      unless @options.quiet
        @progress.print(char)
        @progress.flush
      end
    end

    #
    # Create method for internal alias
    #
    def initialize_public_method(method, parent)
      return if !method || !parent

      new_meth = AnyMethod.new("External Alias for module", method.name)
      new_meth.singleton    = method.singleton
      new_meth.params       = method.params.clone
      new_meth.comment      = remove_trailing_alias(method.comment.clone)
      new_meth.comment      << "\n\n#{EXTERNAL_ALIAS_MES} #{parent.strip.chomp}\##{method.name}"

      return new_meth
    end

    #
    # Create method for external alias
    #
    # If argument "internal" is true, file is ignored.
    #
    def initialize_external_method(new, old, params, file, comment, token=nil,
                                   internal=nil, nolink=nil)
      return nil unless new || old

      if internal
        external_alias_header = "#{INTERNAL_ALIAS_MES} "
        external_alias_text   = external_alias_header + old 
      elsif file
        external_alias_header = "#{EXTERNAL_ALIAS_MES} "
        external_alias_text   = external_alias_header + file + "#" + old
      else
        return nil
      end
      external_meth = AnyMethod.new(external_alias_text, new)
      external_meth.singleton    = false
      external_meth.params       = params
      external_comment = remove_trailing_alias(comment) + "\n\n" if comment
      external_meth.comment = external_comment || ""
      if nolink && token
        external_meth.start_collecting_tokens
        external_meth.add_token Token.new(1,1).set_text(token)
      else
        external_meth.comment << external_alias_text
      end

      return external_meth
    end



    #
    # Parse visibility
    #
    def parse_visibility(code, default, container)
      result = []
      visibility_default = default || :public

      used_modules = []
      container.includes.each{|i| used_modules << i.name} if container

      remaining_code = code.gsub(/^\s*?type[\s\,]+.*?\s+end\s+type.*?$/im, "")
      remaining_code.split("\n").each{ |line|
        if /^\s*?private\s*?$/ =~ line
          visibility_default = :private
          break
        end
      } if remaining_code

      remaining_code.split("\n").each{ |line|
        if /^\s*?private\s*?(::)?\s+(.*)\s*?(!.*?)?/i =~ line
          methods = $2.sub(/!.*$/, '')
          methods.split(",").each{ |meth|
            meth.sub!(/!.*$/, '')
            meth.gsub!(/:/, '')
            result << {
              "name" => meth.chomp.strip,
              "visibility" => :private,
              "used_modules" => used_modules.clone,
              "file_or_module" => container,
              "entity_is_discovered" => nil,
              "local_name" => nil
            }
          }
        elsif /^\s*?public\s*?(::)?\s+(.*)\s*?(!.*?)?/i =~ line
          methods = $2.sub(/!.*$/, '')
          methods.split(",").each{ |meth|
            meth.sub!(/!.*$/, '')
            meth.gsub!(/:/, '')
            result << {
              "name" => meth.chomp.strip,
              "visibility" => :public,
              "used_modules" => used_modules.clone,
              "file_or_module" => container,
              "entity_is_discovered" => nil,
              "local_name" => nil
            }
          }
        end
      } if remaining_code

      if container
        result.each{ |vis_info|
          vis_info["parent"] = container.name
        }
      end

      return visibility_default, result
    end

    #
    # Set visibility
    #
    # "subname" element of "visibility_info" is deleted.
    #
    def set_visibility(container, subname, visibility_default, visibility_info)
      return unless container || subname || visibility_default || visibility_info
      not_found = true
      visibility_info.collect!{ |info|
        if info["name"] == subname ||
            @options.ignore_case && info["name"].upcase == subname.upcase
          if info["file_or_module"].name == container.name
            container.set_visibility_for([subname], info["visibility"])
            info["entity_is_discovered"] = true
            not_found = false
          end
        end
        info
      }
      if not_found
        return container.set_visibility_for([subname], visibility_default)
      else
        return container
      end
    end

    #
    # Find visibility
    #
    def find_visibility(container, subname, visibility_info)
      return nil if !subname || !visibility_info
      visibility_info.each{ |info|
        if info["name"] == subname ||
            @options.ignore_case && info["name"].upcase == subname.upcase
          if info["parent"] == container.name
            return info["visibility"]
          end
        end
      }
      return nil
    end

    #
    # Check external aliases
    #
    def check_external_aliases(subname, params, comment, test=nil)
      @@external_aliases.each{ |alias_item|
        if subname == alias_item["old_name"] ||
                    subname.upcase == alias_item["old_name"].upcase &&
                            @options.ignore_case

          new_meth = initialize_external_method(alias_item["new_name"], 
                                                subname, params, @file_name, 
                                                comment)
          new_meth.visibility = alias_item["visibility"]

          progress "e"
          @stats.num_methods += 1
          alias_item["file_or_module"].add_method(new_meth)

          if !alias_item["file_or_module"].include_requires?(@file_name, @options.ignore_case)
            alias_item["file_or_module"].add_require(Require.new(@file_name, ""))
          end
        end
      }
    end

    #
    # Check public_methods
    #
    def check_public_methods(method, parent)
      return if !method || !parent
      @@public_methods.each{ |alias_item|
        parent_is_used_module = nil
        alias_item["used_modules"].each{ |used_module|
          if used_module == parent ||
              used_module.upcase == parent.upcase &&
              @options.ignore_case
            parent_is_used_module = true
          end
        }
        next if !parent_is_used_module

        if method.name == alias_item["name"] ||
            method.name.upcase == alias_item["name"].upcase &&
            @options.ignore_case

          new_meth = initialize_public_method(method, parent)
          if alias_item["local_name"]
            new_meth.name = alias_item["local_name"]
          end

          progress "e"
          @stats.num_methods += 1
          alias_item["file_or_module"].add_method new_meth
        end
      }
    end

    #
    # Continuous lines are united.
    #
    # Comments in continuous lines are removed.
    #
    def united_to_one_line(f90src)
      return "" unless f90src
      lines = f90src.split("\n")
      previous_continuing = false
      now_continuing = false
      body = ""
      lines.each{ |line|
        words = line.split("")
        next if words.empty? && previous_continuing
        commentout = false
        brank_flag = true ; brank_char = ""
        squote = false    ; dquote = false
        ignore = false
        words.collect! { |char|
          if previous_continuing && brank_flag
            now_continuing = true
            ignore         = true
            case char
            when "!"                       ; break
            when " " ; brank_char << char  ; next ""
            when "&"
              brank_flag = false
              now_continuing = false
              next ""
            else 
              brank_flag     = false
              now_continuing = false
              ignore         = false
              next brank_char + char
            end
          end
          ignore = false

          if now_continuing
            next ""
          elsif !(squote) && !(dquote) && !(commentout)
            case char
            when "!" ; commentout = true     ; next char
            when "\""; dquote = true         ; next char
            when "\'"; squote = true         ; next char
            when "&" ; now_continuing = true ; next ""
            else next char
            end
          elsif commentout
            next char
          elsif squote
            case char
            when "\'"; squote = false ; next char
            else next char
            end
          elsif dquote
            case char
            when "\""; dquote = false ; next char
            else next char
            end
          end
        }
        if !ignore && !previous_continuing || !brank_flag
          if previous_continuing
            body << words.join("")
          else
            body << "\n" + words.join("")
          end
        end
        previous_continuing = now_continuing ? true : nil
        now_continuing = nil
      }
      return body
    end


    #
    # Continuous line checker
    #
    def continuous_line?(line)
      continuous = false
      if /&\s*?(!.*)?$/ =~ line
        continuous = true
        if comment_out?($~.pre_match)
          continuous = false
        end
      end
      return continuous
    end

    #
    # Comment out checker
    #
    def comment_out?(line)
      return nil unless line
      commentout = false
      squote = false ; dquote = false
      line.split("").each { |char|
        if !(squote) && !(dquote)
          case char
          when "!" ; commentout = true ; break
          when "\""; dquote = true
          when "\'"; squote = true
          else next
          end
        elsif squote
          case char
          when "\'"; squote = false
          else next
          end
        elsif dquote
          case char
          when "\""; dquote = false
          else next
          end
        end
      }
      return commentout
    end

    #
    # Semicolons are replaced to line feed.
    #
    def semicolon_to_linefeed(text)
      return "" unless text
      lines = text.split("\n")
      lines.collect!{ |line|
        words = line.split("")
        commentout = false
        squote = false ; dquote = false
        words.collect! { |char|
          if !(squote) && !(dquote) && !(commentout)
            case char
            when "!" ; commentout = true ; next char
            when "\""; dquote = true     ; next char
            when "\'"; squote = true     ; next char
            when ";" ;                     "\n"
            else next char
            end
          elsif commentout
            next char
          elsif squote
            case char
            when "\'"; squote = false ; next char
            else next char
            end
          elsif dquote
            case char
            when "\""; dquote = false ; next char
            else next char
            end
          end
        }
        words.join("")
      }
      return lines.join("\n")
    end

    #
    # Which "line" is start of block (module, program, block data,
    # subroutine, function) statement ?
    #
    def block_start?(line)
      return nil if !line

      if line =~ /^\s*?module\s+(\w+)\s*?(!.*?)?$/i    ||
          line =~ /^\s*?program\s+(\w+)\s*?(!.*?)?$/i  ||
          line =~ /^\s*?block\s+data(\s+\w+)?\s*?(!.*?)?$/i     ||
          line =~ \
                  /^\s*?
                   (recursive|pure|elemental)?\s*?
                   subroutine\s+(\w+)\s*?(\(.*?\))?\s*?(!.*?)?$
                  /ix ||
          line =~ \
                  /^\s*?
                   (recursive|pure|elemental)?\s*?
                   (
                       character\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                     | type\s*?\([\w\s]+?\)\s+
                     | integer\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                     | real\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                     | double\s+precision\s+
                     | logical\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                     | complex\s*?(\([\w\s\=\(\)\*]+?\))?\s+
                   )?
                   function\s+(\w+)\s*?
                   (\(.*?\))?(\s+result\((.*?)\))?\s*?(!.*?)?$
                  /ix
        return true
      end

      return nil
    end

    #
    # Which "line" is end of block (module, program, block data,
    # subroutine, function) statement ?
    #
    def block_end?(line)
      return nil if !line

      if line =~ /^\s*?end\s*?(!.*?)?$/i                 ||
          line =~ /^\s*?end\s+module(\s+\w+)?\s*?(!.*?)?$/i       ||
          line =~ /^\s*?end\s+program(\s+\w+)?\s*?(!.*?)?$/i      ||
          line =~ /^\s*?end\s+block\s+data(\s+\w+)?\s*?(!.*?)?$/i  ||
          line =~ /^\s*?end\s+subroutine(\s+\w+)?\s*?(!.*?)?$/i   ||
          line =~ /^\s*?end\s+function(\s+\w+)?\s*?(!.*?)?$/i
        return true
      end

      return nil
    end

    #
    # Remove "Alias for" in end of comments
    #
    def remove_trailing_alias(text)
      return "" if !text
      lines = text.split("\n").reverse
      comment_block = Array.new
      checked = false
      lines.each do |line|
        if !checked 
          if /^\s?#{INTERNAL_ALIAS_MES}/ =~ line ||
              /^\s?#{EXTERNAL_ALIAS_MES}/ =~ line
            checked = true
            next
          end
        end
        comment_block.unshift line
      end
      nice_lines = comment_block.join("\n")
      nice_lines ||= ""
      return nice_lines
    end

    # Empty lines in header are removed
    def remove_empty_head_lines(text)
      return "" unless text
      lines = text.split("\n")
      header = true
      lines.delete_if{ |line|
        header = false if /\S/ =~ line
        header && /^\s*?$/ =~ line
      }
      lines.join("\n")
    end


    # header marker "=", "==", ... are removed
    def remove_header_marker(text)
      return text.gsub(/^\s?(=+)/, '<tt></tt>\1')
    end

    def remove_private_comments(body)
      body.gsub!(/^\s*!--\s*?$.*?^\s*!\+\+\s*?$/m, '')
      return body
    end


    #
    # Information of arguments of subroutines and functions in Fortran95
    #
    class Fortran95Definition

      # Name of variable
      #
      attr_reader   :varname

      # Types of variable
      #
      attr_reader   :types

      # Initial Value
      #
      attr_reader   :inivalue

      # Suffix of array
      #
      attr_reader   :arraysuffix

      # Comments
      #
      attr_accessor   :comment

      # Flag of non documentation
      #
      attr_accessor   :nodoc

      def initialize(varname, types, inivalue, arraysuffix, comment,
                     nodoc=false)
        @varname = varname
        @types = types
        @inivalue = inivalue
        @arraysuffix = arraysuffix
        @comment = comment
        @nodoc = nodoc
      end

      def to_s
        return <<-EOF
<Fortran95Definition: 
  varname=#{@varname}, types=#{types},
  inivalue=#{@inivalue}, arraysuffix=#{@arraysuffix}, nodoc=#{@nodoc}, 
  comment=
#{@comment}
>
EOF
      end

      #
      # If attr is included, true is returned
      #
      def include_attr?(attr)
        return if !attr
        @types.split(",").each{ |type|
          return true if type.strip.chomp.upcase == attr.strip.chomp.upcase
        }
        return nil
      end

    end # End of Fortran95Definition

    #
    # Parse string argument "text", and Return Array of
    # Fortran95Definition object
    #
    def definition_info(text)
      return nil unless text
      lines = "#{text}"
      defs = Array.new
      comment = ""
      trailing_comment = ""
      under_comment_valid = false
      lines.split("\n").each{ |line|
        if /^\s*?!\s?(.*)/ =~ line
          if COMMENTS_ARE_UPPER
            comment << remove_header_marker($1)
            comment << "\n"
          elsif defs[-1] && under_comment_valid
            defs[-1].comment << "\n"
            defs[-1].comment << remove_header_marker($1)
          end
          next
        elsif /^\s*?$/ =~ line
          comment = ""
          under_comment_valid = false
          next
        end
        type = ""
        characters = ""
        if line =~ /^\s*?
                    (
                        character\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]*
                      | type\s*?\([\w\s]+?\)[\s\,]*
                      | integer\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]*
                      | real\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]*
                      | double\s+precision[\s\,]*
                      | logical\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]*
                      | complex\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]*
                    )
                    (.*?::)?
                    (.+)$
                   /ix
          characters = $8
          type = $1
          type << $7.gsub(/::/, '').gsub(/^\s*?\,/, '') if $7
        else
          under_comment_valid = false
          next
        end
        squote = false ; dquote = false ; bracket = 0
        iniflag = false; commentflag = false
        varname = "" ; arraysuffix = "" ; inivalue = ""
        start_pos = defs.size
        characters.split("").each { |char|
          if !(squote) && !(dquote) && bracket <= 0 && !(iniflag) && !(commentflag)
            case char
            when "!" ; commentflag = true
            when "(" ; bracket += 1       ; arraysuffix = char
            when "\""; dquote = true
            when "\'"; squote = true
            when "=" ; iniflag = true     ; inivalue << char
            when ","
              defs << Fortran95Definition.new(varname, type, inivalue, arraysuffix, comment)
              varname = "" ; arraysuffix = "" ; inivalue = ""
              under_comment_valid = true
            when " " ; next
            else     ; varname << char
            end
          elsif commentflag
            comment << remove_header_marker(char)
            trailing_comment << remove_header_marker(char)
          elsif iniflag
            if dquote
              case char
              when "\"" ; dquote = false ; inivalue << char
              else      ; inivalue << char
              end
            elsif squote
              case char
              when "\'" ; squote = false ; inivalue << char
              else      ; inivalue << char
              end
            elsif bracket > 0
              case char
              when "(" ; bracket += 1 ; inivalue << char
              when ")" ; bracket -= 1 ; inivalue << char
              else     ; inivalue << char
              end
            else
              case char
              when ","
                defs << Fortran95Definition.new(varname, type, inivalue, arraysuffix, comment)
                varname = "" ; arraysuffix = "" ; inivalue = ""
                iniflag = false
                under_comment_valid = true
              when "(" ; bracket += 1 ; inivalue << char
              when "\""; dquote = true  ; inivalue << char
              when "\'"; squote = true  ; inivalue << char
              when "!" ; commentflag = true
              else     ; inivalue << char
              end
            end
          elsif !(squote) && !(dquote) && bracket > 0
            case char
            when "(" ; bracket += 1 ; arraysuffix << char
            when ")" ; bracket -= 1 ; arraysuffix << char
            else     ; arraysuffix << char
            end
          elsif squote
            case char
            when "\'"; squote = false ; inivalue << char
            else     ; inivalue << char
            end
          elsif dquote
            case char
            when "\""; dquote = false ; inivalue << char
            else     ; inivalue << char
            end
          end
        }
        defs << Fortran95Definition.new(varname, type, inivalue, arraysuffix, comment)
        if trailing_comment =~ /^:nodoc:/
          defs[start_pos..-1].collect!{ |defitem|
            defitem.nodoc = true
          }
        end
        varname = "" ; arraysuffix = "" ; inivalue = ""
        comment = ""
        under_comment_valid = true
        trailing_comment = ""
      }
      return defs
    end


  end # class Fortran95parser

end # module RDoc
PK     Z\R|Ka  a    rdoc/parsers/parse_c.rbnu [        # Classes and modules built in to the interpreter. We need
# these to define superclasses of user objects

require "rdoc/code_objects"
require "rdoc/parsers/parserfactory"
require "rdoc/options"
require "rdoc/rdoc"

module RDoc

  ##
  # Ruby's built-in classes.

  KNOWN_CLASSES = {
    "rb_cObject"           => "Object",
    "rb_cArray"            => "Array",
    "rb_cBignum"           => "Bignum",
    "rb_cClass"            => "Class",
    "rb_cDir"              => "Dir",
    "rb_cData"             => "Data",
    "rb_cFalseClass"       => "FalseClass",
    "rb_cFile"             => "File",
    "rb_cFixnum"           => "Fixnum",
    "rb_cFloat"            => "Float",
    "rb_cHash"             => "Hash",
    "rb_cInteger"          => "Integer",
    "rb_cIO"               => "IO",
    "rb_cModule"           => "Module",
    "rb_cNilClass"         => "NilClass",
    "rb_cNumeric"          => "Numeric",
    "rb_cProc"             => "Proc",
    "rb_cRange"            => "Range",
    "rb_cRegexp"           => "Regexp",
    "rb_cString"           => "String",
    "rb_cSymbol"           => "Symbol",
    "rb_cThread"           => "Thread",
    "rb_cTime"             => "Time",
    "rb_cTrueClass"        => "TrueClass",
    "rb_cStruct"           => "Struct",
    "rb_eException"        => "Exception",
    "rb_eStandardError"    => "StandardError",
    "rb_eSystemExit"       => "SystemExit",
    "rb_eInterrupt"        => "Interrupt",
    "rb_eSignal"           => "Signal",
    "rb_eFatal"            => "Fatal",
    "rb_eArgError"         => "ArgError",
    "rb_eEOFError"         => "EOFError",
    "rb_eIndexError"       => "IndexError",
    "rb_eRangeError"       => "RangeError",
    "rb_eIOError"          => "IOError",
    "rb_eRuntimeError"     => "RuntimeError",
    "rb_eSecurityError"    => "SecurityError",
    "rb_eSystemCallError"  => "SystemCallError",
    "rb_eTypeError"        => "TypeError",
    "rb_eZeroDivError"     => "ZeroDivError",
    "rb_eNotImpError"      => "NotImpError",
    "rb_eNoMemError"       => "NoMemError",
    "rb_eFloatDomainError" => "FloatDomainError",
    "rb_eScriptError"      => "ScriptError",
    "rb_eNameError"        => "NameError",
    "rb_eSyntaxError"      => "SyntaxError",
    "rb_eLoadError"        => "LoadError",

    "rb_mKernel"           => "Kernel",
    "rb_mComparable"       => "Comparable",
    "rb_mEnumerable"       => "Enumerable",
    "rb_mPrecision"        => "Precision",
    "rb_mErrno"            => "Errno",
    "rb_mFileTest"         => "FileTest",
    "rb_mGC"               => "GC",
    "rb_mMath"             => "Math",
    "rb_mProcess"          => "Process"
  }

  ##
  # We attempt to parse C extension files. Basically we look for
  # the standard patterns that you find in extensions: <tt>rb_define_class,
  # rb_define_method</tt> and so on. We also try to find the corresponding
  # C source for the methods and extract comments, but if we fail
  # we don't worry too much.
  #
  # The comments associated with a Ruby method are extracted from the C
  # comment block associated with the routine that _implements_ that
  # method, that is to say the method whose name is given in the
  # <tt>rb_define_method</tt> call. For example, you might write:
  #
  #  /*
  #   * Returns a new array that is a one-dimensional flattening of this
  #   * array (recursively). That is, for every element that is an array,
  #   * extract its elements into the new array.
  #   *
  #   *    s = [ 1, 2, 3 ]           #=> [1, 2, 3]
  #   *    t = [ 4, 5, 6, [7, 8] ]   #=> [4, 5, 6, [7, 8]]
  #   *    a = [ s, t, 9, 10 ]       #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
  #   *    a.flatten                 #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  #   */
  #   static VALUE
  #   rb_ary_flatten(ary)
  #       VALUE ary;
  #   {
  #       ary = rb_obj_dup(ary);
  #       rb_ary_flatten_bang(ary);
  #       return ary;
  #   }
  #
  #   ...
  #
  #   void
  #   Init_Array()
  #   {
  #     ...
  #     rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0);
  #
  # Here RDoc will determine from the rb_define_method line that there's a
  # method called "flatten" in class Array, and will look for the implementation
  # in the method rb_ary_flatten. It will then use the comment from that
  # method in the HTML output. This method must be in the same source file
  # as the rb_define_method.
  #
  # C classes can be diagrammed (see /tc/dl/ruby/ruby/error.c), and RDoc
  # integrates C and Ruby source into one tree
  #
  # The comment blocks may include special directives:
  #
  # [Document-class: <i>name</i>]
  #   This comment block is documentation for the given class. Use this
  #   when the <tt>Init_xxx</tt> method is not named after the class.
  #
  # [Document-method: <i>name</i>]
  #   This comment documents the named method. Use when RDoc cannot
  #   automatically find the method from it's declaration
  #
  # [call-seq:  <i>text up to an empty line</i>]
  #   Because C source doesn't give descriptive names to Ruby-level parameters,
  #   you need to document the calling sequence explicitly
  #
  # In addition, RDoc assumes by default that the C method implementing a 
  # Ruby function is in the same source file as the rb_define_method call.
  # If this isn't the case, add the comment 
  #
  #    rb_define_method(....);  // in: filename
  #
  # As an example, we might have an extension that defines multiple classes
  # in its Init_xxx method. We could document them using
  #
  #  
  #  /*
  #   * Document-class:  MyClass
  #   *
  #   * Encapsulate the writing and reading of the configuration
  #   * file. ...
  #   */
  #  
  #  /*
  #   * Document-method: read_value
  #   *
  #   * call-seq:
  #   *   cfg.read_value(key)            -> value
  #   *   cfg.read_value(key} { |key| }  -> value
  #   *
  #   * Return the value corresponding to +key+ from the configuration.
  #   * In the second form, if the key isn't found, invoke the
  #   * block and return its value.
  #   */
  #

  class C_Parser

    attr_accessor :progress

    extend ParserFactory
    parse_files_matching(/\.(?:([CcHh])\1?|c([+xp])\2|y)\z/)

    @@known_bodies = {}

    # prepare to parse a C file
    def initialize(top_level, file_name, body, options, stats)
      @known_classes = KNOWN_CLASSES.dup
      @body = handle_tab_width(handle_ifdefs_in(body))
      @options = options
      @stats   = stats
      @top_level = top_level
      @classes = Hash.new
      @file_dir = File.dirname(file_name)
      @progress = $stderr unless options.quiet
    end

    # Extract the classes/modules and methods from a C file
    # and return the corresponding top-level object
    def scan
      remove_commented_out_lines
      do_classes
      do_constants
      do_methods
      do_includes
      do_aliases
      @top_level
    end

    #######
    private
    #######

    def progress(char)
      unless @options.quiet
        @progress.print(char)
        @progress.flush
      end
    end

    def warn(msg)
      $stderr.puts
      $stderr.puts msg
      $stderr.flush
    end

    def remove_private_comments(comment)
       comment.gsub!(/\/?\*--(.*?)\/?\*\+\+/m, '')
       comment.sub!(/\/?\*--.*/m, '')
    end

    ##
    # removes lines that are commented out that might otherwise get picked up
    # when scanning for classes and methods

    def remove_commented_out_lines
      @body.gsub!(%r{//.*rb_define_}, '//')
    end
    
    def handle_class_module(var_name, class_mod, class_name, parent, in_module)
      progress(class_mod[0, 1])

      parent_name = @known_classes[parent] || parent

      if in_module
        enclosure = @classes[in_module]
        unless enclosure
          if enclosure = @known_classes[in_module]
            handle_class_module(in_module, (/^rb_m/ =~ in_module ? "module" : "class"),
                                enclosure, nil, nil)
            enclosure = @classes[in_module]
          end
        end
        unless enclosure
          warn("Enclosing class/module '#{in_module}' for " +
                "#{class_mod} #{class_name} not known")
          return
        end
      else
        enclosure = @top_level
      end

      if class_mod == "class" 
        cm = enclosure.add_class(NormalClass, class_name, parent_name)
        @stats.num_classes += 1
      else
        cm = enclosure.add_module(NormalModule, class_name)
        @stats.num_modules += 1
      end
      cm.record_location(enclosure.toplevel)

      find_class_comment(cm.full_name, cm)
      @classes[var_name] = cm
      @known_classes[var_name] = cm.full_name
    end

    ##
    # Look for class or module documentation above Init_+class_name+(void),
    # in a Document-class +class_name+ (or module) comment or above an
    # rb_define_class (or module).  If a comment is supplied above a matching
    # Init_ and a rb_define_class the Init_ comment is used.
    #
    #   /*
    #    * This is a comment for Foo
    #    */
    #   Init_Foo(void) {
    #       VALUE cFoo = rb_define_class("Foo", rb_cObject);
    #   }
    #
    #   /*
    #    * Document-class: Foo
    #    * This is a comment for Foo
    #    */
    #   Init_foo(void) {
    #       VALUE cFoo = rb_define_class("Foo", rb_cObject);
    #   }
    #
    #   /*
    #    * This is a comment for Foo
    #    */
    #   VALUE cFoo = rb_define_class("Foo", rb_cObject);

    def find_class_comment(class_name, class_meth)
      comment = nil
      if @body =~ %r{((?>/\*.*?\*/\s+))
                     (static\s+)?void\s+Init_#{class_name}\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)}xmi
        comment = $1
      elsif @body =~ %r{Document-(class|module):\s#{class_name}\s*?\n((?>.*?\*/))}m
        comment = $2
      else
        if @body =~ /rb_define_(class|module)/m then
          class_name = class_name.split("::").last
          comments = []
          @body.split(/(\/\*.*?\*\/)\s*?\n/m).each_with_index do |chunk, index|
            comments[index] = chunk
            if chunk =~ /rb_define_(class|module).*?"(#{class_name})"/m then
              comment = comments[index-1]
              break
            end
          end
        end
      end
      class_meth.comment = mangle_comment(comment) if comment
    end
    
    ############################################################

    def do_classes
      @body.scan(/(\w+)\s* = \s*rb_define_module\s*\(\s*"(\w+)"\s*\)/mx) do 
        |var_name, class_name|
        handle_class_module(var_name, "module", class_name, nil, nil)
      end
      
      # The '.' lets us handle SWIG-generated files
      @body.scan(/([\w\.]+)\s* = \s*rb_define_class\s*
                \( 
                   \s*"(\w+)",
                   \s*(\w+)\s*
                \)/mx) do 
        
        |var_name, class_name, parent|
        handle_class_module(var_name, "class", class_name, parent, nil)
      end
      
      @body.scan(/(\w+)\s*=\s*boot_defclass\s*\(\s*"(\w+?)",\s*(\w+?)\s*\)/) do
        |var_name, class_name, parent|
        parent = nil if parent == "0"
        handle_class_module(var_name, "class", class_name, parent, nil)
      end

      @body.scan(/(\w+)\s* = \s*rb_define_module_under\s*
                \( 
                   \s*(\w+),
                   \s*"(\w+)"
                \s*\)/mx) do 
        
        |var_name, in_module, class_name|
        handle_class_module(var_name, "module", class_name, nil, in_module)
      end
      
      @body.scan(/([\w\.]+)\s* = \s*rb_define_class_under\s*
                \( 
                   \s*(\w+),
                   \s*"(\w+)",
                   \s*(\w+)\s*
                \s*\)/mx) do 
        
        |var_name, in_module, class_name, parent|
        handle_class_module(var_name, "class", class_name, parent, in_module)
      end
      
    end

		###########################################################

    def do_constants
      @body.scan(%r{\Wrb_define_
                     (
                        variable |
                        readonly_variable |
                        const |
                        global_const |
                      )
                 \s*\( 
                   (?:\s*(\w+),)?
                   \s*"(\w+)",
                   \s*(.*?)\s*\)\s*;
                   }xm) do
        
        |type, var_name, const_name, definition|
        var_name = "rb_cObject" if !var_name or var_name == "rb_mKernel"
				handle_constants(type, var_name, const_name, definition)
      end
    end
    
    ############################################################
    
    def do_methods

      @body.scan(%r{rb_define_
                     (
                        singleton_method |
                        method           |
                        module_function  |
                        private_method
                     )
                     \s*\(\s*([\w\.]+),
                       \s*"([^"]+)",
                       \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
                       \s*(-?\w+)\s*\)
                     (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
                   }xm) do
        |type, var_name, meth_name, meth_body, param_count, source_file|
       #" 

        # Ignore top-object and weird struct.c dynamic stuff
        next if var_name == "ruby_top_self" 
        next if var_name == "nstr"
        next if var_name == "envtbl"
        next if var_name == "argf"   # it'd be nice to handle this one

        var_name = "rb_cObject" if var_name == "rb_mKernel"
        handle_method(type, var_name, meth_name, 
                      meth_body, param_count, source_file)
      end

      @body.scan(%r{rb_define_attr\(
                               \s*([\w\.]+),
                               \s*"([^"]+)",
                               \s*(\d+),
                               \s*(\d+)\s*\);
                  }xm) do  #"
        |var_name, attr_name, attr_reader, attr_writer|
        
        #var_name = "rb_cObject" if var_name == "rb_mKernel"
        handle_attr(var_name, attr_name,
                    attr_reader.to_i != 0,
                    attr_writer.to_i != 0)
      end

      @body.scan(%r{rb_define_global_function\s*\(
                               \s*"([^"]+)",
                               \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
                               \s*(-?\w+)\s*\)
                  (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
                  }xm) do  #"
        |meth_name, meth_body, param_count, source_file|
        handle_method("method", "rb_mKernel", meth_name, 
                      meth_body, param_count, source_file)
      end
  
      @body.scan(/define_filetest_function\s*\(
                               \s*"([^"]+)",
                               \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
                               \s*(-?\w+)\s*\)/xm) do  #"
        |meth_name, meth_body, param_count|
        
        handle_method("method", "rb_mFileTest", meth_name, meth_body, param_count)
        handle_method("singleton_method", "rb_cFile", meth_name, meth_body, param_count)
      end
   end

    ############################################################
    
    def do_aliases
      @body.scan(%r{rb_define_alias\s*\(\s*(\w+),\s*"([^"]+)",\s*"([^"]+)"\s*\)}m) do
        |var_name, new_name, old_name|
        @stats.num_methods += 1
        class_name = @known_classes[var_name] || var_name
        class_obj  = find_class(var_name, class_name)

        class_obj.add_alias(Alias.new("", old_name, new_name, ""))
      end
   end

    ##
    # Adds constant comments.  By providing some_value: at the start ofthe
    # comment you can override the C value of the comment to give a friendly
    # definition.
    #
    #   /* 300: The perfect score in bowling */
    #   rb_define_const(cFoo, "PERFECT", INT2FIX(300);
    #
    # Will override +INT2FIX(300)+ with the value +300+ in the output RDoc.
    # Values may include quotes and escaped colons (\:).

    def handle_constants(type, var_name, const_name, definition)
      #@stats.num_constants += 1
      class_name = @known_classes[var_name]
      
      return unless class_name

      class_obj  = find_class(var_name, class_name)

      unless class_obj
        warn("Enclosing class/module '#{const_name}' for not known")
        return
      end
      
      comment = find_const_comment(type, const_name)

      # In the case of rb_define_const, the definition and comment are in
      # "/* definition: comment */" form.  The literal ':' and '\' characters
      # can be escaped with a backslash.
      if type.downcase == 'const' then
         elements = mangle_comment(comment).split(':')
         if elements.nil? or elements.empty? then
            con = Constant.new(const_name, definition, mangle_comment(comment))
         else
            new_definition = elements[0..-2].join(':')
            if new_definition.empty? then # Default to literal C definition
               new_definition = definition
            else
               new_definition.gsub!("\:", ":")
               new_definition.gsub!("\\", '\\')
            end
            new_definition.sub!(/\A(\s+)/, '')
            new_comment = $1.nil? ? elements.last : "#{$1}#{elements.last.lstrip}"
            con = Constant.new(const_name, new_definition,
                               mangle_comment(new_comment))
         end
      else
         con = Constant.new(const_name, definition, mangle_comment(comment))
      end

      class_obj.add_constant(con)
    end

    ##
    # Finds a comment matching +type+ and +const_name+ either above the
    # comment or in the matching Document- section.

    def find_const_comment(type, const_name)
      if @body =~ %r{((?>^\s*/\*.*?\*/\s+))
                     rb_define_#{type}\((?:\s*(\w+),)?\s*"#{const_name}"\s*,.*?\)\s*;}xmi
        $1
      elsif @body =~ %r{Document-(?:const|global|variable):\s#{const_name}\s*?\n((?>.*?\*/))}m
        $1
      else
        ''
      end
    end

    ###########################################################

    def handle_attr(var_name, attr_name, reader, writer)
      rw = ''
      if reader 
        #@stats.num_methods += 1
        rw << 'R'
      end
      if writer
        #@stats.num_methods += 1
        rw << 'W'
      end

      class_name = @known_classes[var_name]

      return unless class_name
      
      class_obj  = find_class(var_name, class_name)

      if class_obj
        comment = find_attr_comment(attr_name)
        unless comment.empty?
          comment = mangle_comment(comment)
        end
        att = Attr.new('', attr_name, rw, comment)
        class_obj.add_attribute(att)
      end

    end

    ###########################################################

    def find_attr_comment(attr_name)
      if @body =~ %r{((?>/\*.*?\*/\s+))
                     rb_define_attr\((?:\s*(\w+),)?\s*"#{attr_name}"\s*,.*?\)\s*;}xmi
        $1
      elsif @body =~ %r{Document-attr:\s#{attr_name}\s*?\n((?>.*?\*/))}m
        $1
      else
        ''
      end
    end

    ###########################################################

    def handle_method(type, var_name, meth_name, 
                      meth_body, param_count, source_file = nil)
      progress(".")

      @stats.num_methods += 1
      class_name = @known_classes[var_name]

      return unless class_name

      class_obj  = find_class(var_name, class_name)
      
      if class_obj
        if meth_name == "initialize"
          meth_name = "new"
          type = "singleton_method"
        end
        meth_obj = AnyMethod.new("", meth_name)
        meth_obj.singleton =
	  %w{singleton_method module_function}.include?(type) 
        
        p_count = (Integer(param_count) rescue -1)
        
        if p_count < 0
          meth_obj.params = "(...)"
        elsif p_count == 0
          meth_obj.params = "()"
        else
          meth_obj.params = "(" +
                            (1..p_count).map{|i| "p#{i}"}.join(", ") + 
                                                ")"
        end

        if source_file
          file_name = File.join(@file_dir, source_file)
          body = (@@known_bodies[source_file] ||= File.read(file_name))
        else
          body = @body
        end
        if find_body(meth_body, meth_obj, body) and meth_obj.document_self
          class_obj.add_method(meth_obj)
        end
      end
    end
    
    ############################################################

    # Find the C code corresponding to a Ruby method
    def find_body(meth_name, meth_obj, body, quiet = false)
      case body
      when %r{((?>/\*.*?\*/\s*))(?:static\s+)?VALUE\s+#{meth_name}
              \s*(\(.*?\)).*?^}xm
        comment, params = $1, $2
        body_text = $&

        remove_private_comments(comment) if comment

        # see if we can find the whole body
        
        re = Regexp.escape(body_text) + '[^(]*^\{.*?^\}'
        if Regexp.new(re, Regexp::MULTILINE).match(body)
          body_text = $&
        end

        # The comment block may have been overridden with a
        # 'Document-method' block. This happens in the interpreter
        # when multiple methods are vectored through to the same
        # C method but those methods are logically distinct (for
        # example Kernel.hash and Kernel.object_id share the same
        # implementation

        override_comment = find_override_comment(meth_obj.name)
        comment = override_comment if override_comment

        find_modifiers(comment, meth_obj) if comment
        
#        meth_obj.params = params
        meth_obj.start_collecting_tokens
        meth_obj.add_token(RubyToken::Token.new(1,1).set_text(body_text))
        meth_obj.comment = mangle_comment(comment)
      when %r{((?>/\*.*?\*/\s*))^\s*\#\s*define\s+#{meth_name}\s+(\w+)}m
        comment = $1
        find_body($2, meth_obj, body, true)
        find_modifiers(comment, meth_obj)
        meth_obj.comment = mangle_comment(comment) + meth_obj.comment
      when %r{^\s*\#\s*define\s+#{meth_name}\s+(\w+)}m
        unless find_body($1, meth_obj, body, true)
          warn "No definition for #{meth_name}" unless quiet
          return false
        end
      else

        # No body, but might still have an override comment
        comment = find_override_comment(meth_obj.name)

        if comment
          find_modifiers(comment, meth_obj)
          meth_obj.comment = mangle_comment(comment)
        else
          warn "No definition for #{meth_name}" unless quiet
          return false
        end
      end
      true
    end


    ##
    # If the comment block contains a section that looks like:
    #
    #    call-seq:
    #        Array.new
    #        Array.new(10)
    #
    # use it for the parameters.

    def find_modifiers(comment, meth_obj)
      if comment.sub!(/:nodoc:\s*^\s*\*?\s*$/m, '') or
         comment.sub!(/\A\/\*\s*:nodoc:\s*\*\/\Z/, '')
        meth_obj.document_self = false
      end
      if comment.sub!(/call-seq:(.*?)^\s*\*?\s*$/m, '') or
         comment.sub!(/\A\/\*\s*call-seq:(.*?)\*\/\Z/, '')
        seq = $1
        seq.gsub!(/^\s*\*\s*/, '')
        meth_obj.call_seq = seq
      end
    end

    ############################################################

    def find_override_comment(meth_name)
      name = Regexp.escape(meth_name)
      if @body =~ %r{Document-method:\s#{name}\s*?\n((?>.*?\*/))}m
        $1
      end
    end

    ##
    # Look for includes of the form:
    #
    #     rb_include_module(rb_cArray, rb_mEnumerable);

    def do_includes
      @body.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c,m|
        if cls = @classes[c]
          m = @known_classes[m] || m
          cls.add_include(Include.new(m, ""))
        end
      end
    end

    ##
    # Remove the /*'s and leading asterisks from C comments
    
    def mangle_comment(comment)
      comment.sub!(%r{/\*+}) { " " * $&.length }
      comment.sub!(%r{\*+/}) { " " * $&.length }
      comment.gsub!(/^[ \t]*\*/m) { " " * $&.length }
      comment
    end

    def find_class(raw_name, name)
      unless @classes[raw_name]
        if raw_name =~ /^rb_m/ 
          @classes[raw_name] = @top_level.add_module(NormalModule, name)
        else
          @classes[raw_name] = @top_level.add_class(NormalClass, name, nil)
        end
      end
      @classes[raw_name]
    end

    def handle_tab_width(body)
      if /\t/ =~ body
        tab_width = Options.instance.tab_width
        body.split(/\n/).map do |line|
          1 while line.gsub!(/\t+/) { ' ' * (tab_width*$&.length - $`.length % tab_width)}  && $~ #`
          line
        end .join("\n")
      else
        body
      end
    end

    ##
    # Removes #ifdefs that would otherwise confuse us
    
    def handle_ifdefs_in(body)
      body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m) { $1 }
    end
    
  end

end

PK     Z\8Ye\'  '    rdoc/parsers/parse_simple.rbnu [        # Parse a non-source file. We basically take the whole thing 
# as one big comment. If the first character in the file
# is '#', we strip leading pound signs.


require "rdoc/code_objects"
require "rdoc/markup/simple_markup/preprocess"

module RDoc
  # See rdoc/parsers/parse_c.rb

  class SimpleParser
    
    # prepare to parse a plain file
    def initialize(top_level, file_name, body, options, stats)
      
      preprocess = SM::PreProcess.new(file_name, options.rdoc_include)
      
      preprocess.handle(body) do |directive, param|
        $stderr.puts "Unrecognized directive '#{directive}' in #{file_name}"
      end
      
      @body = body
      @options = options
      @top_level = top_level
    end
    
    # Extract the file contents and attach them to the toplevel as a
    # comment
    
    def scan
      #    @body.gsub(/^(\s\n)+/, '')
      @top_level.comment = remove_private_comments(@body)
      @top_level
    end

    def remove_private_comments(comment)
      comment.gsub(/^--.*?^\+\+/m, '').sub(/^--.*/m, '')
    end
  end
end
PK     Z\ kU
  
    rdoc/parsers/parserfactory.rbnu [        require "rdoc/parsers/parse_simple"

module RDoc

  # A parser is simple a class that implements
  #
  #   #initialize(file_name, body, options)
  #
  # and
  #
  #   #scan
  #
  # The initialize method takes a file name to be used, the body of the
  # file, and an RDoc::Options object. The scan method is then called
  # to return an appropriately parsed TopLevel code object.
  #
  # The ParseFactory is used to redirect to the correct parser given a filename
  # extension. This magic works because individual parsers have to register 
  # themselves with us as they are loaded in. The do this using the following
  # incantation
  #
  #
  #    require "rdoc/parsers/parsefactory"
  #    
  #    module RDoc
  #    
  #      class XyzParser
  #        extend ParseFactory                  <<<<
  #        parse_files_matching /\.xyz$/        <<<<
  #    
  #        def initialize(file_name, body, options)
  #          ...
  #        end
  #    
  #        def scan
  #          ...
  #        end
  #      end
  #    end
  #
  # Just to make life interesting, if we suspect a plain text file, we
  # also look for a shebang line just in case it's a potential
  # shell script



  module ParserFactory

    @@parsers = []

    Parsers = Struct.new(:regexp, :parser)

    # Record the fact that a particular class parses files that
    # match a given extension

    def parse_files_matching(regexp)
      @@parsers.unshift Parsers.new(regexp, self)
    end

    # Return a parser that can handle a particular extension

    def ParserFactory.can_parse(file_name)
      @@parsers.find {|p| p.regexp.match(file_name) }
    end

    # Alias an extension to another extension. After this call,
    # files ending "new_ext" will be parsed using the same parser
    # as "old_ext"

    def ParserFactory.alias_extension(old_ext, new_ext)
      parser = ParserFactory.can_parse("xxx.#{old_ext}")
      return false unless parser
      @@parsers.unshift Parsers.new(Regexp.new("\\.#{new_ext}$"), parser.parser)
      true
    end

    # Find the correct parser for a particular file name. Return a 
    # SimpleParser for ones that we don't know

    def ParserFactory.parser_for(top_level, file_name, body, options, stats)
      # If no extension, look for shebang
      if file_name !~ /\.\w+$/ && body =~ %r{\A#!(.+)}
        shebang = $1
        case shebang
        when %r{env\s+ruby}, %r{/ruby}
          file_name = "dummy.rb"
        end
      end
      parser_description = can_parse(file_name)
      if parser_description
        parser = parser_description.parser 
      else
        parser = SimpleParser
      end

      parser.new(top_level, file_name, body, options, stats)
    end
  end
end
PK     Z\T?  ?    rdoc/parsers/parse_rb.rbnu [        #!/usr/local/bin/ruby

# Parse a Ruby source file, building a set of objects
# representing the modules, classes, methods,
# requires, and includes we find (these classes
# are defined in code_objects.rb).

# This file contains stuff stolen outright from:
#
#   rtags.rb - 
#   ruby-lex.rb - ruby lexcal analizer
#   ruby-token.rb - ruby tokens 
#   	by Keiju ISHITSUKA (Nippon Rational Inc.)
#

require "e2mmap"
require "irb/slex"

require "rdoc/code_objects"
require "rdoc/tokenstream"

require "rdoc/markup/simple_markup/preprocess"

require "rdoc/parsers/parserfactory"

$TOKEN_DEBUG = $DEBUG

# Definitions of all tokens involved in the lexical analysis

module RubyToken
  EXPR_BEG   = :EXPR_BEG
  EXPR_MID   = :EXPR_MID
  EXPR_END   = :EXPR_END
  EXPR_ARG   = :EXPR_ARG
  EXPR_FNAME = :EXPR_FNAME
  EXPR_DOT   = :EXPR_DOT
  EXPR_CLASS = :EXPR_CLASS
  
  class Token
    NO_TEXT = "??".freeze
    attr :text

    def initialize(line_no, char_no)
      @line_no = line_no
      @char_no = char_no
      @text    = NO_TEXT
    end

    # Because we're used in contexts that expect to return a token,
    # we set the text string and then return ourselves
    def set_text(text)
      @text = text
      self
    end

    attr_reader :line_no, :char_no, :text
  end

  class TkNode < Token
    attr :node
  end

  class TkId < Token
    def initialize(line_no, char_no, name)
      super(line_no, char_no)
      @name = name
    end
    attr :name
  end

  class TkKW < TkId
  end

  class TkVal < Token
    def initialize(line_no, char_no, value = nil)
      super(line_no, char_no)
      set_text(value)
    end
  end

  class TkOp < Token
    def name
      self.class.op_name
    end
  end

  class TkOPASGN < TkOp
    def initialize(line_no, char_no, op)
      super(line_no, char_no)
      op = TkReading2Token[op] unless op.kind_of?(Symbol)
      @op = op
    end
    attr :op
  end

  class TkUnknownChar < Token
    def initialize(line_no, char_no, id)
      super(line_no, char_no)
      @name = char_no.chr
    end
    attr :name
  end

  class TkError < Token
  end

  def set_token_position(line, char)
    @prev_line_no = line
    @prev_char_no = char
  end

  def Token(token, value = nil)
    tk = nil
    case token
    when String, Symbol
      source = token.kind_of?(String) ? TkReading2Token : TkSymbol2Token
      if (tk = source[token]).nil?
	IRB.fail TkReading2TokenNoKey, token
      end
      tk = Token(tk[0], value) 
    else 
      tk = if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty?
             token.new(@prev_line_no, @prev_char_no)
           else
             token.new(@prev_line_no, @prev_char_no, value)
           end
    end
    tk
  end

  TokenDefinitions = [
    [:TkCLASS,      TkKW,  "class",  EXPR_CLASS],
    [:TkMODULE,     TkKW,  "module", EXPR_BEG],
    [:TkDEF,	    TkKW,  "def",    EXPR_FNAME],
    [:TkUNDEF,      TkKW,  "undef",  EXPR_FNAME],
    [:TkBEGIN,      TkKW,  "begin",  EXPR_BEG],
    [:TkRESCUE,     TkKW,  "rescue", EXPR_MID],
    [:TkENSURE,     TkKW,  "ensure", EXPR_BEG],
    [:TkEND,	    TkKW,  "end",    EXPR_END],
    [:TkIF,         TkKW,  "if",     EXPR_BEG, :TkIF_MOD],
    [:TkUNLESS,     TkKW,  "unless", EXPR_BEG, :TkUNLESS_MOD],
    [:TkTHEN,	    TkKW,  "then",   EXPR_BEG],
    [:TkELSIF,      TkKW,  "elsif",  EXPR_BEG],
    [:TkELSE,	    TkKW,  "else",   EXPR_BEG],
    [:TkCASE,	    TkKW,  "case",   EXPR_BEG],
    [:TkWHEN,	    TkKW,  "when",   EXPR_BEG],
    [:TkWHILE,      TkKW,  "while",  EXPR_BEG, :TkWHILE_MOD],
    [:TkUNTIL,      TkKW,  "until",  EXPR_BEG, :TkUNTIL_MOD],
    [:TkFOR,	    TkKW,  "for",    EXPR_BEG],
    [:TkBREAK,      TkKW,  "break",  EXPR_END],
    [:TkNEXT,	    TkKW,  "next",   EXPR_END],
    [:TkREDO,	    TkKW,  "redo",   EXPR_END],
    [:TkRETRY,      TkKW,  "retry",  EXPR_END],
    [:TkIN,	    TkKW,  "in",     EXPR_BEG],
    [:TkDO,	    TkKW,  "do",     EXPR_BEG],
    [:TkRETURN,     TkKW,  "return", EXPR_MID],
    [:TkYIELD,      TkKW,  "yield",  EXPR_END],
    [:TkSUPER,      TkKW,  "super",  EXPR_END],
    [:TkSELF,	    TkKW,  "self",   EXPR_END],
    [:TkNIL, 	    TkKW,  "nil",    EXPR_END],
    [:TkTRUE,	    TkKW,  "true",   EXPR_END],
    [:TkFALSE,      TkKW,  "false",  EXPR_END],
    [:TkAND,	    TkKW,  "and",    EXPR_BEG],
    [:TkOR, 	    TkKW,  "or",     EXPR_BEG],
    [:TkNOT,	    TkKW,  "not",    EXPR_BEG],
    [:TkIF_MOD,     TkKW],
    [:TkUNLESS_MOD, TkKW],
    [:TkWHILE_MOD,  TkKW],
    [:TkUNTIL_MOD,  TkKW],
    [:TkALIAS,      TkKW,  "alias",    EXPR_FNAME],
    [:TkDEFINED,    TkKW,  "defined?", EXPR_END],
    [:TklBEGIN,     TkKW,  "BEGIN",    EXPR_END],
    [:TklEND,	    TkKW,  "END",      EXPR_END],
    [:Tk__LINE__,   TkKW,  "__LINE__", EXPR_END],
    [:Tk__FILE__,   TkKW,  "__FILE__", EXPR_END],

    [:TkIDENTIFIER, TkId],
    [:TkFID,	    TkId],
    [:TkGVAR,	    TkId],
    [:TkIVAR,	    TkId],
    [:TkCONSTANT,   TkId],

    [:TkINTEGER,    TkVal],
    [:TkFLOAT,      TkVal],
    [:TkSTRING,     TkVal],
    [:TkXSTRING,    TkVal],
    [:TkREGEXP,     TkVal],
    [:TkCOMMENT,    TkVal],

    [:TkDSTRING,    TkNode],
    [:TkDXSTRING,   TkNode],
    [:TkDREGEXP,    TkNode],
    [:TkNTH_REF,    TkId],
    [:TkBACK_REF,   TkId],

    [:TkUPLUS,      TkOp,   "+@"],
    [:TkUMINUS,     TkOp,   "-@"],
    [:TkPOW,	    TkOp,   "**"],
    [:TkCMP,	    TkOp,   "<=>"],
    [:TkEQ,	    TkOp,   "=="],
    [:TkEQQ,	    TkOp,   "==="],
    [:TkNEQ,	    TkOp,   "!="],
    [:TkGEQ,	    TkOp,   ">="],
    [:TkLEQ,	    TkOp,   "<="],
    [:TkANDOP,      TkOp,   "&&"],
    [:TkOROP,	    TkOp,   "||"],
    [:TkMATCH,      TkOp,   "=~"],
    [:TkNMATCH,     TkOp,   "!~"],
    [:TkDOT2,	    TkOp,   ".."],
    [:TkDOT3,	    TkOp,   "..."],
    [:TkAREF,	    TkOp,   "[]"],
    [:TkASET,	    TkOp,   "[]="],
    [:TkLSHFT,      TkOp,   "<<"],
    [:TkRSHFT,      TkOp,   ">>"],
    [:TkCOLON2,     TkOp],
    [:TkCOLON3,     TkOp],
#   [:OPASGN,	    TkOp],               # +=, -=  etc. #
    [:TkASSOC,      TkOp,   "=>"],
    [:TkQUESTION,   TkOp,   "?"],	 #?
    [:TkCOLON,      TkOp,   ":"],        #:
    
    [:TkfLPAREN],         # func( #
    [:TkfLBRACK],         # func[ #
    [:TkfLBRACE],         # func{ #
    [:TkSTAR],            # *arg
    [:TkAMPER],           # &arg #
    [:TkSYMBOL,     TkId],          # :SYMBOL
    [:TkSYMBEG,     TkId], 
    [:TkGT,	    TkOp,   ">"],
    [:TkLT,	    TkOp,   "<"],
    [:TkPLUS,	    TkOp,   "+"],
    [:TkMINUS,      TkOp,   "-"],
    [:TkMULT,	    TkOp,   "*"],
    [:TkDIV,	    TkOp,   "/"],
    [:TkMOD,	    TkOp,   "%"],
    [:TkBITOR,      TkOp,   "|"],
    [:TkBITXOR,     TkOp,   "^"],
    [:TkBITAND,     TkOp,   "&"],
    [:TkBITNOT,     TkOp,   "~"],
    [:TkNOTOP,      TkOp,   "!"],

    [:TkBACKQUOTE,  TkOp,   "`"],

    [:TkASSIGN,     Token,  "="],
    [:TkDOT,	    Token,  "."],
    [:TkLPAREN,     Token,  "("],  #(exp)
    [:TkLBRACK,     Token,  "["],  #[arry]
    [:TkLBRACE,     Token,  "{"],  #{hash}
    [:TkRPAREN,     Token,  ")"],
    [:TkRBRACK,     Token,  "]"],
    [:TkRBRACE,     Token,  "}"],
    [:TkCOMMA,      Token,  ","],
    [:TkSEMICOLON,  Token,  ";"],

    [:TkRD_COMMENT],
    [:TkSPACE],
    [:TkNL],
    [:TkEND_OF_SCRIPT],

    [:TkBACKSLASH,  TkUnknownChar,  "\\"],
    [:TkAT,	    TkUnknownChar,  "@"],
    [:TkDOLLAR,     TkUnknownChar,  "\$"], #"
  ]

  # {reading => token_class}
  # {reading => [token_class, *opt]}
  TkReading2Token = {}
  TkSymbol2Token = {}

  def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts)
    token_n = token_n.id2name unless token_n.kind_of?(String)
    if RubyToken.const_defined?(token_n)
      IRB.fail AlreadyDefinedToken, token_n
    end

    token_c =  Class.new super_token
    RubyToken.const_set token_n, token_c
#    token_c.inspect
 
    if reading
      if TkReading2Token[reading]
	IRB.fail TkReading2TokenDuplicateError, token_n, reading
      end
      if opts.empty?
	TkReading2Token[reading] = [token_c]
      else
	TkReading2Token[reading] = [token_c].concat(opts)
      end
    end
    TkSymbol2Token[token_n.intern] = token_c

    if token_c <= TkOp
      token_c.class_eval %{
        def self.op_name; "#{reading}"; end
      }
    end
  end

  for defs in TokenDefinitions
    def_token(*defs)
  end

  NEWLINE_TOKEN = TkNL.new(0,0)
  NEWLINE_TOKEN.set_text("\n")

end



# Lexical analyzer for Ruby source

class RubyLex

  ######################################################################
  #
  # Read an input stream character by character. We allow for unlimited
  # ungetting of characters just read.
  #
  # We simplify the implementation greatly by reading the entire input
  # into a buffer initially, and then simply traversing it using
  # pointers.
  #
  # We also have to allow for the <i>here document diversion</i>. This
  # little gem comes about when the lexer encounters a here
  # document. At this point we effectively need to split the input
  # stream into two parts: one to read the body of the here document,
  # the other to read the rest of the input line where the here
  # document was initially encountered. For example, we might have
  #
  #   do_something(<<-A, <<-B)
  #     stuff
  #     for
  #   A
  #     stuff
  #     for
  #   B
  #
  # When the lexer encounters the <<A, it reads until the end of the
  # line, and keeps it around for later. It then reads the body of the
  # here document.  Once complete, it needs to read the rest of the
  # original line, but then skip the here document body.
  #
  
  class BufferedReader
    
    attr_reader :line_num
    
    def initialize(content)
      if /\t/ =~ content
        tab_width = Options.instance.tab_width
        content = content.split(/\n/).map do |line|
          1 while line.gsub!(/\t+/) { ' ' * (tab_width*$&.length - $`.length % tab_width)}  && $~ #`
          line
        end .join("\n")
      end
      @content   = content
      @content << "\n" unless @content[-1,1] == "\n"
      @size      = @content.size
      @offset    = 0
      @hwm       = 0
      @line_num  = 1
      @read_back_offset = 0
      @last_newline = 0
      @newline_pending = false
    end
    
    def column
      @offset - @last_newline
    end
    
    def getc
      return nil if @offset >= @size
      ch = @content[@offset, 1]
      
      @offset += 1
      @hwm = @offset if @hwm < @offset
      
      if @newline_pending
        @line_num += 1
        @last_newline = @offset - 1
        @newline_pending = false
      end
      
      if ch == "\n"
        @newline_pending = true
      end
      ch
    end
    
    def getc_already_read
      getc
    end
    
    def ungetc(ch)
      raise "unget past beginning of file" if @offset <= 0
      @offset -= 1
      if @content[@offset] == ?\n
        @newline_pending = false
      end
    end
    
    def get_read
      res = @content[@read_back_offset...@offset]
      @read_back_offset = @offset
      res
    end
    
    def peek(at)
      pos = @offset + at
      if pos >= @size
        nil
      else
        @content[pos, 1]
      end
    end
    
    def peek_equal(str)
      @content[@offset, str.length] == str
    end
    
    def divert_read_from(reserve)
      @content[@offset, 0] = reserve
      @size      = @content.size
    end
  end

  # end of nested class BufferedReader

  extend Exception2MessageMapper
  def_exception(:AlreadyDefinedToken, "Already defined token(%s)")
  def_exception(:TkReading2TokenNoKey, "key nothing(key='%s')")
  def_exception(:TkSymbol2TokenNoKey, "key nothing(key='%s')")
  def_exception(:TkReading2TokenDuplicateError, 
		"key duplicate(token_n='%s', key='%s')")
  def_exception(:SyntaxError, "%s")
  
  include RubyToken
  include IRB

  attr_reader :continue
  attr_reader :lex_state

  def RubyLex.debug?
    false
  end

  def initialize(content)
    lex_init

    @reader = BufferedReader.new(content)

    @exp_line_no = @line_no = 1
    @base_char_no = 0
    @indent = 0

    @ltype = nil
    @quoted = nil
    @lex_state = EXPR_BEG
    @space_seen = false
    
    @continue = false
    @line = ""

    @skip_space = false
    @read_auto_clean_up = false
    @exception_on_syntax_error = true
  end

  attr :skip_space, true
  attr :read_auto_clean_up, true
  attr :exception_on_syntax_error, true

  attr :indent

  # io functions
  def line_no
    @reader.line_num
  end

  def char_no
    @reader.column
  end

  def get_read
    @reader.get_read
  end

  def getc
    @reader.getc
  end

  def getc_of_rests
    @reader.getc_already_read
  end

  def gets
    c = getc or return
    l = ""
    begin
      l.concat c unless c == "\r"
      break if c == "\n"
    end while c = getc
    l
  end


  def ungetc(c = nil)
    @reader.ungetc(c)
  end

  def peek_equal?(str)
    @reader.peek_equal(str)
  end

  def peek(i = 0)
    @reader.peek(i)
  end

  def lex
    until (((tk = token).kind_of?(TkNL) || tk.kind_of?(TkEND_OF_SCRIPT)) &&
	     !@continue or
	     tk.nil?)
    end
    line = get_read

    if line == "" and tk.kind_of?(TkEND_OF_SCRIPT) || tk.nil?
      nil
    else
      line
    end
  end

  def token
    set_token_position(line_no, char_no)
    begin
      begin
	tk = @OP.match(self)
	@space_seen = tk.kind_of?(TkSPACE)
      rescue SyntaxError
	abort if @exception_on_syntax_error
	tk = TkError.new(line_no, char_no)
      end
    end while @skip_space and tk.kind_of?(TkSPACE)
    if @read_auto_clean_up
      get_read
    end
#   throw :eof unless tk
    p tk if $DEBUG
    tk
  end
  
  ENINDENT_CLAUSE = [
    "case", "class", "def", "do", "for", "if",
    "module", "unless", "until", "while", "begin" #, "when"
  ]
  DEINDENT_CLAUSE = ["end" #, "when"
  ]

  PERCENT_LTYPE = {
    "q" => "\'",
    "Q" => "\"",
    "x" => "\`",
    "r" => "/",
    "w" => "]"
  }
  
  PERCENT_PAREN = {
    "{" => "}",
    "[" => "]",
    "<" => ">",
    "(" => ")"
  }

  Ltype2Token = {
    "\'" => TkSTRING,
    "\"" => TkSTRING,
    "\`" => TkXSTRING,
    "/" => TkREGEXP,
    "]" => TkDSTRING
  }
  Ltype2Token.default = TkSTRING

  DLtype2Token = {
    "\"" => TkDSTRING,
    "\`" => TkDXSTRING,
    "/" => TkDREGEXP,
  }

  def lex_init()
    @OP = SLex.new
    @OP.def_rules("\0", "\004", "\032") do |chars, io|
      Token(TkEND_OF_SCRIPT).set_text(chars)
    end

    @OP.def_rules(" ", "\t", "\f", "\r", "\13") do |chars, io|
      @space_seen = TRUE
      while (ch = getc) =~ /[ \t\f\r\13]/
        chars << ch
      end
      ungetc
      Token(TkSPACE).set_text(chars)
    end

    @OP.def_rule("#") do
      |op, io|
      identify_comment
    end

    @OP.def_rule("=begin", proc{@prev_char_no == 0 && peek(0) =~ /\s/}) do
      |op, io|
      str = op
      @ltype = "="


      begin
        line = ""
        begin
          ch = getc
          line << ch
        end until ch == "\n"
        str << line
      end until line =~ /^=end/

      ungetc

      @ltype = nil

      if str =~ /\A=begin\s+rdoc/i
        str.sub!(/\A=begin.*\n/, '')
        str.sub!(/^=end.*/m, '')
        Token(TkCOMMENT).set_text(str)
      else
        Token(TkRD_COMMENT)#.set_text(str)
      end
    end

    @OP.def_rule("\n") do
      print "\\n\n" if RubyLex.debug?
      case @lex_state
      when EXPR_BEG, EXPR_FNAME, EXPR_DOT
	@continue = TRUE
      else
	@continue = FALSE
	@lex_state = EXPR_BEG
      end
      Token(TkNL).set_text("\n")
    end

    @OP.def_rules("*", "**",	
		  "!", "!=", "!~",
		  "=", "==", "===", 
		  "=~", "<=>",	
		  "<", "<=",
		  ">", ">=", ">>") do
      |op, io|
      @lex_state = EXPR_BEG
      Token(op).set_text(op)
    end

    @OP.def_rules("<<") do
      |op, io|
      tk = nil
      if @lex_state != EXPR_END && @lex_state != EXPR_CLASS &&
	  (@lex_state != EXPR_ARG || @space_seen)
	c = peek(0)
	if /[-\w_\"\'\`]/ =~ c
	  tk = identify_here_document
	end
      end
      if !tk
        @lex_state = EXPR_BEG
        tk = Token(op).set_text(op)
      end
      tk
    end

    @OP.def_rules("'", '"') do
      |op, io|
      identify_string(op)
    end

    @OP.def_rules("`") do
      |op, io|
      if @lex_state == EXPR_FNAME
	Token(op).set_text(op)
      else
	identify_string(op)
      end
    end

    @OP.def_rules('?') do
      |op, io|
      if @lex_state == EXPR_END
	@lex_state = EXPR_BEG
	Token(TkQUESTION).set_text(op)
      else
	ch = getc
	if @lex_state == EXPR_ARG && ch !~ /\s/
	  ungetc
	  @lex_state = EXPR_BEG;
	  Token(TkQUESTION).set_text(op)
	else
          str = op
          str << ch
	  if (ch == '\\') #'
	    str << read_escape
	  end
	  @lex_state = EXPR_END
	  Token(TkINTEGER).set_text(str)
	end
      end
    end

    @OP.def_rules("&", "&&", "|", "||") do
      |op, io|
      @lex_state = EXPR_BEG
      Token(op).set_text(op)
    end
    
    @OP.def_rules("+=", "-=", "*=", "**=", 
		  "&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do
      |op, io|
      @lex_state = EXPR_BEG
      op =~ /^(.*)=$/
      Token(TkOPASGN, $1).set_text(op)
    end

    @OP.def_rule("+@", proc{@lex_state == EXPR_FNAME}) do |op, io|
      Token(TkUPLUS).set_text(op)
    end

    @OP.def_rule("-@", proc{@lex_state == EXPR_FNAME}) do |op, io|
      Token(TkUMINUS).set_text(op)
    end

    @OP.def_rules("+", "-") do
      |op, io|
      catch(:RET) do
	if @lex_state == EXPR_ARG
	  if @space_seen and peek(0) =~ /[0-9]/
	    throw :RET, identify_number(op)
	  else
	    @lex_state = EXPR_BEG
	  end
	elsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/
	  throw :RET, identify_number(op)
	else
	  @lex_state = EXPR_BEG
	end
	Token(op).set_text(op)
      end
    end

    @OP.def_rule(".") do
      @lex_state = EXPR_BEG
      if peek(0) =~ /[0-9]/
	ungetc
	identify_number("")
      else
	# for obj.if
	@lex_state = EXPR_DOT
	Token(TkDOT).set_text(".")
      end
    end

    @OP.def_rules("..", "...") do
      |op, io|
      @lex_state = EXPR_BEG
      Token(op).set_text(op)
    end

    lex_int2
  end
  
  def lex_int2
    @OP.def_rules("]", "}", ")") do
      |op, io|
      @lex_state = EXPR_END
      @indent -= 1
      Token(op).set_text(op)
    end

    @OP.def_rule(":") do
      if @lex_state == EXPR_END || peek(0) =~ /\s/
	@lex_state = EXPR_BEG
	tk = Token(TkCOLON)
      else
	@lex_state = EXPR_FNAME;
	tk = Token(TkSYMBEG)
      end
      tk.set_text(":")
    end

    @OP.def_rule("::") do
#      p @lex_state.id2name, @space_seen
      if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen
	@lex_state = EXPR_BEG
	tk = Token(TkCOLON3)
      else
	@lex_state = EXPR_DOT
	tk = Token(TkCOLON2)
      end
      tk.set_text("::")
    end

    @OP.def_rule("/") do
      |op, io|
      if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
	identify_string(op)
      elsif peek(0) == '='
	getc
	@lex_state = EXPR_BEG
	Token(TkOPASGN, :/).set_text("/=") #")
      elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
	identify_string(op)
      else 
	@lex_state = EXPR_BEG
        Token("/").set_text(op)
      end
    end

    @OP.def_rules("^") do
      @lex_state = EXPR_BEG
      Token("^").set_text("^")
    end

    #       @OP.def_rules("^=") do
    # 	@lex_state = EXPR_BEG
    # 	Token(TkOPASGN, :^)
    #       end
    
    @OP.def_rules(",", ";") do
      |op, io|
      @lex_state = EXPR_BEG
      Token(op).set_text(op)
    end

    @OP.def_rule("~") do
      @lex_state = EXPR_BEG
      Token("~").set_text("~")
    end

    @OP.def_rule("~@", proc{@lex_state = EXPR_FNAME}) do
      @lex_state = EXPR_BEG
      Token("~").set_text("~@")
    end
    
    @OP.def_rule("(") do
      @indent += 1
      if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
	@lex_state = EXPR_BEG
	tk = Token(TkfLPAREN)
      else
	@lex_state = EXPR_BEG
	tk = Token(TkLPAREN)
      end
      tk.set_text("(")
    end

    @OP.def_rule("[]", proc{@lex_state == EXPR_FNAME}) do
      Token("[]").set_text("[]")
    end

    @OP.def_rule("[]=", proc{@lex_state == EXPR_FNAME}) do
      Token("[]=").set_text("[]=")
    end

    @OP.def_rule("[") do
      @indent += 1
      if @lex_state == EXPR_FNAME
	t = Token(TkfLBRACK)
      else
	if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
	  t = Token(TkLBRACK)
	elsif @lex_state == EXPR_ARG && @space_seen
	  t = Token(TkLBRACK)
	else
	  t = Token(TkfLBRACK)
	end
	@lex_state = EXPR_BEG
      end
      t.set_text("[")
    end

    @OP.def_rule("{") do
      @indent += 1
      if @lex_state != EXPR_END && @lex_state != EXPR_ARG
	t = Token(TkLBRACE)
      else
	t = Token(TkfLBRACE)
      end
      @lex_state = EXPR_BEG
      t.set_text("{")
    end

    @OP.def_rule('\\') do   #'
      if getc == "\n" 
	@space_seen = true
	@continue = true
	Token(TkSPACE).set_text("\\\n")
      else 
	ungetc
	Token("\\").set_text("\\")  #"
      end 
    end 

    @OP.def_rule('%') do
      |op, io|
      if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
	identify_quotation('%')
      elsif peek(0) == '='
	getc
	Token(TkOPASGN, "%").set_text("%=")
      elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
	identify_quotation('%')
      else
	@lex_state = EXPR_BEG
	Token("%").set_text("%")
      end
    end

    @OP.def_rule('$') do  #'
      identify_gvar
    end

    @OP.def_rule('@') do
      if peek(0) =~ /[@\w_]/
	ungetc
	identify_identifier
      else
	Token("@").set_text("@")
      end
    end

    #       @OP.def_rule("def", proc{|op, io| /\s/ =~ io.peek(0)}) do 
    # 	|op, io|
    # 	@indent += 1
    # 	@lex_state = EXPR_FNAME
    # #	@lex_state = EXPR_END
    # #	until @rests[0] == "\n" or @rests[0] == ";"
    # #	  rests.shift
    # #	end
    #       end

    @OP.def_rule("__END__", proc{@prev_char_no == 0 && peek(0) =~ /[\r\n]/}) do
      throw :eof
    end

    @OP.def_rule("") do
      |op, io|
      printf "MATCH: start %s: %s\n", op, io.inspect if RubyLex.debug?
      if peek(0) =~ /[0-9]/
	t = identify_number("")
      elsif peek(0) =~ /[\w_]/
	t = identify_identifier
      end
      printf "MATCH: end %s: %s\n", op, io.inspect if RubyLex.debug?
      t
    end
    
    p @OP if RubyLex.debug?
  end
  
  def identify_gvar
    @lex_state = EXPR_END
    str = "$"

    tk = case ch = getc
         when /[~_*$?!@\/\\;,=:<>".]/   #"
           str << ch
           Token(TkGVAR, str)
           
         when "-"
           str << "-" << getc
           Token(TkGVAR, str)
           
         when "&", "`", "'", "+"
           str << ch
           Token(TkBACK_REF, str)
           
         when /[1-9]/
           str << ch
           while (ch = getc) =~ /[0-9]/
             str << ch
           end
           ungetc
           Token(TkNTH_REF)
         when /\w/
           ungetc
           ungetc
           return identify_identifier
         else 
           ungetc
           Token("$")     
         end
    tk.set_text(str)
  end
  
  def identify_identifier
    token = ""
    token.concat getc if peek(0) =~ /[$@]/
    token.concat getc if peek(0) == "@"

    while (ch = getc) =~ /\w|_/
      print ":", ch, ":" if RubyLex.debug?
      token.concat ch
    end
    ungetc
    
    if ch == "!" or ch == "?"
      token.concat getc
    end
    # fix token

    # $stderr.puts "identifier - #{token}, state = #@lex_state"

    case token
    when /^\$/
      return Token(TkGVAR, token).set_text(token)
    when /^\@/
      @lex_state = EXPR_END
      return Token(TkIVAR, token).set_text(token)
    end
    
    if @lex_state != EXPR_DOT
      print token, "\n" if RubyLex.debug?

      token_c, *trans = TkReading2Token[token]
      if token_c
	# reserved word?

	if (@lex_state != EXPR_BEG &&
	    @lex_state != EXPR_FNAME &&
	    trans[1])
	  # modifiers
	  token_c = TkSymbol2Token[trans[1]]
	  @lex_state = trans[0]
	else
	  if @lex_state != EXPR_FNAME
	    if ENINDENT_CLAUSE.include?(token)
	      @indent += 1
	    elsif DEINDENT_CLAUSE.include?(token)
	      @indent -= 1
	    end
	    @lex_state = trans[0]
	  else
	    @lex_state = EXPR_END
	  end
	end
	return Token(token_c, token).set_text(token)
      end
    end

    if @lex_state == EXPR_FNAME
      @lex_state = EXPR_END
      if peek(0) == '='
	token.concat getc
      end
    elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT
      @lex_state = EXPR_ARG
    else
      @lex_state = EXPR_END
    end

    if token[0, 1] =~ /[A-Z]/
      return Token(TkCONSTANT, token).set_text(token)
    elsif token[token.size - 1, 1] =~ /[!?]/
      return Token(TkFID, token).set_text(token)
    else
      return Token(TkIDENTIFIER, token).set_text(token)
    end
  end

  def identify_here_document
    ch = getc
    if ch == "-"
      ch = getc
      indent = true
    end
    if /['"`]/ =~ ch            # '
      lt = ch
      quoted = ""
      while (c = getc) && c != lt
	quoted.concat c
      end
    else
      lt = '"'
      quoted = ch.dup
      while (c = getc) && c =~ /\w/
	quoted.concat c
      end
      ungetc
    end

    ltback, @ltype = @ltype, lt
    reserve = ""

    while ch = getc
      reserve << ch
      if ch == "\\"    #"
        ch = getc
	reserve << ch
      elsif ch == "\n"
	break
      end
    end

    str = ""
    while (l = gets)
      l.chomp!
      l.strip! if indent
      break if l == quoted
      str << l.chomp << "\n"
    end

    @reader.divert_read_from(reserve)

    @ltype = ltback
    @lex_state = EXPR_END
    Token(Ltype2Token[lt], str).set_text(str.dump)
  end
  
  def identify_quotation(initial_char)
    ch = getc
    if lt = PERCENT_LTYPE[ch]
      initial_char += ch
      ch = getc
    elsif ch =~ /\W/
      lt = "\""
    else
      RubyLex.fail SyntaxError, "unknown type of %string ('#{ch}')"
    end
#     if ch !~ /\W/
#       ungetc
#       next
#     end
    #@ltype = lt
    @quoted = ch unless @quoted = PERCENT_PAREN[ch]
    identify_string(lt, @quoted, ch, initial_char)
  end

  def identify_number(start)
    str = start.dup

    if start == "+" or start == "-" or start == ""
      start = getc
      str << start
    end

    @lex_state = EXPR_END

    if start == "0"
      if peek(0) == "x"
        ch = getc
        str << ch
        match = /[0-9a-f_]/
      else
        match = /[0-7_]/
      end
      while ch = getc
        if ch !~ match
          ungetc
          break
        else
          str << ch
        end
      end
      return Token(TkINTEGER).set_text(str)
    end

    type = TkINTEGER
    allow_point = TRUE
    allow_e = TRUE
    while ch = getc
      case ch
      when /[0-9_]/
        str << ch

      when allow_point && "."
	type = TkFLOAT
	if peek(0) !~ /[0-9]/
	  ungetc
	  break
	end
        str << ch
	allow_point = false

      when allow_e && "e", allow_e && "E"
        str << ch
	type = TkFLOAT
	if peek(0) =~ /[+-]/
	  str << getc
	end
	allow_e = false
	allow_point = false
      else
	ungetc
	break
      end
    end
    Token(type).set_text(str)
  end
  
  def identify_string(ltype, quoted = ltype, opener=nil, initial_char = nil)
    @ltype = ltype
    @quoted = quoted
    subtype = nil

    str = ""
    str << initial_char if initial_char
    str << (opener||quoted)

    nest = 0
    begin
      while ch = getc 
	str << ch
	if @quoted == ch 
          if nest == 0
            break
          else
            nest -= 1
          end
        elsif opener == ch
          nest += 1
	elsif @ltype != "'" && @ltype != "]" and ch == "#"
          ch = getc
          if ch == "{"
            subtype = true
            str << ch << skip_inner_expression
          else
            ungetc(ch)
          end
	elsif ch == '\\' #'
	  str << read_escape
	end
      end
      if @ltype == "/"
	if peek(0) =~ /i|o|n|e|s/
	  str << getc
	end
      end
      if subtype
	Token(DLtype2Token[ltype], str)
      else
	Token(Ltype2Token[ltype], str)
      end.set_text(str)
    ensure
      @ltype = nil
      @quoted = nil
      @lex_state = EXPR_END
    end
  end

  def skip_inner_expression
    res = ""
    nest = 0
    while (ch = getc)
      res << ch
      if ch == '}'
        break if nest.zero?
        nest -= 1
      elsif ch == '{'
        nest += 1
      end
    end
    res
  end

  def identify_comment
    @ltype = "#"
    comment = "#"
    while ch = getc
      if ch == "\\"
        ch = getc
        if ch == "\n"
          ch = " "
        else
          comment << "\\" 
        end
      else
        if ch == "\n"
          @ltype = nil
          ungetc
          break
        end
      end
      comment << ch
    end
    return Token(TkCOMMENT).set_text(comment)
  end
  
  def read_escape
    res = ""
    case ch = getc
    when /[0-7]/
      ungetc ch
      3.times do
	case ch = getc
	when /[0-7]/
	when nil
	  break
	else
	  ungetc
	  break
	end
        res << ch
      end
      
    when "x"
      res << ch
      2.times do
	case ch = getc
	when /[0-9a-fA-F]/
	when nil
	  break
	else
	  ungetc
	  break
	end
        res << ch
      end

    when "M"
      res << ch
      if (ch = getc) != '-'
	ungetc
      else
        res << ch
	if (ch = getc) == "\\" #"
          res << ch
	  res << read_escape
        else
          res << ch
	end
      end

    when "C", "c" #, "^"
      res << ch
      if ch == "C" and (ch = getc) != "-"
	ungetc
      else
        res << ch
        if (ch = getc) == "\\" #"
          res << ch
          res << read_escape
        else
          res << ch
        end
      end
    else
      res << ch
    end
    res
  end
end



# Extract code elements from a source file, returning a TopLevel
# object containing the constituent file elements.
#
# This file is based on rtags

module RDoc

  GENERAL_MODIFIERS = [ 'nodoc' ].freeze

  CLASS_MODIFIERS = GENERAL_MODIFIERS

  ATTR_MODIFIERS  = GENERAL_MODIFIERS

  CONSTANT_MODIFIERS = GENERAL_MODIFIERS

  METHOD_MODIFIERS = GENERAL_MODIFIERS + 
    [ 'arg', 'args', 'yield', 'yields', 'notnew', 'not-new', 'not_new', 'doc' ]


  class RubyParser
    include RubyToken
    include TokenStream

    extend ParserFactory

    parse_files_matching(/\.rbw?$/)


    def initialize(top_level, file_name, content, options, stats)
      @options = options
      @stats   = stats
      @size = 0
      @token_listeners = nil
      @input_file_name = file_name
      @scanner = RubyLex.new(content)
      @scanner.exception_on_syntax_error = false
      @top_level = top_level
      @progress = $stderr unless options.quiet
    end

    def scan
      @tokens = []
      @unget_read = []
      @read = []
      catch(:eof) do
        catch(:enddoc) do
          begin
            parse_toplevel_statements(@top_level)
          rescue Exception => e
            $stderr.puts "\n\n"
            $stderr.puts "RDoc failure in #@input_file_name at or around " +
                         "line #{@scanner.line_no} column #{@scanner.char_no}"
            $stderr.puts 
            $stderr.puts "Before reporting this, could you check that the file"
            $stderr.puts "you're documenting compiles cleanly--RDoc is not a"
            $stderr.puts "full Ruby parser, and gets confused easily if fed"
            $stderr.puts "invalid programs."
            $stderr.puts
            $stderr.puts "The internal error was:\n\n"
            
            e.set_backtrace(e.backtrace[0,4])
            raise
          end
        end
      end
      @top_level
    end

    private 

    def make_message(msg)
      prefix = "\n" + @input_file_name + ":"
      if @scanner
        prefix << "#{@scanner.line_no}:#{@scanner.char_no}: "
      end
      return prefix + msg
    end

    def warn(msg)
      return if @options.quiet
      msg = make_message msg
      $stderr.puts msg
    end

    def error(msg)
      msg = make_message msg
      $stderr.puts msg
      exit(1)
    end

    def progress(char)
      unless @options.quiet
        @progress.print(char)
	@progress.flush
      end
    end

    def add_token_listener(obj)
      @token_listeners ||= []
      @token_listeners << obj
    end

    def remove_token_listener(obj)
      @token_listeners.delete(obj)
    end

    def get_tk
      tk = nil
      if @tokens.empty?
	tk = @scanner.token
	@read.push @scanner.get_read
	puts "get_tk1 => #{tk.inspect}" if $TOKEN_DEBUG
      else
	@read.push @unget_read.shift
	tk = @tokens.shift
	puts "get_tk2 => #{tk.inspect}" if $TOKEN_DEBUG
      end

      if tk.kind_of?(TkSYMBEG)
        set_token_position(tk.line_no, tk.char_no)
        tk1 = get_tk
        if tk1.kind_of?(TkId) || tk1.kind_of?(TkOp)
          tk = Token(TkSYMBOL).set_text(":" + tk1.name)
          # remove the identifier we just read (we're about to
          # replace it with a symbol)
          @token_listeners.each do |obj|
            obj.pop_token
          end if @token_listeners
        else
          warn("':' not followed by identifier or operator")
          tk = tk1
        end
      end

      # inform any listeners of our shiny new token
      @token_listeners.each do |obj|
        obj.add_token(tk)
      end if @token_listeners

      tk
    end

    def peek_tk
      unget_tk(tk = get_tk)
      tk
    end

    def unget_tk(tk)
      @tokens.unshift tk
      @unget_read.unshift @read.pop

      # Remove this token from any listeners
      @token_listeners.each do |obj|
        obj.pop_token
      end if @token_listeners
    end

    def skip_tkspace(skip_nl = true)
      tokens = []
      while ((tk = get_tk).kind_of?(TkSPACE) ||
	     (skip_nl && tk.kind_of?(TkNL)))
	tokens.push tk
      end
      unget_tk(tk)
      tokens
    end

    def get_tkread
      read = @read.join("")
      @read = []
      read
    end

    def peek_read
      @read.join('')
    end

    NORMAL = "::"
    SINGLE = "<<"

    # Look for the first comment in a file that isn't
    # a shebang line.

    def collect_first_comment
      skip_tkspace
      res = ''
      first_line = true

      tk = get_tk
      while tk.kind_of?(TkCOMMENT)
        if first_line && /\A#!/ =~ tk.text
          skip_tkspace
          tk = get_tk
        elsif first_line && /\A#\s*-\*-/ =~ tk.text
          first_line = false
          skip_tkspace
          tk = get_tk
        else
          first_line = false
          res << tk.text << "\n"
          tk = get_tk
          if tk.kind_of? TkNL
            skip_tkspace(false)
            tk = get_tk
          end
        end
      end
      unget_tk(tk)
      res
    end

    def parse_toplevel_statements(container)
      comment = collect_first_comment
      look_for_directives_in(container, comment)
      container.comment = comment unless comment.empty?
      parse_statements(container, NORMAL, nil, comment)
    end
    
    def parse_statements(container, single=NORMAL, current_method=nil, comment='')
      nest = 1
      save_visibility = container.visibility
      
#      if container.kind_of?(TopLevel)
#      else
#        comment = ''
#      end

      non_comment_seen = true
      
      while tk = get_tk
        
        keep_comment = false
        
        non_comment_seen = true unless tk.kind_of?(TkCOMMENT)
        
	case tk

        when TkNL
          skip_tkspace(true)   # Skip blanks and newlines
          tk = get_tk
          if tk.kind_of?(TkCOMMENT)
            if non_comment_seen
              comment = ''
              non_comment_seen = false
            end
            while tk.kind_of?(TkCOMMENT)
              comment << tk.text << "\n"
              tk = get_tk          # this is the newline 
              skip_tkspace(false)  # leading spaces
              tk = get_tk
            end
            unless comment.empty?
              look_for_directives_in(container, comment) 
              if container.done_documenting
                container.ongoing_visibility = save_visibility
#                return
              end
            end
            keep_comment = true
          else
            non_comment_seen = true
          end
          unget_tk(tk)
          keep_comment = true


	when TkCLASS
	  if container.document_children
            parse_class(container, single, tk, comment)
	  else
	    nest += 1
          end

	when TkMODULE
	  if container.document_children
            parse_module(container, single, tk, comment)
	  else
	    nest += 1
          end

	when TkDEF
	  if container.document_self
	    parse_method(container, single, tk, comment)
	  else
	    nest += 1
          end

        when TkCONSTANT
          if container.document_self
            parse_constant(container, single, tk, comment)
          end

	when TkALIAS
 	  if container.document_self
	    parse_alias(container, single, tk, comment)
	  end

        when TkYIELD
          if current_method.nil?
            warn("Warning: yield outside of method") if container.document_self
          else
            parse_yield(container, single, tk, current_method)
          end

          # Until and While can have a 'do', which shouldn't increas
          # the nesting. We can't solve the general case, but we can
          # handle most occurrences by ignoring a do at the end of a line

        when  TkUNTIL, TkWHILE
          nest += 1
          puts "FOUND #{tk.class} in #{container.name}, nest = #{nest}, " +
            "line #{tk.line_no}" if $DEBUG
          skip_optional_do_after_expression

          # 'for' is trickier
        when TkFOR
          nest += 1
          puts "FOUND #{tk.class} in #{container.name}, nest = #{nest}, " +
            "line #{tk.line_no}" if $DEBUG
          skip_for_variable
          skip_optional_do_after_expression

	when TkCASE, TkDO, TkIF, TkUNLESS, TkBEGIN
	  nest += 1
          puts "Found #{tk.class} in #{container.name}, nest = #{nest}, " +
            "line #{tk.line_no}" if $DEBUG

	when TkIDENTIFIER
          if nest == 1 and current_method.nil?
            case tk.name
            when "private", "protected", "public",
                 "private_class_method", "public_class_method"
              parse_visibility(container, single, tk)
              keep_comment = true
            when "attr"
              parse_attr(container, single, tk, comment)
            when /^attr_(reader|writer|accessor)$/, @options.extra_accessors
              parse_attr_accessor(container, single, tk, comment)
            when "alias_method"
              if container.document_self
	        parse_alias(container, single, tk, comment)
	      end
            end
	  end
	  
	  case tk.name
	  when "require"
	    parse_require(container, comment)
	  when "include"
	    parse_include(container, comment)
	  end


	when TkEND
          nest -= 1
          puts "Found 'end' in #{container.name}, nest = #{nest}, line #{tk.line_no}" if $DEBUG
          puts "Method = #{current_method.name}" if $DEBUG and current_method
	  if nest == 0
            read_documentation_modifiers(container, CLASS_MODIFIERS)
            container.ongoing_visibility = save_visibility
            return
          end

	end

        comment = '' unless keep_comment
	begin
	  get_tkread
	  skip_tkspace(false)
	end while peek_tk == TkNL

      end
    end
    
    def parse_class(container, single, tk, comment, &block)
      progress("c")

      @stats.num_classes += 1

      container, name_t = get_class_or_module(container)

      case name_t
      when TkCONSTANT
	name = name_t.name
        superclass = "Object"

        if peek_tk.kind_of?(TkLT)
          get_tk
          skip_tkspace(true)
          superclass = get_class_specification
          superclass = "<unknown>" if superclass.empty?
        end

	if single == SINGLE
	  cls_type = SingleClass
	else
	  cls_type = NormalClass
	end

        cls = container.add_class(cls_type, name, superclass)
        read_documentation_modifiers(cls, CLASS_MODIFIERS)
        cls.record_location(@top_level)
	parse_statements(cls)
        cls.comment = comment

      when TkLSHFT
	case name = get_class_specification
	when "self", container.name
	  parse_statements(container, SINGLE, &block)
	else
          other = TopLevel.find_class_named(name)
          unless other
#            other = @top_level.add_class(NormalClass, name, nil)
#            other.record_location(@top_level)
#            other.comment = comment
            other = NormalClass.new("Dummy", nil)
          end
          read_documentation_modifiers(other, CLASS_MODIFIERS)
          parse_statements(other, SINGLE, &block)
	end

      else
	warn("Expected class name or '<<'. Got #{name_t.class}: #{name_t.text.inspect}")
      end
    end

    def parse_module(container, single, tk, comment)
      progress("m")
      @stats.num_modules += 1
      container, name_t  = get_class_or_module(container)
#      skip_tkspace
      name = name_t.name
      mod = container.add_module(NormalModule, name)
      mod.record_location(@top_level)
      read_documentation_modifiers(mod, CLASS_MODIFIERS)
      parse_statements(mod)
      mod.comment = comment
    end

    # Look for the name of a class of module (optionally with a leading :: or
    # with :: separated named) and return the ultimate name and container

    def get_class_or_module(container)
      skip_tkspace
      name_t = get_tk

      # class ::A -> A is in the top level
      if name_t.kind_of?(TkCOLON2)
        name_t = get_tk
        container = @top_level
      end

      skip_tkspace(false)

      while peek_tk.kind_of?(TkCOLON2)
        prev_container = container
        container = container.find_module_named(name_t.name)
        if !container
#          warn("Couldn't find module #{name_t.name}")
          container = prev_container.add_module(NormalModule, name_t.name)
        end
        get_tk
        name_t = get_tk
      end
      skip_tkspace(false)
      return [container, name_t]
    end

    def parse_constant(container, single, tk, comment)
      name = tk.name
      skip_tkspace(false)
      eq_tk = get_tk

      unless eq_tk.kind_of?(TkASSIGN)
        unget_tk(eq_tk)
        return
      end


      nest = 0
      get_tkread

      tk = get_tk
      if tk.kind_of? TkGT
        unget_tk(tk)
        unget_tk(eq_tk)
        return
      end

      loop do
        puts("Param: #{tk}, #{@scanner.continue} " +
          "#{@scanner.lex_state} #{nest}")  if $DEBUG

        case tk
        when TkSEMICOLON
          break
        when TkLPAREN, TkfLPAREN
          nest += 1
        when TkRPAREN
          nest -= 1
        when TkCOMMENT
          if nest <= 0 && @scanner.lex_state == EXPR_END
            unget_tk(tk)
            break
          end
        when TkNL
          if (@scanner.lex_state == EXPR_END and nest <= 0) || !@scanner.continue
            unget_tk(tk)
            break
          end
        end
        tk = get_tk
      end

      res = get_tkread.tr("\n", " ").strip
      res = "" if res == ";"
      con = Constant.new(name, res, comment)
      read_documentation_modifiers(con, CONSTANT_MODIFIERS)
      if con.document_self
	container.add_constant(con)
      end
    end

    def parse_method(container, single, tk, comment)
      progress(".")
      @stats.num_methods += 1
      line_no = tk.line_no
      column  = tk.char_no
      
      start_collecting_tokens
      add_token(tk)
      add_token_listener(self)
      
      @scanner.instance_eval{@lex_state = EXPR_FNAME}
      skip_tkspace(false)
      name_t = get_tk
      back_tk = skip_tkspace
      meth = nil
      added_container = false

      dot = get_tk
      if dot.kind_of?(TkDOT) or dot.kind_of?(TkCOLON2)
	@scanner.instance_eval{@lex_state = EXPR_FNAME}
	skip_tkspace
	name_t2 = get_tk
	case name_t
	when TkSELF
	  name = name_t2.name
	when TkCONSTANT
          name = name_t2.name
          prev_container = container
          container = container.find_module_named(name_t.name)
          if !container
            added_container = true
            obj = name_t.name.split("::").inject(Object) do |state, item|
              state.const_get(item)
            end rescue nil

            type = obj.class == Class ? NormalClass : NormalModule
            if not [Class, Module].include?(obj.class)
              warn("Couldn't find #{name_t.name}. Assuming it's a module")
            end

            if type == NormalClass then
              container = prev_container.add_class(type, name_t.name, obj.superclass.name)
            else
              container = prev_container.add_module(type, name_t.name)
            end
          end
	else
	  # warn("Unexpected token '#{name_t2.inspect}'")
	  # break
          skip_method(container)
          return
	end
	meth =  AnyMethod.new(get_tkread, name)
        meth.singleton = true
      else
	unget_tk dot
	back_tk.reverse_each do
	  |tk|
	  unget_tk tk
	end
	name = name_t.name

        meth =  AnyMethod.new(get_tkread, name)
        meth.singleton = (single == SINGLE)
      end

      remove_token_listener(self)

      meth.start_collecting_tokens
      indent = TkSPACE.new(1,1)
      indent.set_text(" " * column)

      meth.add_tokens([TkCOMMENT.new(line_no,
                                     1,
                                     "# File #{@top_level.file_absolute_name}, line #{line_no}"),
                        NEWLINE_TOKEN,
                        indent])

      meth.add_tokens(@token_stream)

      add_token_listener(meth)

      @scanner.instance_eval{@continue = false}
      parse_method_parameters(meth)

      if meth.document_self
        container.add_method(meth)
      elsif added_container
        container.document_self = false
      end

      # Having now read the method parameters and documentation modifiers, we
      # now know whether we have to rename #initialize to ::new

      if name == "initialize" && !meth.singleton
        if meth.dont_rename_initialize
          meth.visibility = :protected
        else
          meth.singleton = true
          meth.name = "new"
          meth.visibility = :public
        end
      end
      
      parse_statements(container, single, meth)
      
      remove_token_listener(meth)

      # Look for a 'call-seq' in the comment, and override the
      # normal parameter stuff

      if comment.sub!(/:?call-seq:(.*?)^\s*\#?\s*$/m, '')
        seq = $1
        seq.gsub!(/^\s*\#\s*/, '')
        meth.call_seq = seq
      end
      
      meth.comment = comment

    end
    
    def skip_method(container)
      meth =  AnyMethod.new("", "anon")
      parse_method_parameters(meth)
      parse_statements(container, false, meth)
    end
    
    # Capture the method's parameters. Along the way,
    # look for a comment containing 
    #
    #    # yields: ....
    #
    # and add this as the block_params for the method

    def parse_method_parameters(method)
      res = parse_method_or_yield_parameters(method)
      res = "(" + res + ")" unless res[0] == ?(
      method.params = res unless method.params
      if method.block_params.nil?
          skip_tkspace(false)
	  read_documentation_modifiers(method, METHOD_MODIFIERS)
      end
    end

    def parse_method_or_yield_parameters(method=nil, modifiers=METHOD_MODIFIERS)
      skip_tkspace(false)
      tk = get_tk

      # Little hack going on here. In the statement
      #  f = 2*(1+yield)
      # We see the RPAREN as the next token, so we need
      # to exit early. This still won't catch all cases
      # (such as "a = yield + 1"
      end_token = case tk
                  when TkLPAREN, TkfLPAREN
                    TkRPAREN
                  when TkRPAREN
                    return ""
                  else
                    TkNL
                  end
      nest = 0

      loop do
        puts("Param: #{tk.inspect}, #{@scanner.continue} " +
          "#{@scanner.lex_state} #{nest}")  if $DEBUG
        case tk
        when TkSEMICOLON
          break
        when TkLBRACE
          nest += 1
        when TkRBRACE
          # we might have a.each {|i| yield i }
          unget_tk(tk) if nest.zero?
          nest -= 1
          break if nest <= 0
        when TkLPAREN, TkfLPAREN
          nest += 1
        when end_token
          if end_token == TkRPAREN
            nest -= 1
            break if @scanner.lex_state == EXPR_END and nest <= 0
          else
            break unless @scanner.continue
          end
        when method && method.block_params.nil? && TkCOMMENT
	  unget_tk(tk)
	  read_documentation_modifiers(method, modifiers)
        end
        tk = get_tk
      end
      res = get_tkread.tr("\n", " ").strip
      res = "" if res == ";"
      res
    end

    # skip the var [in] part of a 'for' statement
    def skip_for_variable
      skip_tkspace(false)
      tk = get_tk
      skip_tkspace(false)
      tk = get_tk
      unget_tk(tk) unless tk.kind_of?(TkIN)
    end

    # while, until, and for have an optional 
    def skip_optional_do_after_expression
      skip_tkspace(false)
      tk = get_tk
      case tk
      when TkLPAREN, TkfLPAREN
        end_token = TkRPAREN
      else
        end_token = TkNL
      end

      nest = 0
      @scanner.instance_eval{@continue = false}

      loop do
        puts("\nWhile: #{tk}, #{@scanner.continue} " +
          "#{@scanner.lex_state} #{nest}") if $DEBUG
        case tk
        when TkSEMICOLON
          break
        when TkLPAREN, TkfLPAREN
          nest += 1
        when TkDO
          break if nest.zero?
        when end_token
          if end_token == TkRPAREN
            nest -= 1
            break if @scanner.lex_state == EXPR_END and nest.zero?
          else
            break unless @scanner.continue
          end
        end
        tk = get_tk
      end
      skip_tkspace(false)
      if peek_tk.kind_of? TkDO
        get_tk
      end
    end
    
    # Return a superclass, which can be either a constant
    # of an expression

    def get_class_specification
      tk = get_tk
      return "self" if tk.kind_of?(TkSELF)
        
      res = ""
      while tk.kind_of?(TkCOLON2) ||
          tk.kind_of?(TkCOLON3)   ||
          tk.kind_of?(TkCONSTANT)   
        
        res += tk.text
        tk = get_tk
      end

      unget_tk(tk)
      skip_tkspace(false)

      get_tkread # empty out read buffer

      tk = get_tk

      case tk
      when TkNL, TkCOMMENT, TkSEMICOLON
        unget_tk(tk)
        return res
      end

      res += parse_call_parameters(tk)
      res
    end

    def parse_call_parameters(tk)

      end_token = case tk
                  when TkLPAREN, TkfLPAREN
                    TkRPAREN
                  when TkRPAREN
                    return ""
                  else
                    TkNL
                  end
      nest = 0

      loop do
        puts("Call param: #{tk}, #{@scanner.continue} " +
          "#{@scanner.lex_state} #{nest}") if $DEBUG
        case tk
        when TkSEMICOLON
          break
        when TkLPAREN, TkfLPAREN
          nest += 1
        when end_token
          if end_token == TkRPAREN
            nest -= 1
            break if @scanner.lex_state == EXPR_END and nest <= 0
          else
            break unless @scanner.continue
          end
        when TkCOMMENT
	  unget_tk(tk)
	  break
        end
        tk = get_tk
      end
      res = get_tkread.tr("\n", " ").strip
      res = "" if res == ";"
      res
    end


    # Parse a constant, which might be qualified by
    # one or more class or module names

    def get_constant
      res = ""
      skip_tkspace(false)
      tk = get_tk

      while tk.kind_of?(TkCOLON2) ||
          tk.kind_of?(TkCOLON3)   ||
          tk.kind_of?(TkCONSTANT)          
        
        res += tk.text
        tk = get_tk
      end

#      if res.empty?
#        warn("Unexpected token #{tk} in constant")
#      end 
      unget_tk(tk)
      res
    end

    # Get a constant that may be surrounded by parens
    
    def get_constant_with_optional_parens
      skip_tkspace(false)
      nest = 0
      while (tk = peek_tk).kind_of?(TkLPAREN)  || tk.kind_of?(TkfLPAREN)
        get_tk
        skip_tkspace(true)
        nest += 1
      end

      name = get_constant

      while nest > 0
        skip_tkspace(true)
        tk = get_tk
        nest -= 1 if tk.kind_of?(TkRPAREN)
      end
      name
    end

    # Directives are modifier comments that can appear after class, module,
    # or method names. For example
    #
    #   def fred    # :yields:  a, b
    #
    # or
    #
    #   class SM  # :nodoc:
    #
    # we return the directive name and any parameters as a two element array
    
    def read_directive(allowed)
      tk = get_tk
      puts "directive: #{tk.inspect}" if $DEBUG
      result = nil
      if tk.kind_of?(TkCOMMENT) 
        if tk.text =~ /\s*:?(\w+):\s*(.*)/
          directive = $1.downcase
          if allowed.include?(directive)
            result = [directive, $2]
          end
        end
      else
        unget_tk(tk)
      end
      result
    end

    
    def read_documentation_modifiers(context, allow)
      dir = read_directive(allow)

      case dir[0]

      when "notnew", "not_new", "not-new"
        context.dont_rename_initialize = true

      when "nodoc"
        context.document_self = false
	if dir[1].downcase == "all"
	  context.document_children = false
	end

      when "doc"
        context.document_self = true
        context.force_documentation = true

      when "yield", "yields"
        unless context.params.nil?
          context.params.sub!(/(,|)\s*&\w+/,'') # remove parameter &proc
        end
	context.block_params = dir[1]

      when "arg", "args"
        context.params = dir[1]
      end if dir
    end

    
    # Look for directives in a normal comment block:
    #
    #   #--       - don't display comment from this point forward
    #  
    #
    # This routine modifies it's parameter

    def look_for_directives_in(context, comment)

      preprocess = SM::PreProcess.new(@input_file_name,
                                      @options.rdoc_include)

      preprocess.handle(comment) do |directive, param|
        case directive
        when "stopdoc"
          context.stop_doc
          ""
        when "startdoc"
          context.start_doc
          context.force_documentation = true
          ""

        when "enddoc"
          #context.done_documenting = true
          #""
          throw :enddoc

        when "main"
          options = Options.instance
          options.main_page = param
	  ""

        when "title"
          options = Options.instance
          options.title = param
          ""

        when "section"
          context.set_current_section(param, comment)
          comment.replace("") # 1.8 doesn't support #clear
          break 
        else
          warn "Unrecognized directive '#{directive}'"
          break
        end
      end

      remove_private_comments(comment)
    end

    def remove_private_comments(comment)
      comment.gsub!(/^#--.*?^#\+\+/m, '')
      comment.sub!(/^#--.*/m, '')
    end



    def get_symbol_or_name
      tk = get_tk
      case tk
      when  TkSYMBOL
        tk.text.sub(/^:/, '')
      when TkId, TkOp
        tk.name
      when TkSTRING
        tk.text
      else
        raise "Name or symbol expected (got #{tk})"
      end
    end
    
    def parse_alias(context, single, tk, comment)
      skip_tkspace
      if (peek_tk.kind_of? TkLPAREN)
        get_tk
        skip_tkspace
      end
      new_name = get_symbol_or_name
      @scanner.instance_eval{@lex_state = EXPR_FNAME}
      skip_tkspace
      if (peek_tk.kind_of? TkCOMMA)
        get_tk
        skip_tkspace
      end
      old_name = get_symbol_or_name

      al = Alias.new(get_tkread, old_name, new_name, comment)
      read_documentation_modifiers(al, ATTR_MODIFIERS)
      if al.document_self
	context.add_alias(al)
      end
    end

    def parse_yield_parameters
      parse_method_or_yield_parameters
    end

  def parse_yield(context, single, tk, method)
    if method.block_params.nil?
      get_tkread
      @scanner.instance_eval{@continue = false}
      method.block_params = parse_yield_parameters
    end
  end

  def parse_require(context, comment)
    skip_tkspace_comment
    tk = get_tk
    if tk.kind_of? TkLPAREN
      skip_tkspace_comment
      tk = get_tk
    end

    name = nil
    case tk
    when TkSTRING
      name = tk.text
#    when TkCONSTANT, TkIDENTIFIER, TkIVAR, TkGVAR
#      name = tk.name
    when TkDSTRING
      warn "Skipping require of dynamic string: #{tk.text}"
 #   else
 #     warn "'require' used as variable"
    end
    if name
      context.add_require(Require.new(name, comment))
    else
      unget_tk(tk)
    end
  end

  def parse_include(context, comment)
    loop do
      skip_tkspace_comment
      name = get_constant_with_optional_parens
      unless name.empty?
        context.add_include(Include.new(name, comment))
      end
      return unless peek_tk.kind_of?(TkCOMMA)
      get_tk
    end
  end

    def get_bool
      skip_tkspace
      tk = get_tk
      case tk
      when TkTRUE
        true
      when TkFALSE, TkNIL
        false
      else
        unget_tk tk
        true
      end
    end

    def parse_attr(context, single, tk, comment)
      args = parse_symbol_arg(1)
      if args.size > 0
	name = args[0]
        rw = "R"
        skip_tkspace(false)
        tk = get_tk
        if tk.kind_of? TkCOMMA
          rw = "RW" if get_bool
        else
          unget_tk tk
        end
	att = Attr.new(get_tkread, name, rw, comment)
	read_documentation_modifiers(att, ATTR_MODIFIERS)
	if att.document_self
	  context.add_attribute(att)
	end
      else
	warn("'attr' ignored - looks like a variable")
      end    

    end

    def parse_visibility(container, single, tk)
      singleton = (single == SINGLE)
      vis = case tk.name
            when "private"   then :private
            when "protected" then :protected
            when "public"    then :public
            when "private_class_method"
              singleton = true
              :private
            when "public_class_method"
              singleton = true
              :public
            else raise "Invalid visibility: #{tk.name}"
            end
            
      skip_tkspace_comment(false)
      case peek_tk
        # Ryan Davis suggested the extension to ignore modifiers, because he
        # often writes
        #
        #   protected unless $TESTING
        #
      when TkNL, TkUNLESS_MOD, TkIF_MOD
#        error("Missing argument") if singleton        
        container.ongoing_visibility = vis
      else
        args = parse_symbol_arg
        container.set_visibility_for(args, vis, singleton)
      end
    end

    def parse_attr_accessor(context, single, tk, comment)
      args = parse_symbol_arg
      read = get_tkread
      rw = "?"

      # If nodoc is given, don't document any of them

      tmp = CodeObject.new
      read_documentation_modifiers(tmp, ATTR_MODIFIERS)
      return unless tmp.document_self

      case tk.name
      when "attr_reader"   then rw = "R"
      when "attr_writer"   then rw = "W"
      when "attr_accessor" then rw = "RW"
      else
        rw = @options.extra_accessor_flags[tk.name]
      end
      
      for name in args
	att = Attr.new(get_tkread, name, rw, comment)
        context.add_attribute(att)
      end    
    end

    def skip_tkspace_comment(skip_nl = true)
      loop do
        skip_tkspace(skip_nl)
        return unless peek_tk.kind_of? TkCOMMENT
        get_tk
      end
    end

    def parse_symbol_arg(no = nil)

      args = []
      skip_tkspace_comment
      case tk = get_tk
      when TkLPAREN
	loop do
	  skip_tkspace_comment
	  if tk1 = parse_symbol_in_arg
	    args.push tk1
	    break if no and args.size >= no
	  end
	  
	  skip_tkspace_comment
	  case tk2 = get_tk
	  when TkRPAREN
	    break
	  when TkCOMMA
	  else
           warn("unexpected token: '#{tk2.inspect}'") if $DEBUG
	    break
	  end
	end
      else
	unget_tk tk
	if tk = parse_symbol_in_arg
	  args.push tk
	  return args if no and args.size >= no
	end

	loop do
#	  skip_tkspace_comment(false)
	  skip_tkspace(false)

	  tk1 = get_tk
	  unless tk1.kind_of?(TkCOMMA) 
	    unget_tk tk1
	    break
	  end
	  
	  skip_tkspace_comment
	  if tk = parse_symbol_in_arg
	    args.push tk
	    break if no and args.size >= no
	  end
	end
      end
      args
    end

    def parse_symbol_in_arg
      case tk = get_tk
      when TkSYMBOL
        tk.text.sub(/^:/, '')
      when TkSTRING
	eval @read[-1]
      else
	warn("Expected symbol or string, got #{tk.inspect}") if $DEBUG
	nil
      end
    end
  end

end
PK     Z\%l@  @    rdoc/template.rbnu [        # Cheap-n-cheerful HTML page template system. You create a 
# template containing:
#
# * variable names between percent signs (<tt>%fred%</tt>)
# * blocks of repeating stuff:
#
#     START:key
#       ... stuff
#     END:key
#
# You feed the code a hash. For simple variables, the values
# are resolved directly from the hash. For blocks, the hash entry
# corresponding to +key+ will be an array of hashes. The block will
# be generated once for each entry. Blocks can be nested arbitrarily
# deeply.
#
# The template may also contain
#
#   IF:key
#     ... stuff
#   ENDIF:key
#
# _stuff_ will only be included in the output if the corresponding
# key is set in the value hash.
#
# Usage:  Given a set of templates <tt>T1, T2,</tt> etc
#
#            values = { "name" => "Dave", state => "TX" }
#
#            t = TemplatePage.new(T1, T2, T3)
#            File.open(name, "w") {|f| t.write_html_on(f, values)}
#         or
#            res = ''
#            t.write_html_on(res, values)
#
#

class TemplatePage

  ##########
  # A context holds a stack of key/value pairs (like a symbol
  # table). When asked to resolve a key, it first searches the top of
  # the stack, then the next level, and so on until it finds a match
  # (or runs out of entries)

  class Context
    def initialize
      @stack = []
    end

    def push(hash)
      @stack.push(hash)
    end

    def pop
      @stack.pop
    end

    # Find a scalar value, throwing an exception if not found. This
    # method is used when substituting the %xxx% constructs

    def find_scalar(key)
      @stack.reverse_each do |level|
        if val = level[key]
          return val unless val.kind_of? Array
        end
      end
      raise "Template error: can't find variable '#{key}'"
    end

    # Lookup any key in the stack of hashes

    def lookup(key)
      @stack.reverse_each do |level|
        val = level[key]
        return val if val
      end
      nil
    end
  end

  #########
  # Simple class to read lines out of a string

  class LineReader
    # we're initialized with an array of lines
    def initialize(lines)
      @lines = lines
    end

    # read the next line 
    def read
      @lines.shift
    end

    # Return a list of lines up to the line that matches
    # a pattern. That last line is discarded.
    def read_up_to(pattern)
      res = []
      while line = read
        if pattern.match(line)
          return LineReader.new(res) 
        else
          res << line
        end
      end
      raise "Missing end tag in template: #{pattern.source}"
    end

    # Return a copy of ourselves that can be modified without
    # affecting us
    def dup
      LineReader.new(@lines.dup)
    end
  end



  # +templates+ is an array of strings containing the templates.
  # We start at the first, and substitute in subsequent ones
  # where the string <tt>!INCLUDE!</tt> occurs. For example,
  # we could have the overall page template containing
  #
  #   <html><body>
  #     <h1>Master</h1>
  #     !INCLUDE!
  #   </bost></html>
  #
  # and substitute subpages in to it by passing [master, sub_page].
  # This gives us a cheap way of framing pages

  def initialize(*templates)
    result = "!INCLUDE!"
    templates.each do |content|
      result.sub!(/!INCLUDE!/, content)
    end
    @lines = LineReader.new(result.split($/))
  end

  # Render the templates into HTML, storing the result on +op+ 
  # using the method <tt><<</tt>. The <tt>value_hash</tt> contains
  # key/value pairs used to drive the substitution (as described above)

  def write_html_on(op, value_hash)
    @context = Context.new
    op << substitute_into(@lines, value_hash).tr("\000", '\\')
  end


  # Substitute a set of key/value pairs into the given template. 
  # Keys with scalar values have them substituted directly into
  # the page. Those with array values invoke <tt>substitute_array</tt>
  # (below), which examples a block of the template once for each 
  # row in the array.
  #
  # This routine also copes with the <tt>IF:</tt>_key_ directive,
  # removing chunks of the template if the corresponding key
  # does not appear in the hash, and the START: directive, which
  # loops its contents for each value in an array

  def substitute_into(lines, values)
    @context.push(values)
    skip_to = nil
    result = []

    while line = lines.read

      case line

      when /^IF:(\w+)/
        lines.read_up_to(/^ENDIF:#$1/) unless @context.lookup($1)

    when /^IFNOT:(\w+)/
        lines.read_up_to(/^ENDIF:#$1/) if @context.lookup($1)

      when /^ENDIF:/
        ;

      when /^START:(\w+)/
        tag = $1
        body = lines.read_up_to(/^END:#{tag}/)
        inner_values = @context.lookup(tag)
        raise "unknown tag: #{tag}" unless inner_values
        raise "not array: #{tag}"   unless inner_values.kind_of?(Array)
        inner_values.each do |vals|
          result << substitute_into(body.dup, vals)
        end
      else
        result << expand_line(line.dup)
      end
    end

    @context.pop

    result.join("\n")
  end

  # Given an individual line, we look for %xxx% constructs and 
  # HREF:ref:name: constructs, substituting for each.

  def expand_line(line)
    # Generate a cross reference if a reference is given,
    # otherwise just fill in the name part

    line.gsub!(/HREF:(\w+?):(\w+?):/) {
      ref = @context.lookup($1)
      name = @context.find_scalar($2)

      if ref and !ref.kind_of?(Array)
	"<a href=\"#{ref}\">#{name}</a>"
      else
	name
      end
    }

    # Substitute in values for %xxx% constructs.  This is made complex
    # because the replacement string may contain characters that are
    # meaningful to the regexp (like \1)

    line = line.gsub(/%([a-zA-Z]\w*)%/) {
      val = @context.find_scalar($1) 
      val.tr('\\', "\000")
    }


    line
  rescue Exception => e
    $stderr.puts "Error in template: #{e}"
    $stderr.puts "Original line: #{line}"
    exit
  end

end

PK     Z\9O9  9    rdoc/ri/ri_formatter.rbnu [        module RI
  class TextFormatter

    attr_reader :indent
    
    def initialize(options, indent)
      @options = options
      @width   = options.width
      @indent  = indent
    end
    
    
    ######################################################################
    
    def draw_line(label=nil)
      len = @width
      len -= (label.size+1) if label
      print "-"*len
      if label
        print(" ")
        bold_print(label) 
      end
      puts
    end
    
    ######################################################################
    
    def wrap(txt,  prefix=@indent, linelen=@width)
      return unless txt && !txt.empty?
      work = conv_markup(txt)
      textLen = linelen - prefix.length
      patt = Regexp.new("^(.{0,#{textLen}})[ \n]")
      next_prefix = prefix.tr("^ ", " ")

      res = []

      while work.length > textLen
        if work =~ patt
          res << $1
          work.slice!(0, $&.length)
        else
          res << work.slice!(0, textLen)
        end
      end
      res << work if work.length.nonzero?
      puts(prefix + res.join("\n" + next_prefix))
    end

    ######################################################################

    def blankline
      puts
    end
    
    ######################################################################

    # called when we want to ensure a nbew 'wrap' starts on a newline
    # Only needed for HtmlFormatter, because the rest do their
    # own line breaking

    def break_to_newline
    end
    
    ######################################################################

    def bold_print(txt)
      print txt
    end

    ######################################################################

    def raw_print_line(txt)
      puts txt
    end

    ######################################################################

    # convert HTML entities back to ASCII
    def conv_html(txt)
      txt.
          gsub(/&gt;/, '>').
          gsub(/&lt;/, '<').
          gsub(/&quot;/, '"').
          gsub(/&amp;/, '&')
          
    end

    # convert markup into display form
    def conv_markup(txt)
      txt.
          gsub(%r{<tt>(.*?)</tt>}) { "+#$1+" } .
          gsub(%r{<code>(.*?)</code>}) { "+#$1+" } .
          gsub(%r{<b>(.*?)</b>}) { "*#$1*" } .
          gsub(%r{<em>(.*?)</em>}) { "_#$1_" }
    end

    ######################################################################

    def display_list(list)
      case list.type

      when SM::ListBase::BULLET 
        prefixer = proc { |ignored| @indent + "*   " }

      when SM::ListBase::NUMBER,
      SM::ListBase::UPPERALPHA,
      SM::ListBase::LOWERALPHA

        start = case list.type
                when SM::ListBase::NUMBER      then 1
                when  SM::ListBase::UPPERALPHA then 'A'
                when SM::ListBase::LOWERALPHA  then 'a'
                end
        prefixer = proc do |ignored|
          res = @indent + "#{start}.".ljust(4)
          start = start.succ
          res
        end
        
      when SM::ListBase::LABELED
        prefixer = proc do |li|
          li.label
        end

      when SM::ListBase::NOTE
        longest = 0
        list.contents.each do |item|
          if item.kind_of?(SM::Flow::LI) && item.label.length > longest
            longest = item.label.length
          end
        end

        prefixer = proc do |li|
          @indent + li.label.ljust(longest+1)
        end

      else
        fail "unknown list type"

      end

      list.contents.each do |item|
        if item.kind_of? SM::Flow::LI
          prefix = prefixer.call(item)
          display_flow_item(item, prefix)
        else
          display_flow_item(item)
        end
       end
    end

    ######################################################################

    def display_flow_item(item, prefix=@indent)
      case item
      when SM::Flow::P, SM::Flow::LI
        wrap(conv_html(item.body), prefix)
        blankline
        
      when SM::Flow::LIST
        display_list(item)

      when SM::Flow::VERB
        display_verbatim_flow_item(item, @indent)

      when SM::Flow::H
        display_heading(conv_html(item.text), item.level, @indent)

      when SM::Flow::RULE
        draw_line

      else
        fail "Unknown flow element: #{item.class}"
      end
    end

    ######################################################################

    def display_verbatim_flow_item(item, prefix=@indent)
        item.body.split(/\n/).each do |line|
          print @indent, conv_html(line), "\n"
        end
        blankline
    end

    ######################################################################

    def display_heading(text, level, indent)
      text = strip_attributes(text)
      case level
      when 1
        ul = "=" * text.length
        puts
        puts text.upcase
        puts ul
#        puts
        
      when 2
        ul = "-" * text.length
        puts
        puts text
        puts ul
#        puts
      else
        print indent, text, "\n"
      end
    end


    def display_flow(flow)
      flow.each do |f|
        display_flow_item(f)
      end
    end

    def strip_attributes(txt)
      tokens = txt.split(%r{(</?(?:b|code|em|i|tt)>)})
      text = [] 
      attributes = 0
      tokens.each do |tok|
        case tok
        when %r{^</(\w+)>$}, %r{^<(\w+)>$}
          ;
        else
          text << tok
        end
      end
      text.join
    end


  end
  
  
  ######################################################################
  # Handle text with attributes. We're a base class: there are
  # different presentation classes (one, for example, uses overstrikes
  # to handle bold and underlining, while another using ANSI escape
  # sequences
  
  class AttributeFormatter < TextFormatter
    
    BOLD      = 1
    ITALIC    = 2
    CODE      = 4

    ATTR_MAP = {
      "b"    => BOLD,
      "code" => CODE,
      "em"   => ITALIC,
      "i"    => ITALIC,
      "tt"   => CODE
    }

    # TODO: struct?
    class AttrChar
      attr_reader :char
      attr_reader :attr

      def initialize(char, attr)
        @char = char
        @attr = attr
      end
    end

    
    class AttributeString
      attr_reader :txt

      def initialize
        @txt = []
        @optr = 0
      end

      def <<(char)
        @txt << char
      end

      def empty?
        @optr >= @txt.length
      end

      # accept non space, then all following spaces
      def next_word
        start = @optr
        len = @txt.length

        while @optr < len && @txt[@optr].char != " "
          @optr += 1
        end

        while @optr < len && @txt[@optr].char == " "
          @optr += 1
        end

        @txt[start...@optr]
      end
    end

    ######################################################################
    # overrides base class. Looks for <tt>...</tt> etc sequences
    # and generates an array of AttrChars. This array is then used
    # as the basis for the split

    def wrap(txt,  prefix=@indent, linelen=@width)
      return unless txt && !txt.empty?

      txt = add_attributes_to(txt)
      next_prefix = prefix.tr("^ ", " ")
      linelen -= prefix.size

      line = []

      until txt.empty?
        word = txt.next_word
        if word.size + line.size > linelen
          write_attribute_text(prefix, line)
          prefix = next_prefix
          line = []
        end
        line.concat(word)
      end

      write_attribute_text(prefix, line) if line.length > 0
    end

    protected

    # overridden in specific formatters

    def write_attribute_text(prefix, line)
      print prefix
      line.each do |achar|
        print achar.char
      end
      puts
    end

    # again, overridden

    def bold_print(txt)
      print txt
    end

    private

    def add_attributes_to(txt)
      tokens = txt.split(%r{(</?(?:b|code|em|i|tt)>)})
      text = AttributeString.new
      attributes = 0
      tokens.each do |tok|
        case tok
        when %r{^</(\w+)>$} then attributes &= ~(ATTR_MAP[$1]||0)
        when %r{^<(\w+)>$}  then attributes  |= (ATTR_MAP[$1]||0)
        else
          tok.split(//).each {|ch| text << AttrChar.new(ch, attributes)}
        end
      end
      text
    end

  end


  ##################################################
  
  # This formatter generates overstrike-style formatting, which
  # works with pagers such as man and less.

  class OverstrikeFormatter < AttributeFormatter

    BS = "\C-h"

    def write_attribute_text(prefix, line)
      print prefix
      line.each do |achar|
        attr = achar.attr
        if (attr & (ITALIC+CODE)) != 0
          print "_", BS
        end
        if (attr & BOLD) != 0
          print achar.char, BS
        end
        print achar.char
      end
      puts
    end

    # draw a string in bold
    def bold_print(text)
      text.split(//).each do |ch|
        print ch, BS, ch
      end
    end
  end

  ##################################################
  
  # This formatter uses ANSI escape sequences
  # to colorize stuff
  # works with pages such as man and less.

  class AnsiFormatter < AttributeFormatter

    def initialize(*args)
      print "\033[0m"
      super
    end

    def write_attribute_text(prefix, line)
      print prefix
      curr_attr = 0
      line.each do |achar|
        attr = achar.attr
        if achar.attr != curr_attr
          update_attributes(achar.attr)
          curr_attr = achar.attr
        end
        print achar.char
      end
      update_attributes(0) unless curr_attr.zero?
      puts
    end


    def bold_print(txt)
      print "\033[1m#{txt}\033[m"
    end

    HEADINGS = {
      1 => [ "\033[1;32m", "\033[m" ] ,
      2 => ["\033[4;32m", "\033[m" ],
      3 => ["\033[32m", "\033[m" ]
    }

    def display_heading(text, level, indent)
      level = 3 if level > 3
      heading = HEADINGS[level]
      print indent
      print heading[0]
      print strip_attributes(text)
      puts heading[1]
    end
    
    private

    ATTR_MAP = {
      BOLD   => "1",
      ITALIC => "33",
      CODE   => "36"
    }

    def update_attributes(attr)
      str = "\033["
      for quality in [ BOLD, ITALIC, CODE]
        unless (attr & quality).zero?
          str << ATTR_MAP[quality]
        end
      end
      print str, "m"
    end
  end

  ##################################################
  
  # This formatter uses HTML.

  class HtmlFormatter < AttributeFormatter

    def initialize(*args)
      super
    end

    def write_attribute_text(prefix, line)
      curr_attr = 0
      line.each do |achar|
        attr = achar.attr
        if achar.attr != curr_attr
          update_attributes(curr_attr, achar.attr)
          curr_attr = achar.attr
        end
        print(escape(achar.char))
      end
      update_attributes(curr_attr, 0) unless curr_attr.zero?
    end

    def draw_line(label=nil)
      if label != nil
        bold_print(label)
      end
      puts("<hr>")
    end

    def bold_print(txt)
      tag("b") { txt }
    end

    def blankline()
      puts("<p>")
    end

    def break_to_newline
      puts("<br>")
    end

    def display_heading(text, level, indent)
      level = 4 if level > 4
      tag("h#{level}") { text }
      puts
    end
    
    ######################################################################

    def display_list(list)

      case list.type
      when SM::ListBase::BULLET 
        list_type = "ul"
        prefixer = proc { |ignored| "<li>" }

      when SM::ListBase::NUMBER,
      SM::ListBase::UPPERALPHA,
      SM::ListBase::LOWERALPHA
        list_type = "ol"
        prefixer = proc { |ignored| "<li>" }
        
      when SM::ListBase::LABELED
        list_type = "dl"
        prefixer = proc do |li|
          "<dt><b>" + escape(li.label) + "</b><dd>"
        end

      when SM::ListBase::NOTE
        list_type = "table"
        prefixer = proc do |li|
          %{<tr valign="top"><td>#{li.label.gsub(/ /, '&nbsp;')}</td><td>}
        end
      else
        fail "unknown list type"
      end

      print "<#{list_type}>"
      list.contents.each do |item|
        if item.kind_of? SM::Flow::LI
          prefix = prefixer.call(item)
          print prefix
          display_flow_item(item, prefix)
        else
          display_flow_item(item)
        end
      end
      print "</#{list_type}>"
    end

    def display_verbatim_flow_item(item, prefix=@indent)
        print("<pre>")
        puts item.body
        puts("</pre>")
    end

    private

    ATTR_MAP = {
      BOLD   => "b>",
      ITALIC => "i>",
      CODE   => "tt>"
    }

    def update_attributes(current, wanted)
      str = ""
      # first turn off unwanted ones
      off = current & ~wanted
      for quality in [ BOLD, ITALIC, CODE]
        if (off & quality) > 0
          str << "</" + ATTR_MAP[quality]
        end
      end

      # now turn on wanted
      for quality in [ BOLD, ITALIC, CODE]
        unless (wanted & quality).zero?
          str << "<" << ATTR_MAP[quality]
        end
      end
      print str
    end

    def tag(code)
        print("<#{code}>")
        print(yield)
        print("</#{code}>")
    end

    def escape(str)
      str.
          gsub(/&/n, '&amp;').
          gsub(/\"/n, '&quot;').
          gsub(/>/n, '&gt;').
          gsub(/</n, '&lt;')
    end

  end

  ##################################################
  
  # This formatter reduces extra lines for a simpler output.
  # It improves way output looks for tools like IRC bots.

  class SimpleFormatter < TextFormatter

    ######################################################################

    # No extra blank lines

    def blankline
    end

    ######################################################################

    # Display labels only, no lines

    def draw_line(label=nil)
      unless label.nil? then
        bold_print(label) 
        puts
      end
    end

    ######################################################################

    # Place heading level indicators inline with heading.

    def display_heading(text, level, indent)
      text = strip_attributes(text)
      case level
      when 1
        puts "= " + text.upcase
      when 2
        puts "-- " + text
      else
        print indent, text, "\n"
      end
    end

  end


  # Finally, fill in the list of known formatters

  class TextFormatter

    FORMATTERS = {
      "ansi"   => AnsiFormatter,
      "bs"     => OverstrikeFormatter,
      "html"   => HtmlFormatter,
      "plain"  => TextFormatter,
      "simple" => SimpleFormatter,
    }
      
    def TextFormatter.list
      FORMATTERS.keys.sort.join(", ")
    end

    def TextFormatter.for(name)
      FORMATTERS[name.downcase]
    end

  end

end


PK     Z\<*      rdoc/ri/ri_reader.rbnu [        require 'rdoc/ri/ri_descriptions'
require 'rdoc/ri/ri_writer'
require 'rdoc/markup/simple_markup/to_flow'

module RI
  class RiReader

    def initialize(ri_cache)
      @cache = ri_cache
    end

    def top_level_namespace
      [ @cache.toplevel ]
    end

    def lookup_namespace_in(target, namespaces)
      result = []
      for n in namespaces
        result.concat(n.contained_modules_matching(target))
      end
      result
    end

    def find_class_by_name(full_name)
      names = full_name.split(/::/)
      ns = @cache.toplevel
      for name in names
        ns = ns.contained_class_named(name)
        return nil if ns.nil?
      end
      get_class(ns)
    end

    def find_methods(name, is_class_method, namespaces)
      result = []
      namespaces.each do |ns|
        result.concat ns.methods_matching(name, is_class_method)
      end
      result
    end

    # return the MethodDescription for a given MethodEntry
    # by deserializing the YAML
    def get_method(method_entry)
      path = method_entry.path_name
      File.open(path) { |f| RI::Description.deserialize(f) }
    end

    # Return a class description
    def get_class(class_entry)
      result = nil
      for path in class_entry.path_names
        path = RiWriter.class_desc_path(path, class_entry)
        desc = File.open(path) {|f| RI::Description.deserialize(f) }
        if result
          result.merge_in(desc)
        else
          result = desc
        end
      end
      result
    end

    # return the names of all classes and modules
    def full_class_names
      res = []
      find_classes_in(res, @cache.toplevel)
    end

    # return a list of all classes, modules, and methods
    def all_names
      res = []
      find_names_in(res, @cache.toplevel)
    end

    # ----
    private
    # ----

    def find_classes_in(res, klass)
      classes = klass.classes_and_modules
      for c in classes
        res << c.full_name
        find_classes_in(res, c)
      end
      res
    end

    def find_names_in(res, klass)
      classes = klass.classes_and_modules
      for c in classes
        res << c.full_name
        res.concat c.all_method_names
        find_names_in(res, c)
      end
      res
    end

  end
end
PK     Z\sb  b    rdoc/ri/ri_util.rbnu [        ######################################################################

class RiError < Exception; end
#
# Break argument into its constituent class or module names, an
# optional method type, and a method name

class NameDescriptor

  attr_reader :class_names
  attr_reader :method_name

  # true and false have the obvious meaning. nil means we don't care
  attr_reader :is_class_method

  # arg may be
  # 1. a class or module name (optionally qualified with other class
  #    or module names (Kernel, File::Stat etc)
  # 2. a method name
  # 3. a method name qualified by a optionally fully qualified class
  #    or module name
  #
  # We're fairly casual about delimiters: folks can say Kernel::puts,
  # Kernel.puts, or Kernel\#puts for example. There's one exception:
  # if you say IO::read, we look for a class method, but if you
  # say IO.read, we look for an instance method

  def initialize(arg)
    @class_names = []
    separator = nil

    tokens = arg.split(/(\.|::|#)/)

    # Skip leading '::', '#' or '.', but remember it might
    # be a method name qualifier
    separator = tokens.shift if tokens[0] =~ /^(\.|::|#)/

    # Skip leading '::', but remember we potentially have an inst

    # leading stuff must be class names
    
    while tokens[0] =~ /^[A-Z]/
      @class_names << tokens.shift
      unless tokens.empty?
        separator = tokens.shift
        break unless separator == "::"
      end
    end
    
    # Now must have a single token, the method name, or an empty
    # array
    unless tokens.empty?
      @method_name = tokens.shift
      # We may now have a trailing !, ?, or = to roll into
      # the method name
      if !tokens.empty? && tokens[0] =~ /^[!?=]$/
        @method_name << tokens.shift
      end

      if @method_name =~ /::|\.|#/ or !tokens.empty?
        raise RiError.new("Bad argument: #{arg}") 
      end
      if separator && separator != '.'
        @is_class_method = separator == "::"
      end
    end
  end

  # Return the full class name (with '::' between the components)
  # or "" if there's no class name

  def full_class_name
    @class_names.join("::")
  end
end
PK     Z\`\l      rdoc/ri/ri_display.rbnu [        require 'rdoc/ri/ri_util'
require 'rdoc/ri/ri_formatter'
require 'rdoc/ri/ri_options'


# This is a kind of 'flag' module. If you want to write your
# own 'ri' display module (perhaps because you'r writing
# an IDE or somesuch beast), you simply write a class
# which implements the various 'display' methods in 'DefaultDisplay',
# and include the 'RiDisplay' module in that class. 
#
# To access your class from the command line, you can do
#
#    ruby -r <your source file>  ../ri ....
#
# If folks _really_ want to do this from the command line,
# I'll build an option in

module RiDisplay
  @@display_class = nil

  def RiDisplay.append_features(display_class)
    @@display_class = display_class
  end

  def RiDisplay.new(*args)
    @@display_class.new(*args)
  end
end

######################################################################
#
# A paging display module. Uses the ri_formatter class to do the
# actual presentation
#

class  DefaultDisplay

  include RiDisplay

  def initialize(options)
    @options = options
    @formatter = @options.formatter.new(@options, "     ")
  end    
  
  
  ######################################################################
  
  def display_usage
    page do
      RI::Options::OptionList.usage(short_form=true)
    end
  end


  ######################################################################
  
  def display_method_info(method)
    page do
      @formatter.draw_line(method.full_name)
      display_params(method)
      @formatter.draw_line
      display_flow(method.comment)
      if method.aliases && !method.aliases.empty?
        @formatter.blankline
        aka = "(also known as "
        aka << method.aliases.map {|a| a.name }.join(", ") 
        aka << ")"
        @formatter.wrap(aka)
      end
    end
  end
  
  ######################################################################
  
  def display_class_info(klass, ri_reader)
    page do 
      superclass = klass.superclass_string
      
      if superclass
        superclass = " < " + superclass
      else
        superclass = ""
      end
      
      @formatter.draw_line(klass.display_name + ": " +
                           klass.full_name + superclass)
      
      display_flow(klass.comment)
      @formatter.draw_line 
    
      unless klass.includes.empty?
        @formatter.blankline
        @formatter.display_heading("Includes:", 2, "")
        incs = []
        klass.includes.each do |inc|
          inc_desc = ri_reader.find_class_by_name(inc.name)
          if inc_desc
            str = inc.name + "("
            str << inc_desc.instance_methods.map{|m| m.name}.join(", ")
            str << ")"
            incs << str
          else
            incs << inc.name
          end
      end
        @formatter.wrap(incs.sort.join(', '))
      end
      
      unless klass.constants.empty?
        @formatter.blankline
        @formatter.display_heading("Constants:", 2, "")
        len = 0
        klass.constants.each { |c| len = c.name.length if c.name.length > len }
        len += 2
        klass.constants.each do |c|
          @formatter.wrap(c.value, 
                          @formatter.indent+((c.name+":").ljust(len)))
        end 
      end
      
      unless klass.class_methods.empty?
        @formatter.blankline
        @formatter.display_heading("Class methods:", 2, "")
        @formatter.wrap(klass.class_methods.map{|m| m.name}.sort.join(', '))
      end
      
      unless klass.instance_methods.empty?
        @formatter.blankline
        @formatter.display_heading("Instance methods:", 2, "")
        @formatter.wrap(klass.instance_methods.map{|m| m.name}.sort.join(', '))
      end
      
      unless klass.attributes.empty?
        @formatter.blankline
        @formatter.wrap("Attributes:", "")
        @formatter.wrap(klass.attributes.map{|a| a.name}.sort.join(', '))
      end
    end
  end
  
  ######################################################################
  
  # Display a list of method names
  
  def display_method_list(methods)
    page do
      puts "More than one method matched your request. You can refine"
      puts "your search by asking for information on one of:\n\n"
      @formatter.wrap(methods.map {|m| m.full_name} .join(", "))
    end
  end
  
  ######################################################################
  
  def display_class_list(namespaces)
    page do
      puts "More than one class or module matched your request. You can refine"
      puts "your search by asking for information on one of:\n\n"
      @formatter.wrap(namespaces.map {|m| m.full_name}.join(", "))
    end
  end
  
  ######################################################################

  def list_known_classes(classes)
    if classes.empty?
      warn_no_database
    else
      page do 
        @formatter.draw_line("Known classes and modules")
        @formatter.blankline
        @formatter.wrap(classes.sort.join(", "))
      end
    end
  end

  ######################################################################

  def list_known_names(names)
    if names.empty?
      warn_no_database
    else
      page do 
        names.each {|n| @formatter.raw_print_line(n)}
      end
    end
  end

  ######################################################################

  private

  ######################################################################

  def page
    return yield unless pager = setup_pager
    begin
      save_stdout = STDOUT.clone
      STDOUT.reopen(pager)
      yield
    ensure
      STDOUT.reopen(save_stdout)
      save_stdout.close
      pager.close
    end
  end

  ######################################################################

  def setup_pager
    unless @options.use_stdout
      for pager in [ ENV['PAGER'], "less", "more", 'pager' ].compact.uniq
        return IO.popen(pager, "w") rescue nil
      end
      @options.use_stdout = true
      nil
    end
  end

  ######################################################################
  
  def display_params(method)

    params = method.params

    if params[0,1] == "("
      if method.is_singleton
        params = method.full_name + params
      else
        params = method.name + params
      end
    end
    params.split(/\n/).each do |p|
      @formatter.wrap(p) 
      @formatter.break_to_newline
    end
  end
  ######################################################################
  
  def display_flow(flow)
    if !flow || flow.empty?
      @formatter.wrap("(no description...)")
    else
      @formatter.display_flow(flow)
    end
  end

  ######################################################################
  
  def warn_no_database
    puts "Before using ri, you need to generate documentation"
    puts "using 'rdoc' with the --ri option"
  end
end  # class RiDisplay
PK     Z\|Qi"  i"    rdoc/ri/ri_options.rbnu [        # We handle the parsing of options, and subsequently as a singleton
# object to be queried for option values

module RI

  require 'rdoc/ri/ri_paths'
  require 'rdoc/ri/ri_display'

  VERSION_STRING = "ri v1.0.1 - 20041108"

  class Options
    
    require 'singleton'
    require 'getoptlong'
    
    include Singleton

    # No not use a pager. Writable, because ri sets it if it
    # can't find a pager
    attr_accessor :use_stdout

    # should we just display a class list and exit
    attr_reader :list_classes

    # should we display a list of all names
    attr_reader :list_names

    # The width of the output line
    attr_reader :width

    # the formatting we apply to the output
    attr_reader :formatter

    # the directory we search for original documentation
    attr_reader :doc_dir

    module OptionList
      
      OPTION_LIST = [
        [ "--help",          "-h",   nil,
          "you're looking at it" ],

        [ "--classes",      "-c",   nil,
          "Display the names of classes and modules we\n" +
          "know about"],

        [ "--doc-dir",      "-d",   "<dirname>",
          "A directory to search for documentation. If not\n" +
          "specified, we search the standard rdoc/ri directories.\n" +
          "May be repeated."],

        [ "--system",       nil,    nil,
          "Include documentation from Ruby's standard library:\n  " +
          RI::Paths::SYSDIR ],

        [ "--site",         nil,    nil,
          "Include documentation from libraries installed in site_lib:\n  " +
          RI::Paths::SITEDIR ],

        [ "--home",         nil,    nil,
          "Include documentation stored in ~/.rdoc:\n  " +
          (RI::Paths::HOMEDIR || "No ~/.rdoc found") ],

        [ "--gems",         nil,    nil,
          "Include documentation from RubyGems:\n" +
          (RI::Paths::GEMDIRS ?
           Gem.path.map { |dir| "  #{dir}/doc/*/ri" }.join("\n") :
           "No Rubygems ri found.") ],

        [ "--format",       "-f",   "<name>",
          "Format to use when displaying output:\n" +
          "   " + RI::TextFormatter.list + "\n" +
          "Use 'bs' (backspace) with most pager programs.\n" +
          "To use ANSI, either also use the -T option, or\n" +
          "tell your pager to allow control characters\n" +
          "(for example using the -R option to less)"],

        [ "--list-names",    "-l",   nil,
          "List all the names known to RDoc, one per line"
        ],

        [ "--no-pager",      "-T",   nil,
          "Send output directly to stdout." 
        ],

        [ "--width",         "-w",   "output width",
        "Set the width of the output" ],

        [ "--version",       "-v",   nil,
         "Display the version of ri"
        ],

      ]

      def OptionList.options
        OPTION_LIST.map do |long, short, arg,|
          option = []
          option << long
          option << short unless short.nil?
          option << (arg ? GetoptLong::REQUIRED_ARGUMENT :
                           GetoptLong::NO_ARGUMENT)
          option
        end
      end


      def OptionList.strip_output(text)
        text =~ /^\s+/
        leading_spaces = $&
        text.gsub!(/^#{leading_spaces}/, '')
        $stdout.puts text
      end
      
      
      # Show an error and exit
      
      def OptionList.error(msg)
        $stderr.puts
        $stderr.puts msg
        name = File.basename $PROGRAM_NAME
        $stderr.puts "\nFor help on options, try '#{name} --help'\n\n"
        exit 1
      end
      
      # Show usage and exit
      
      def OptionList.usage(short_form=false)
        
        puts
        puts(RI::VERSION_STRING)
        puts
        
        name = File.basename($0)

        directories = [
          RI::Paths::SYSDIR,
          RI::Paths::SITEDIR,
          RI::Paths::HOMEDIR
        ]

        if RI::Paths::GEMDIRS then
          Gem.path.each do |dir|
            directories << "#{dir}/doc/*/ri"
          end
        end

        directories = directories.join("\n    ")

        OptionList.strip_output(<<-EOT)
          Usage:

            #{name} [options]  [names...]

          Display information on Ruby classes, modules, and methods.
          Give the names of classes or methods to see their documentation.
          Partial names may be given: if the names match more than
          one entity, a list will be shown, otherwise details on
          that entity will be displayed.

          Nested classes and modules can be specified using the normal
          Name::Name notation, and instance methods can be distinguished
          from class methods using "." (or "#") instead of "::".

          For example:

              #{name}  File
              #{name}  File.new
              #{name}  F.n
              #{name}  zip

          Note that shell quoting may be required for method names
          containing punctuation:

              #{name} 'Array.[]'
              #{name} compact\\!

          By default ri searches for documentation in the following
          directories:

              #{directories}

          Specifying the --system, --site, --home, --gems or --doc-dir
          options will limit ri to searching only the specified
          directories.

        EOT

        if short_form
          puts "For help on options, type '#{name} -h'"
          puts "For a list of classes I know about, type '#{name} -c'"
        else
          puts "Options:\n\n"
          OPTION_LIST.each do|long, short, arg, desc|
            opt = ''
            opt << (short ? sprintf("%15s", "#{long}, #{short}") :
                            sprintf("%15s", long))
            if arg
              opt << " " << arg
            end
            print opt
            desc = desc.split("\n")
            if opt.size < 17
              print " "*(18-opt.size)
              puts desc.shift
            else
              puts
            end
            desc.each do |line|
              puts(" "*18 + line)
            end
            puts
          end
          puts "Options may also be passed in the 'RI' environment variable"
          exit 0
        end
      end
    end

    # Show the version and exit
    def show_version
      puts VERSION_STRING
      exit(0)
    end

    def initialize
      @use_stdout   = !STDOUT.tty?
      @width        = 72
      @formatter    = RI::TextFormatter.for("plain") 
      @list_classes = false
      @list_names   = false

      # By default all paths are used.  If any of these are true, only those
      # directories are used.
      @use_system = false
      @use_site = false
      @use_home = false
      @use_gems = false
      @doc_dirs = []
    end

    # Parse command line options.

    def parse(args)
    
      old_argv = ARGV.dup

      ARGV.replace(args)

      begin

        go = GetoptLong.new(*OptionList.options)
        go.quiet = true

        go.each do |opt, arg|
          case opt
          when "--help"       then OptionList.usage
          when "--version"    then show_version
          when "--list-names" then @list_names = true
          when "--no-pager"   then @use_stdout = true
          when "--classes"    then @list_classes = true

          when "--system"     then @use_system = true
          when "--site"       then @use_site = true
          when "--home"       then @use_home = true
          when "--gems"       then @use_gems = true

          when "--doc-dir"
            if File.directory?(arg)
              @doc_dirs << arg
            else
              $stderr.puts "Invalid directory: #{arg}"
              exit 1
            end

          when "--format"
            @formatter = RI::TextFormatter.for(arg)
            unless @formatter
              $stderr.print "Invalid formatter (should be one of "
              $stderr.puts RI::TextFormatter.list + ")"
              exit 1
            end
          when "--width"
            begin
              @width = Integer(arg)
            rescue 
              $stderr.puts "Invalid width: '#{arg}'"
              exit 1
            end
          end
        end

      rescue GetoptLong::InvalidOption, GetoptLong::MissingArgument => error
        OptionList.error(error.message)

      end
    end

    # Return the selected documentation directories.

    def path
      RI::Paths.path(@use_system, @use_site, @use_home, @use_gems, *@doc_dirs)
    end

    def raw_path
      RI::Paths.raw_path(@use_system, @use_site, @use_home, @use_gems,
                         *@doc_dirs)
    end

    # Return an instance of the displayer (the thing that actually writes
    # the information). This allows us to load in new displayer classes
    # at runtime (for example to help with IDE integration)
    
    def displayer
      ::RiDisplay.new(self)
    end
  end

end

PK     Z\98  8    rdoc/ri/ri_cache.rbnu [        module RI

  class ClassEntry

    attr_reader :name
    attr_reader :path_names
    
    def initialize(path_name, name, in_class)
      @path_names = [ path_name ]
      @name = name
      @in_class = in_class
      @class_methods    = []
      @instance_methods = []
      @inferior_classes = []
    end

    # We found this class in more tha one place, so add
    # in the name from there.
    def add_path(path)
      @path_names << path
    end

    # read in our methods and any classes
    # and modules in our namespace. Methods are
    # stored in files called name-c|i.yaml,
    # where the 'name' portion is the external
    # form of the method name and the c|i is a class|instance
    # flag

    def load_from(dir)
      Dir.foreach(dir) do |name|
        next if name =~ /^\./

        # convert from external to internal form, and
        # extract the instance/class flag

        if name =~ /^(.*?)-(c|i).yaml$/
          external_name = $1
          is_class_method = $2 == "c"
          internal_name = RiWriter.external_to_internal(external_name)
          list = is_class_method ? @class_methods : @instance_methods
          path = File.join(dir, name)
          list << MethodEntry.new(path, internal_name, is_class_method, self)
        else
          full_name = File.join(dir, name)
          if File.directory?(full_name)
            inf_class = @inferior_classes.find {|c| c.name == name }
            if inf_class
              inf_class.add_path(full_name)
            else
              inf_class = ClassEntry.new(full_name, name, self)
              @inferior_classes << inf_class
            end
            inf_class.load_from(full_name)
          end
        end
      end
    end

    # Return a list of any classes or modules that we contain
    # that match a given string

    def contained_modules_matching(name)
      @inferior_classes.find_all {|c| c.name[name]}
    end

    def classes_and_modules
      @inferior_classes
    end

    # Return an exact match to a particular name
    def contained_class_named(name)
      @inferior_classes.find {|c| c.name == name}
    end

    # return the list of local methods matching name
    # We're split into two because we need distinct behavior
    # when called from the _toplevel_
    def methods_matching(name, is_class_method)
      local_methods_matching(name, is_class_method)
    end

    # Find methods matching 'name' in ourselves and in
    # any classes we contain
    def recursively_find_methods_matching(name, is_class_method)
      res = local_methods_matching(name, is_class_method)
      @inferior_classes.each do |c|
        res.concat(c.recursively_find_methods_matching(name, is_class_method))
      end
      res
    end


    # Return our full name
    def full_name
      res = @in_class.full_name
      res << "::" unless res.empty?
      res << @name
    end

    # Return a list of all out method names
    def all_method_names
      res = @class_methods.map {|m| m.full_name }
      @instance_methods.each {|m| res << m.full_name}
      res
    end

    private

    # Return a list of all our methods matching a given string.
    # Is +is_class_methods+ if 'nil', we don't care if the method
    # is a class method or not, otherwise we only return
    # those methods that match
    def local_methods_matching(name, is_class_method)

      list = case is_class_method
             when nil then  @class_methods + @instance_methods
             when true then @class_methods
             when false then @instance_methods
             else fail "Unknown is_class_method: #{is_class_method.inspect}"
             end

      list.find_all {|m| m.name;  m.name[name]}
    end
  end

  # A TopLevelEntry is like a class entry, but when asked to search
  # for methods searches all classes, not just itself

  class TopLevelEntry < ClassEntry
    def methods_matching(name, is_class_method)
      res = recursively_find_methods_matching(name, is_class_method)
    end

    def full_name
      ""
    end

    def module_named(name)
      
    end

  end

  class MethodEntry
    attr_reader :name
    attr_reader :path_name

    def initialize(path_name, name, is_class_method, in_class)
      @path_name = path_name
      @name = name
      @is_class_method = is_class_method
      @in_class = in_class
    end

    def full_name
      res = @in_class.full_name
      unless res.empty?
        if @is_class_method
          res << "::"
        else
          res << "#"
        end
      end
      res << @name
    end
  end

  # We represent everything know about all 'ri' files
  # accessible to this program

  class RiCache

    attr_reader :toplevel

    def initialize(dirs)
      # At the top level we have a dummy module holding the
      # overall namespace
      @toplevel = TopLevelEntry.new('', '::', nil)

      dirs.each do |dir|
        @toplevel.load_from(dir)
      end
    end

  end
end
PK     Z\/      rdoc/ri/ri_writer.rbnu [        require 'fileutils'

module RI
  class RiWriter

    def RiWriter.class_desc_path(dir, class_desc)
      File.join(dir, "cdesc-" + class_desc.name + ".yaml")
    end

    
    # Convert a name from internal form (containing punctuation)
    # to an external form (where punctuation is replaced
    # by %xx)

    def RiWriter.internal_to_external(name)
      name.gsub(/\W/) { sprintf("%%%02x", $&[0]) }
    end

    # And the reverse operation
    def RiWriter.external_to_internal(name)
      name.gsub(/%([0-9a-f]{2,2})/) { $1.to_i(16).chr }
    end

    def initialize(base_dir)
      @base_dir = base_dir
    end

    def remove_class(class_desc)
      FileUtils.rm_rf(path_to_dir(class_desc.full_name))
    end

    def add_class(class_desc)
      dir = path_to_dir(class_desc.full_name)
      FileUtils.mkdir_p(dir)
      class_file_name = RiWriter.class_desc_path(dir, class_desc)
      File.open(class_file_name, "w") do |f|
        f.write(class_desc.serialize)
      end
    end

    def add_method(class_desc, method_desc)
      dir = path_to_dir(class_desc.full_name)
      file_name = RiWriter.internal_to_external(method_desc.name)
      meth_file_name = File.join(dir, file_name)
      if method_desc.is_singleton
        meth_file_name += "-c.yaml"
      else
        meth_file_name += "-i.yaml"
      end

      File.open(meth_file_name, "w") do |f|
        f.write(method_desc.serialize)
      end
    end

    private

    def path_to_dir(class_name)
      File.join(@base_dir, *class_name.split('::'))
    end
  end
end
PK     Z\      rdoc/ri/ri_descriptions.rbnu [        require 'yaml'
require 'rdoc/markup/simple_markup/fragments'

# Descriptions are created by RDoc (in ri_generator) and
# written out in serialized form into the documentation
# tree. ri then reads these to generate the documentation

module RI
  class NamedThing
    attr_reader :name
    def initialize(name)
      @name = name
    end
    def <=>(other)
      @name <=> other.name
    end

    def hash
      @name.hash
    end

    def eql?(other)
      @name.eql?(other)
    end
  end

#  Alias          = Struct.new(:old_name, :new_name)

  class AliasName < NamedThing
  end

  class Attribute < NamedThing
    attr_reader :rw, :comment
    def initialize(name, rw, comment)
      super(name)
      @rw = rw
      @comment = comment
    end
  end

  class Constant < NamedThing
    attr_reader :value, :comment
    def initialize(name, value, comment)
      super(name)
      @value = value
      @comment = comment
    end
  end

  class IncludedModule < NamedThing
  end


  class MethodSummary < NamedThing
    def initialize(name="")
      super
    end
  end



  class Description
    attr_accessor :name
    attr_accessor :full_name
    attr_accessor :comment

    def serialize
      self.to_yaml
    end

    def Description.deserialize(from)
      YAML.load(from)
    end

    def <=>(other)
      @name <=> other.name
    end
  end
  
  class ModuleDescription < Description
    
    attr_accessor :class_methods
    attr_accessor :instance_methods
    attr_accessor :attributes
    attr_accessor :constants
    attr_accessor :includes

    # merge in another class desscription into this one
    def merge_in(old)
      merge(@class_methods, old.class_methods)
      merge(@instance_methods, old.instance_methods)
      merge(@attributes, old.attributes)
      merge(@constants, old.constants)
      merge(@includes, old.includes)
      if @comment.nil? || @comment.empty?
        @comment = old.comment
      else
        unless old.comment.nil? or old.comment.empty? then
          @comment << SM::Flow::RULE.new
          @comment.concat old.comment
        end
      end
    end

    def display_name
      "Module"
    end

    # the 'ClassDescription' subclass overrides this
    # to format up the name of a parent
    def superclass_string
      nil
    end

    private

    def merge(into, from)
      names = {}
      into.each {|i| names[i.name] = i }
      from.each {|i| names[i.name] = i }
      into.replace(names.keys.sort.map {|n| names[n]})
    end
  end
  
  class ClassDescription < ModuleDescription
    attr_accessor :superclass

    def display_name
      "Class"
    end

    def superclass_string
      if @superclass && @superclass != "Object"
        @superclass
      else
        nil
      end
    end
  end


  class MethodDescription < Description
    
    attr_accessor :is_class_method
    attr_accessor :visibility
    attr_accessor :block_params
    attr_accessor :is_singleton
    attr_accessor :aliases
    attr_accessor :is_alias_for
    attr_accessor :params

  end
  
end
PK     Z\O7      rdoc/ri/ri_driver.rbnu [        require 'rdoc/ri/ri_paths'
require 'rdoc/usage'
require 'rdoc/ri/ri_cache'
require 'rdoc/ri/ri_util'
require 'rdoc/ri/ri_reader'
require 'rdoc/ri/ri_formatter'
require 'rdoc/ri/ri_options'


######################################################################

class  RiDriver

  def initialize
    @options = RI::Options.instance

    args = ARGV
    if ENV["RI"]
      args = ENV["RI"].split.concat(ARGV)
    end

    @options.parse(args)

    path = @options.path
    report_missing_documentation @options.raw_path if path.empty?

    @ri_reader = RI::RiReader.new(RI::RiCache.new(path))
    @display   = @options.displayer
  end
  
  # Couldn't find documentation in +path+, so tell the user what to do

  def report_missing_documentation(path)
    STDERR.puts "No ri documentation found in:"
    path.each do |d|
      STDERR.puts "     #{d}"
    end
    STDERR.puts "\nWas rdoc run to create documentation?\n\n"
    RDoc::usage("Installing Documentation")
  end
  
  ######################################################################
  
  # If the list of matching methods contains exactly one entry, or
  # if it contains an entry that exactly matches the requested method,
  # then display that entry, otherwise display the list of
  # matching method names
  
  def report_method_stuff(requested_method_name, methods)
    if methods.size == 1
      method = @ri_reader.get_method(methods[0])
      @display.display_method_info(method)
    else
      entries = methods.find_all {|m| m.name == requested_method_name}
      if entries.size == 1
        method = @ri_reader.get_method(entries[0])
        @display.display_method_info(method)
      else
        @display.display_method_list(methods)
      end
    end
  end
  
  ######################################################################
  
  def report_class_stuff(namespaces)
    if namespaces.size == 1
      klass = @ri_reader.get_class(namespaces[0])
      @display.display_class_info(klass, @ri_reader)
    else 
#      entries = namespaces.find_all {|m| m.full_name == requested_class_name}
#      if entries.size == 1
#        klass = @ri_reader.get_class(entries[0])
#        @display.display_class_info(klass, @ri_reader)
#      else
        @display.display_class_list(namespaces)
#      end
    end
  end
  
  ######################################################################
  
  
  def get_info_for(arg)
    desc = NameDescriptor.new(arg)

    namespaces = @ri_reader.top_level_namespace
    
    for class_name in desc.class_names
      namespaces = @ri_reader.lookup_namespace_in(class_name, namespaces)
      if namespaces.empty?
        raise RiError.new("Nothing known about #{arg}")
      end
    end

    # at this point, if we have multiple possible namespaces, but one
    # is an exact match for our requested class, prune down to just it

    full_class_name = desc.full_class_name
    entries = namespaces.find_all {|m| m.full_name == full_class_name}
    namespaces = entries if entries.size == 1

    if desc.method_name.nil?
      report_class_stuff(namespaces)
    else
      methods = @ri_reader.find_methods(desc.method_name, 
                                        desc.is_class_method,
                                        namespaces)

      if methods.empty?
        raise RiError.new("Nothing known about #{arg}")
      else
        report_method_stuff(desc.method_name, methods)
      end
    end
  end

  ######################################################################

  def process_args
    if @options.list_classes
      classes = @ri_reader.full_class_names
      @display.list_known_classes(classes)
    elsif @options.list_names
      names = @ri_reader.all_names
      @display.list_known_names(names)
    else
      if ARGV.size.zero?
        @display.display_usage
      else
        begin
          ARGV.each do |arg|
            get_info_for(arg)
          end
        rescue RiError => e
          STDERR.puts(e.message)
          exit(1)
        end
      end
    end
  end

end  # class RiDriver
PK     Z\>ꞗ      rdoc/ri/ri_paths.rbnu [        module RI

  # Encapsulate all the strangeness to do with finding out
  # where to find RDoc files
  #
  # We basically deal with three directories:
  #
  # 1. The 'system' documentation directory, which holds
  #    the documentation distributed with Ruby, and which
  #    is managed by the Ruby install process
  # 2. The 'site' directory, which contains site-wide
  #    documentation added locally.
  # 3. The 'user' documentation directory, stored under the
  #    user's own home directory.
  #
  # There's contention about all this, but for now:
  #
  # system:: $datadir/ri/<ver>/system/...
  # site::   $datadir/ri/<ver>/site/...
  # user::   ~/.rdoc

  module Paths

    #:stopdoc:
    require 'rbconfig'
    
    DOC_DIR  = "doc/rdoc"

    version = Config::CONFIG['ruby_version']

    base    = File.join(Config::CONFIG['datadir'], "ri", version)
    SYSDIR  = File.join(base, "system")
    SITEDIR = File.join(base, "site")
    homedir = ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']

    if homedir
      HOMEDIR = File.join(homedir, ".rdoc")
    else
      HOMEDIR = nil
    end

    # This is the search path for 'ri'
    PATH = [ SYSDIR, SITEDIR, HOMEDIR ].find_all {|p| p && File.directory?(p)}

    begin
      require 'rubygems'

      # HACK dup'd from Gem.latest_partials and friends
      all_paths = []

      all_paths = Gem.path.map do |dir|
        Dir[File.join(dir, 'doc', '*', 'ri')]
      end.flatten

      ri_paths = {}

      all_paths.each do |dir|
        base = File.basename File.dirname(dir)
        if base =~ /(.*)-((\d+\.)*\d+)/ then
          name, version = $1, $2
          ver = Gem::Version.new version
          if ri_paths[name].nil? or ver > ri_paths[name][0] then
            ri_paths[name] = [ver, dir]
          end
        end
      end

      GEMDIRS = ri_paths.map { |k,v| v.last }.sort
      GEMDIRS.each { |dir| RI::Paths::PATH << dir }
    rescue LoadError
      GEMDIRS = nil
    end

    # Returns the selected documentation directories as an Array, or PATH if no
    # overriding directories were given.

    def self.path(use_system, use_site, use_home, use_gems, *extra_dirs)
      path = raw_path(use_system, use_site, use_home, use_gems, *extra_dirs)
      return path.select { |directory| File.directory? directory }
    end

    # Returns the selected documentation directories including nonexistent
    # directories.  Used to print out what paths were searched if no ri was
    # found.

    def self.raw_path(use_system, use_site, use_home, use_gems, *extra_dirs)
      return PATH unless use_system or use_site or use_home or use_gems or
                         not extra_dirs.empty?

      path = []
      path << extra_dirs unless extra_dirs.empty?
      path << RI::Paths::SYSDIR if use_system
      path << RI::Paths::SITEDIR if use_site
      path << RI::Paths::HOMEDIR if use_home
      path << RI::Paths::GEMDIRS if use_gems

      return path.flatten.compact
    end

  end
end
PK     Z\@K{  {    rdoc/dot/dot.rbnu [        module DOT

    # these glogal vars are used to make nice graph source
    $tab = '    '
    $tab2 = $tab * 2

    # if we don't like 4 spaces, we can change it any time
    def change_tab( t )
        $tab = t
        $tab2 = t * 2
    end

    # options for node declaration
    NODE_OPTS = [
        'bgcolor',
        'color',
        'fontcolor',
        'fontname',
        'fontsize',
        'height',
        'width',
        'label',
        'layer',
        'rank',
        'shape',
        'shapefile',
        'style',
        'URL',
    ]

    # options for edge declaration
    EDGE_OPTS = [
        'color',
        'decorate',
        'dir',
        'fontcolor',
        'fontname',
        'fontsize',
        'id',
        'label',
        'layer',
        'lhead',
        'ltail',
        'minlen',
        'style',
        'weight'
    ]

    # options for graph declaration
    GRAPH_OPTS = [
        'bgcolor',
        'center',
        'clusterrank',
        'color',
        'compound',
        'concentrate',
        'fillcolor',
        'fontcolor',
        'fontname',
        'fontsize',
        'label',
        'layerseq',
        'margin',
        'mclimit',
        'nodesep',
        'nslimit',
        'ordering',
        'orientation',
        'page',
        'rank',
        'rankdir',
        'ranksep',
        'ratio',
        'size',
        'style',
        'URL'
    ]

    # a root class for any element in dot notation
    class DOTSimpleElement
        attr_accessor :name

        def initialize( params = {} )
            @label = params['name'] ? params['name'] : ''
        end

        def to_s
            @name
        end
    end

    # an element that has options ( node, edge or graph )
    class DOTElement < DOTSimpleElement
        #attr_reader :parent
        attr_accessor :name, :options

        def initialize( params = {}, option_list = [] )
            super( params )
            @name = params['name'] ? params['name'] : nil
            @parent = params['parent'] ? params['parent'] : nil
            @options = {}
            option_list.each{ |i|
                @options[i] = params[i] if params[i]
            }
            @options['label'] ||= @name if @name != 'node'
        end

        def each_option
            @options.each{ |i| yield i }
        end

        def each_option_pair
            @options.each_pair{ |key, val| yield key, val }
        end

        #def parent=( thing )
        #    @parent.delete( self ) if defined?( @parent ) and @parent
        #    @parent = thing
        #end
    end


    # this is used when we build nodes that have shape=record
    # ports don't have options :)
    class DOTPort < DOTSimpleElement
        attr_accessor :label

        def initialize( params = {} )
            super( params )
            @name = params['label'] ? params['label'] : ''
        end
        def to_s
            ( @name && @name != "" ? "<#{@name}>" : "" ) + "#{@label}"
        end
    end

    # node element
    class DOTNode < DOTElement

        def initialize( params = {}, option_list = NODE_OPTS )
            super( params, option_list )
            @ports = params['ports'] ? params['ports'] : []
        end

        def each_port
            @ports.each{ |i| yield i }
        end

        def << ( thing )
            @ports << thing
        end

        def push ( thing )
            @ports.push( thing )
        end

        def pop
            @ports.pop
        end

        def to_s( t = '' )

            label = @options['shape'] != 'record' && @ports.length == 0 ?
                @options['label'] ?
                    t + $tab + "label = \"#{@options['label']}\"\n" :
                    '' :
                t + $tab + 'label = "' + " \\\n" +
                t + $tab2 + "#{@options['label']}| \\\n" +
                @ports.collect{ |i|
                    t + $tab2 + i.to_s
                }.join( "| \\\n" ) + " \\\n" +
                t + $tab + '"' + "\n"

            t + "#{@name} [\n" +
            @options.to_a.collect{ |i|
                i[1] && i[0] != 'label' ?
                    t + $tab + "#{i[0]} = #{i[1]}" : nil
            }.compact.join( ",\n" ) + ( label != '' ? ",\n" : "\n" ) +
            label +
            t + "]\n"
        end
    end

    # subgraph element is the same to graph, but has another header in dot
    # notation
    class DOTSubgraph < DOTElement

        def initialize( params = {}, option_list = GRAPH_OPTS )
            super( params, option_list )
            @nodes = params['nodes'] ? params['nodes'] : []
            @dot_string = 'subgraph'
        end

        def each_node
            @nodes.each{ |i| yield i }
        end

        def << ( thing )
            @nodes << thing
        end

        def push( thing )
            @nodes.push( thing )
        end

        def pop
            @nodes.pop
        end

        def to_s( t = '' )
          hdr = t + "#{@dot_string} #{@name} {\n"

          options = @options.to_a.collect{ |name, val|
            val && name != 'label' ?
            t + $tab + "#{name} = #{val}" :
              name ? t + $tab + "#{name} = \"#{val}\"" : nil
          }.compact.join( "\n" ) + "\n"

          nodes = @nodes.collect{ |i|
            i.to_s( t + $tab )
          }.join( "\n" ) + "\n"
          hdr + options + nodes + t + "}\n"
        end
    end

    # this is graph
    class DOTDigraph < DOTSubgraph
        def initialize( params = {}, option_list = GRAPH_OPTS )
            super( params, option_list )
            @dot_string = 'digraph'
        end
    end

    # this is edge
    class DOTEdge < DOTElement
        attr_accessor :from, :to
        def initialize( params = {}, option_list = EDGE_OPTS )
            super( params, option_list )
            @from = params['from'] ? params['from'] : nil
            @to = params['to'] ? params['to'] : nil
        end

        def to_s( t = '' )
            t + "#{@from} -> #{to} [\n" +
            @options.to_a.collect{ |i|
                i[1] && i[0] != 'label' ?
                    t + $tab + "#{i[0]} = #{i[1]}" :
                    i[1] ? t + $tab + "#{i[0]} = \"#{i[1]}\"" : nil
            }.compact.join( "\n" ) + "\n" + t + "]\n"
        end
    end
end



PK     Z\M)Mę  ę  !  rdoc/generators/html_generator.rbnu [        # We're responsible for generating all the HTML files
# from the object tree defined in code_objects.rb. We
# generate:
#
# [files]   an html file for each input file given. These
#           input files appear as objects of class
#           TopLevel
#
# [classes] an html file for each class or module encountered.
#           These classes are not grouped by file: if a file
#           contains four classes, we'll generate an html
#           file for the file itself, and four html files 
#           for the individual classes. 
#
# [indices] we generate three indices for files, classes,
#           and methods. These are displayed in a browser
#           like window with three index panes across the
#           top and the selected description below
#
# Method descriptions appear in whatever entity (file, class,
# or module) that contains them.
#
# We generate files in a structure below a specified subdirectory,
# normally +doc+.
#
#  opdir
#     |
#     |___ files
#     |       |__  per file summaries
#     |
#     |___ classes
#             |__ per class/module descriptions
#
# HTML is generated using the Template class.
#

require 'ftools'

require 'rdoc/options'
require 'rdoc/template'
require 'rdoc/markup/simple_markup'
require 'rdoc/markup/simple_markup/to_html'
require 'cgi'

module Generators

  # Name of sub-direcories that hold file and class/module descriptions

  FILE_DIR  = "files"
  CLASS_DIR = "classes"
  CSS_NAME  = "rdoc-style.css"
  

  ##
  # Build a hash of all items that can be cross-referenced.
  # This is used when we output required and included names: 
  # if the names appear in this hash, we can generate
  # an html cross reference to the appropriate description.
  # We also use this when parsing comment blocks: any decorated 
  # words matching an entry in this list are hyperlinked.

  class AllReferences
    @@refs = {}
    
    def AllReferences::reset
      @@refs = {}
    end

    def AllReferences.add(name, html_class)
      @@refs[name] = html_class
    end

    def AllReferences.[](name)
      @@refs[name]
    end

    def AllReferences.keys
      @@refs.keys
    end
  end


  ##
  # Subclass of the SM::ToHtml class that supports looking
  # up words in the AllReferences list. Those that are
  # found (like AllReferences in this comment) will
  # be hyperlinked

  class HyperlinkHtml < SM::ToHtml
    # We need to record the html path of our caller so we can generate
    # correct relative paths for any hyperlinks that we find
    def initialize(from_path, context)
      super()
      @from_path = from_path

      @parent_name = context.parent_name
      @parent_name += "::" if @parent_name
      @context = context
    end

    # We're invoked when any text matches the CROSSREF pattern
    # (defined in MarkUp). If we fine the corresponding reference,
    # generate a hyperlink. If the name we're looking for contains
    # no punctuation, we look for it up the module/class chain. For
    # example, HyperlinkHtml is found, even without the Generators::
    # prefix, because we look for it in module Generators first.

    def handle_special_CROSSREF(special)
      name = special.text
      if name[0,1] == '#'
        lookup = name[1..-1]
        name = lookup unless Options.instance.show_hash
      else
        lookup = name
      end

      # Find class, module, or method in class or module.
      if /([A-Z]\w*)[.\#](\w+[!?=]?)/ =~ lookup
        container = $1
        method = $2
        ref = @context.find_symbol(container, method)
      elsif /([A-Za-z]\w*)[.\#](\w+(\([\.\w+\*\/\+\-\=\<\>]+\))?)/ =~ lookup
        container = $1
        method = $2
        ref = @context.find_symbol(container, method)
      else
        ref = @context.find_symbol(lookup)
      end

      if ref and ref.document_self
        "<a href=\"#{ref.as_href(@from_path)}\">#{name}</a>"
      else
        name
      end
    end


    # Generate a hyperlink for url, labeled with text. Handle the
    # special cases for img: and link: described under handle_special_HYPEDLINK
    def gen_url(url, text)
      if url =~ /([A-Za-z]+):(.*)/
        type = $1
        path = $2
      else
        type = "http"
        path = url
        url  = "http://#{url}"
      end

      if type == "link"
        if path[0,1] == '#'     # is this meaningful?
          url = path
        else
          url = HTMLGenerator.gen_url(@from_path, path)
        end
      end

      if (type == "http" || type == "link") && 
          url =~ /\.(gif|png|jpg|jpeg|bmp)$/

        "<img src=\"#{url}\" />"
      else
        "<a href=\"#{url}\">#{text.sub(%r{^#{type}:/*}, '')}</a>"
      end
    end

    # And we're invoked with a potential external hyperlink mailto:
    # just gets inserted. http: links are checked to see if they
    # reference an image. If so, that image gets inserted using an
    # <img> tag. Otherwise a conventional <a href> is used.  We also
    # support a special type of hyperlink, link:, which is a reference
    # to a local file whose path is relative to the --op directory.

    def handle_special_HYPERLINK(special)
      url = special.text
      gen_url(url, url)
    end

    # HEre's a hypedlink where the label is different to the URL
    #  <label>[url]
    #
    
    def handle_special_TIDYLINK(special)
      text = special.text
#      unless text =~ /(\S+)\[(.*?)\]/
      unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/ 
        return text
      end
      label = $1
      url   = $2
      gen_url(url, label)
    end

  end


  
  #####################################################################
  #
  # Handle common markup tasks for the various Html classes
  #

  module MarkUp

    # Convert a string in markup format into HTML. We keep a cached
    # SimpleMarkup object lying around after the first time we're
    # called per object.

    def markup(str, remove_para=false)
      return '' unless str
      unless defined? @markup
        @markup = SM::SimpleMarkup.new

        # class names, variable names, or instance variables
        @markup.add_special(/(
                               \w+(::\w+)*[.\#]\w+(\([\.\w+\*\/\+\-\=\<\>]+\))?  # A::B.meth(**) (for operator in Fortran95)
                             | \#\w+(\([.\w\*\/\+\-\=\<\>]+\))?  #  meth(**) (for operator in Fortran95)
                             | \b([A-Z]\w*(::\w+)*[.\#]\w+)  #    A::B.meth
                             | \b([A-Z]\w+(::\w+)*)       #    A::B..
                             | \#\w+[!?=]?                #    #meth_name 
                             | \b\w+([_\/\.]+\w+)*[!?=]?  #    meth_name
                             )/x, 
                            :CROSSREF)

        # external hyperlinks
        @markup.add_special(/((link:|https?:|mailto:|ftp:|www\.)\S+\w)/, :HYPERLINK)

        # and links of the form  <text>[<url>]
        @markup.add_special(/(((\{.*?\})|\b\S+?)\[\S+?\.\S+?\])/, :TIDYLINK)
#        @markup.add_special(/\b(\S+?\[\S+?\.\S+?\])/, :TIDYLINK)

      end
      unless defined? @html_formatter
        @html_formatter = HyperlinkHtml.new(self.path, self)
      end

      # Convert leading comment markers to spaces, but only
      # if all non-blank lines have them

      if str =~ /^(?>\s*)[^\#]/
        content = str
      else
        content = str.gsub(/^\s*(#+)/)  { $1.tr('#',' ') }
      end

      res = @markup.convert(content, @html_formatter)
      if remove_para
        res.sub!(/^<p>/, '')
        res.sub!(/<\/p>$/, '')
      end
      res
    end

    # Qualify a stylesheet URL; if if +css_name+ does not begin with '/' or
    # 'http[s]://', prepend a prefix relative to +path+. Otherwise, return it
    # unmodified.

    def style_url(path, css_name=nil)
#      $stderr.puts "style_url( #{path.inspect}, #{css_name.inspect} )"
      css_name ||= CSS_NAME
      if %r{^(https?:/)?/} =~ css_name
        return css_name
      else
        return HTMLGenerator.gen_url(path, css_name)
      end
    end

    # Build a webcvs URL with the given 'url' argument. URLs with a '%s' in them
    # get the file's path sprintfed into them; otherwise they're just catenated
    # together.

    def cvs_url(url, full_path)
      if /%s/ =~ url
        return sprintf( url, full_path )
      else
        return url + full_path
      end
    end
  end


  #####################################################################
  #
  # A Context is built by the parser to represent a container: contexts
  # hold classes, modules, methods, require lists and include lists.
  # ClassModule and TopLevel are the context objects we process here
  # 
  class ContextUser

    include MarkUp

    attr_reader :context
    
    def initialize(context, options)
      @context = context
      @options = options
    end
      
    # convenience method to build a hyperlink
    def href(link, cls, name)
      %{<a href="#{link}" class="#{cls}">#{name}</a>} #"
    end

    # return a reference to outselves to be used as an href=
    # the form depends on whether we're all in one file
    # or in multiple files

    def as_href(from_path)
      if @options.all_one_file
        "#" + path
      else
        HTMLGenerator.gen_url(from_path, path)
      end
    end

    # Create a list of HtmlMethod objects for each method
    # in the corresponding context object. If the @options.show_all
    # variable is set (corresponding to the <tt>--all</tt> option,
    # we include all methods, otherwise just the public ones.

    def collect_methods
      list = @context.method_list
      unless @options.show_all
        list = list.find_all {|m| m.visibility == :public || m.visibility == :protected || m.force_documentation }
      end
      @methods = list.collect {|m| HtmlMethod.new(m, self, @options) }
    end

    # Build a summary list of all the methods in this context
    def build_method_summary_list(path_prefix="")
      collect_methods unless @methods
      meths = @methods.sort
      res = []
      meths.each do |meth|
	res << {
          "name" => CGI.escapeHTML(meth.name),
          "aref" => "#{path_prefix}\##{meth.aref}" 
        }
      end
      res
    end


    # Build a list of aliases for which we couldn't find a
    # corresponding method
    def build_alias_summary_list(section)
      values = []
      @context.aliases.each do |al|
        next unless al.section == section
        res = {
          'old_name' => al.old_name,
          'new_name' => al.new_name,
        }
        if al.comment && !al.comment.empty?
          res['desc'] = markup(al.comment, true)
        end
        values << res
      end
      values
    end
    
    # Build a list of constants
    def build_constants_summary_list(section)
      values = []
      @context.constants.each do |co|
        next unless co.section == section
        res = {
          'name'  => co.name,
          'value' => CGI.escapeHTML(co.value)
        }
        res['desc'] = markup(co.comment, true) if co.comment && !co.comment.empty?
        values << res
      end
      values
    end
    
    def build_requires_list(context)
      potentially_referenced_list(context.requires) {|fn| [fn + ".rb"] }
    end

    def build_include_list(context)
      potentially_referenced_list(context.includes)
    end

    # Build a list from an array of <i>Htmlxxx</i> items. Look up each
    # in the AllReferences hash: if we find a corresponding entry,
    # we generate a hyperlink to it, otherwise just output the name.
    # However, some names potentially need massaging. For example,
    # you may require a Ruby file without the .rb extension,
    # but the file names we know about may have it. To deal with
    # this, we pass in a block which performs the massaging,
    # returning an array of alternative names to match

    def potentially_referenced_list(array)
      res = []
      array.each do |i|
        ref = AllReferences[i.name] 
#         if !ref
#           container = @context.parent
#           while !ref && container
#             name = container.name + "::" + i.name
#             ref = AllReferences[name] 
#             container = container.parent
#           end
#         end

        ref = @context.find_symbol(i.name)
        ref = ref.viewer if ref

        if !ref && block_given?
          possibles = yield(i.name)
          while !ref and !possibles.empty?
            ref = AllReferences[possibles.shift]
          end
        end
        h_name = CGI.escapeHTML(i.name)
        if ref and ref.document_self
          path = url(ref.path)
          res << { "name" => h_name, "aref" => path }
        else
          res << { "name" => h_name }
        end
      end
      res
    end

    # Build an array of arrays of method details. The outer array has up
    # to six entries, public, private, and protected for both class
    # methods, the other for instance methods. The inner arrays contain
    # a hash for each method

    def build_method_detail_list(section)
      outer = []

      methods = @methods.sort
      for singleton in [true, false]
        for vis in [ :public, :protected, :private ] 
          res = []
          methods.each do |m|
            if m.section == section and
                m.document_self and 
                m.visibility == vis and 
                m.singleton == singleton
              row = {}
              if m.call_seq
                row["callseq"] = m.call_seq.gsub(/->/, '&rarr;')
              else
                row["name"]        = CGI.escapeHTML(m.name)
                row["params"]      = m.params
              end
              desc = m.description.strip
              row["m_desc"]      = desc unless desc.empty?
              row["aref"]        = m.aref
              row["visibility"]  = m.visibility.to_s

              alias_names = []
              m.aliases.each do |other|
                if other.viewer   # won't be if the alias is private
                  alias_names << {
                    'name' => other.name,
                    'aref'  => other.viewer.as_href(path)
                  } 
                end
              end
              unless alias_names.empty?
                row["aka"] = alias_names
              end

              if @options.inline_source
                code = m.source_code
                row["sourcecode"] = code if code
              else
                code = m.src_url
                if code
                  row["codeurl"] = code
                  row["imgurl"]  = m.img_url
                end
              end
              res << row
            end
          end
          if res.size > 0 
            outer << {
              "type"    => vis.to_s.capitalize,
              "category"    => singleton ? "Class" : "Instance",
              "methods" => res
            }
          end
        end
      end
      outer
    end

    # Build the structured list of classes and modules contained
    # in this context. 

    def build_class_list(level, from, section, infile=nil)
      res = ""
      prefix = "&nbsp;&nbsp;::" * level;

      from.modules.sort.each do |mod|
        next unless mod.section == section
        next if infile && !mod.defined_in?(infile)
        if mod.document_self
          res << 
            prefix <<
            "Module " <<
            href(url(mod.viewer.path), "link", mod.full_name) <<
            "<br />\n" <<
            build_class_list(level + 1, mod, section, infile)
        end
      end

      from.classes.sort.each do |cls|
        next unless cls.section == section
        next if infile && !cls.defined_in?(infile)
        if cls.document_self
          res      <<
            prefix << 
            "Class " <<
            href(url(cls.viewer.path), "link", cls.full_name) <<
            "<br />\n" <<
            build_class_list(level + 1, cls, section, infile)
        end
      end

      res
    end
    
    def url(target)
      HTMLGenerator.gen_url(path, target)
    end

    def aref_to(target)
      if @options.all_one_file
        "#" + target
      else
        url(target)
      end
    end

    def document_self
      @context.document_self
    end

    def diagram_reference(diagram)
      res = diagram.gsub(/((?:src|href)=")(.*?)"/) {
        $1 + url($2) + '"'
      }
      res
    end


    # Find a symbol in ourselves or our parent
    def find_symbol(symbol, method=nil)
      res = @context.find_symbol(symbol, method)
      if res
        res = res.viewer
      end
      res
    end

    # create table of contents if we contain sections
      
    def add_table_of_sections
      toc = []
      @context.sections.each do |section|
        if section.title
          toc << {
            'secname' => section.title,
            'href'    => section.sequence
          }
        end
      end
      
      @values['toc'] = toc unless toc.empty?
    end


  end

  #####################################################################
  #
  # Wrap a ClassModule context

  class HtmlClass < ContextUser

    attr_reader :path

    def initialize(context, html_file, prefix, options)
      super(context, options)

      @html_file = html_file
      @is_module = context.is_module?
      @values    = {}

      context.viewer = self

      if options.all_one_file
        @path = context.full_name
      else
        @path = http_url(context.full_name, prefix)
      end

      collect_methods

      AllReferences.add(name, self)
    end

    # return the relative file name to store this class in,
    # which is also its url
    def http_url(full_name, prefix)
      path = full_name.dup
      if path['<<']
        path.gsub!(/<<\s*(\w*)/) { "from-#$1" }
      end
      File.join(prefix, path.split("::")) + ".html"
    end


    def name
      @context.full_name
    end

    def parent_name
      @context.parent.full_name
    end

    def index_name
      name
    end

    def write_on(f)
      value_hash
      template = TemplatePage.new(RDoc::Page::BODY,
                                      RDoc::Page::CLASS_PAGE,
                                      RDoc::Page::METHOD_LIST)
      template.write_html_on(f, @values)
    end

    def value_hash
      class_attribute_values
      add_table_of_sections

      @values["charset"] = @options.charset
      @values["style_url"] = style_url(path, @options.css)

      d = markup(@context.comment)
      @values["description"] = d unless d.empty?

      ml = build_method_summary_list
      @values["methods"] = ml unless ml.empty?

      il = build_include_list(@context)
      @values["includes"] = il unless il.empty?

      @values["sections"] = @context.sections.map do |section|

        secdata = {
          "sectitle" => section.title,
          "secsequence" => section.sequence,
          "seccomment" => markup(section.comment)
        }

        al = build_alias_summary_list(section)
        secdata["aliases"] = al unless al.empty?
        
        co = build_constants_summary_list(section)
        secdata["constants"] = co unless co.empty?
        
        al = build_attribute_list(section)
        secdata["attributes"] = al unless al.empty?
        
        cl = build_class_list(0, @context, section)
        secdata["classlist"] = cl unless cl.empty?
        
        mdl = build_method_detail_list(section)
        secdata["method_list"] = mdl unless mdl.empty?

        secdata
      end

      @values
    end

    def build_attribute_list(section)
      atts = @context.attributes.sort
      res = []
      atts.each do |att|
        next unless att.section == section
        if att.visibility == :public || att.visibility == :protected || @options.show_all
          entry = {
            "name"   => CGI.escapeHTML(att.name), 
            "rw"     => att.rw, 
            "a_desc" => markup(att.comment, true)
          }
          unless att.visibility == :public || att.visibility == :protected
            entry["rw"] << "-"
          end
          res << entry
        end
      end
      res
    end

    def class_attribute_values
      h_name = CGI.escapeHTML(name)

      @values["classmod"]  = @is_module ? "Module" : "Class"
      @values["title"]     = "#{@values['classmod']}: #{h_name}"

      c = @context
      c = c.parent while c and !c.diagram
      if c && c.diagram
        @values["diagram"] = diagram_reference(c.diagram)
      end

      @values["full_name"] = h_name

      parent_class = @context.superclass

      if parent_class
	@values["parent"] = CGI.escapeHTML(parent_class)

	if parent_name
	  lookup = parent_name + "::" + parent_class
	else
	  lookup = parent_class
	end

	parent_url = AllReferences[lookup] || AllReferences[parent_class]

	if parent_url and parent_url.document_self
	  @values["par_url"] = aref_to(parent_url.path)
	end
      end

      files = []
      @context.in_files.each do |f|
        res = {}
        full_path = CGI.escapeHTML(f.file_absolute_name)

        res["full_path"]     = full_path
        res["full_path_url"] = aref_to(f.viewer.path) if f.document_self

        if @options.webcvs
          res["cvsurl"] = cvs_url( @options.webcvs, full_path )
        end

        files << res
      end

      @values['infiles'] = files
    end

    def <=>(other)
      self.name <=> other.name
    end

  end

  #####################################################################
  #
  # Handles the mapping of a file's information to HTML. In reality,
  # a file corresponds to a +TopLevel+ object, containing modules,
  # classes, and top-level methods. In theory it _could_ contain
  # attributes and aliases, but we ignore these for now.

  class HtmlFile < ContextUser

    attr_reader :path
    attr_reader :name

    def initialize(context, options, file_dir)
      super(context, options)

      @values = {}

      if options.all_one_file
        @path = filename_to_label
      else
        @path = http_url(file_dir)
      end

      @name = @context.file_relative_name

      collect_methods
      AllReferences.add(name, self)
      context.viewer = self
    end

    def http_url(file_dir)
      File.join(file_dir, @context.file_relative_name.tr('.', '_')) +
        ".html"
    end

    def filename_to_label
      @context.file_relative_name.gsub(/%|\/|\?|\#/) {|s| '%' + ("%x" % s[0]) }
    end

    def index_name
      name
    end

    def parent_name
      nil
    end

    def value_hash
      file_attribute_values
      add_table_of_sections

      @values["charset"]   = @options.charset
      @values["href"]      = path
      @values["style_url"] = style_url(path, @options.css)

      if @context.comment
        d = markup(@context.comment)
        @values["description"] = d if d.size > 0
      end

      ml = build_method_summary_list
      @values["methods"] = ml unless ml.empty?

      il = build_include_list(@context)
      @values["includes"] = il unless il.empty?

      rl = build_requires_list(@context)
      @values["requires"] = rl unless rl.empty?

      if @options.promiscuous
        file_context = nil
      else
        file_context = @context
      end


      @values["sections"] = @context.sections.map do |section|

        secdata = {
          "sectitle" => section.title,
          "secsequence" => section.sequence,
          "seccomment" => markup(section.comment)
        }

        cl = build_class_list(0, @context, section, file_context)
        @values["classlist"] = cl unless cl.empty?

        mdl = build_method_detail_list(section)
        secdata["method_list"] = mdl unless mdl.empty?

        al = build_alias_summary_list(section)
        secdata["aliases"] = al unless al.empty?
        
        co = build_constants_summary_list(section)
        @values["constants"] = co unless co.empty?

        secdata
      end
      
      @values
    end
    
    def write_on(f)
      value_hash
      template = TemplatePage.new(RDoc::Page::BODY,
                                  RDoc::Page::FILE_PAGE,
                                  RDoc::Page::METHOD_LIST)
      template.write_html_on(f, @values)
    end

    def file_attribute_values
      full_path = @context.file_absolute_name
      short_name = File.basename(full_path)
      
      @values["title"] = CGI.escapeHTML("File: #{short_name}")

      if @context.diagram
        @values["diagram"] = diagram_reference(@context.diagram)
      end

      @values["short_name"]   = CGI.escapeHTML(short_name)
      @values["full_path"]    = CGI.escapeHTML(full_path)
      @values["dtm_modified"] = @context.file_stat.mtime.to_s

      if @options.webcvs
        @values["cvsurl"] = cvs_url( @options.webcvs, @values["full_path"] )
      end
    end

    def <=>(other)
      self.name <=> other.name
    end
  end

  #####################################################################

  class HtmlMethod
    include MarkUp

    attr_reader :context
    attr_reader :src_url
    attr_reader :img_url
    attr_reader :source_code

    @@seq = "M000000"

    @@all_methods = []

    def HtmlMethod::reset
      @@all_methods = []
    end

    def initialize(context, html_class, options)
      @context    = context
      @html_class = html_class
      @options    = options
      @@seq       = @@seq.succ
      @seq        = @@seq
      @@all_methods << self

      context.viewer = self

      if (ts = @context.token_stream)
        @source_code = markup_code(ts)
        unless @options.inline_source
          @src_url = create_source_code_file(@source_code)
          @img_url = HTMLGenerator.gen_url(path, 'source.png')
        end
      end

      AllReferences.add(name, self)
    end
    
    # return a reference to outselves to be used as an href=
    # the form depends on whether we're all in one file
    # or in multiple files

    def as_href(from_path)
      if @options.all_one_file
        "#" + path
      else
        HTMLGenerator.gen_url(from_path, path)
      end
    end

    def name
      @context.name
    end

    def section
      @context.section
    end

    def index_name
      "#{@context.name} (#{@html_class.name})"
    end

    def parent_name
      if @context.parent.parent
        @context.parent.parent.full_name
      else
        nil
      end
    end

    def aref
      @seq
    end

    def path
      if @options.all_one_file
	aref
      else
	@html_class.path + "#" + aref
      end
    end

    def description
      markup(@context.comment)
    end

    def visibility
      @context.visibility
    end

    def singleton
      @context.singleton
    end

    def call_seq
      cs = @context.call_seq
      if cs
        cs.gsub(/\n/, "<br />\n")
      else
        nil
      end
    end

    def params
      # params coming from a call-seq in 'C' will start with the
      # method name
      p = @context.params
      if p !~ /^\w/
        p = @context.params.gsub(/\s*\#.*/, '')
        p = p.tr("\n", " ").squeeze(" ")
        p = "(" + p + ")" unless p[0] == ?(
        
        if (block = @context.block_params)
         # If this method has explicit block parameters, remove any
         # explicit &block

         p.sub!(/,?\s*&\w+/, '')

          block.gsub!(/\s*\#.*/, '')
          block = block.tr("\n", " ").squeeze(" ")
          if block[0] == ?(
            block.sub!(/^\(/, '').sub!(/\)/, '')
          end
          p << " {|#{block.strip}| ...}"
        end
      end
      CGI.escapeHTML(p)
    end
    
    def create_source_code_file(code_body)
      meth_path = @html_class.path.sub(/\.html$/, '.src')
      File.makedirs(meth_path)
      file_path = File.join(meth_path, @seq) + ".html"

      template = TemplatePage.new(RDoc::Page::SRC_PAGE)
      File.open(file_path, "w") do |f|
        values = {
          'title'     => CGI.escapeHTML(index_name),
          'code'      => code_body,
          'style_url' => style_url(file_path, @options.css),
          'charset'   => @options.charset
        }
        template.write_html_on(f, values)
      end
      HTMLGenerator.gen_url(path, file_path)
    end

    def HtmlMethod.all_methods
      @@all_methods
    end

    def <=>(other)
      @context <=> other.context
    end

    ##
    # Given a sequence of source tokens, mark up the source code
    # to make it look purty.


    def markup_code(tokens)
      src = ""
      tokens.each do |t|
        next unless t
        #    p t.class
#        style = STYLE_MAP[t.class]
        style = case t
                when RubyToken::TkCONSTANT then "ruby-constant"
                when RubyToken::TkKW       then "ruby-keyword kw"
                when RubyToken::TkIVAR     then "ruby-ivar"
                when RubyToken::TkOp       then "ruby-operator"
                when RubyToken::TkId       then "ruby-identifier"
                when RubyToken::TkNode     then "ruby-node"
                when RubyToken::TkCOMMENT  then "ruby-comment cmt"
                when RubyToken::TkREGEXP   then "ruby-regexp re"
                when RubyToken::TkSTRING   then "ruby-value str"
                when RubyToken::TkVal      then "ruby-value"
                else
                    nil
                end

        text = CGI.escapeHTML(t.text)

        if style
          src << "<span class=\"#{style}\">#{text}</span>"
        else
          src << text
        end
      end

      add_line_numbers(src) if Options.instance.include_line_numbers
      src
    end

    # we rely on the fact that the first line of a source code
    # listing has 
    #    # File xxxxx, line dddd

    def add_line_numbers(src)
      if src =~ /\A.*, line (\d+)/
        first = $1.to_i - 1
        last  = first + src.count("\n")
        size = last.to_s.length
        real_fmt = "%#{size}d: "
        fmt = " " * (size+2)
        src.gsub!(/^/) do
          res = sprintf(fmt, first) 
          first += 1
          fmt = real_fmt
          res
        end
      end
    end

    def document_self
      @context.document_self
    end

    def aliases
      @context.aliases
    end

    def find_symbol(symbol, method=nil)
      res = @context.parent.find_symbol(symbol, method)
      if res
        res = res.viewer
      end
      res
    end
  end

  #####################################################################

  class HTMLGenerator

    include MarkUp

    ##
    # convert a target url to one that is relative to a given
    # path
    
    def HTMLGenerator.gen_url(path, target)
      from          = File.dirname(path)
      to, to_file   = File.split(target)
      
      from = from.split("/")
      to   = to.split("/")
      
      while from.size > 0 and to.size > 0 and from[0] == to[0]
        from.shift
        to.shift
      end
      
      from.fill("..")
      from.concat(to)
      from << to_file
      File.join(*from)
    end

    # Generators may need to return specific subclasses depending
    # on the options they are passed. Because of this
    # we create them using a factory

    def HTMLGenerator.for(options)
      AllReferences::reset
      HtmlMethod::reset

      if options.all_one_file
        HTMLGeneratorInOne.new(options)
      else
        HTMLGenerator.new(options)
      end
    end

    class <<self
      protected :new
    end

    # Set up a new HTML generator. Basically all we do here is load
    # up the correct output temlate

    def initialize(options) #:not-new:
      @options    = options
      load_html_template
    end


    ##
    # Build the initial indices and output objects
    # based on an array of TopLevel objects containing
    # the extracted information. 

    def generate(toplevels)
      @toplevels  = toplevels
      @files      = []
      @classes    = []

      write_style_sheet
      gen_sub_directories()
      build_indices
      generate_html
    end

    private

    ##
    # Load up the HTML template specified in the options.
    # If the template name contains a slash, use it literally
    #
    def load_html_template
      template = @options.template
      unless template =~ %r{/|\\}
        template = File.join("rdoc/generators/template",
                             @options.generator.key, template)
      end
      require template
      extend RDoc::Page
    rescue LoadError
      $stderr.puts "Could not find HTML template '#{template}'"
      exit 99
    end

    ##
    # Write out the style sheet used by the main frames
    #
    
    def write_style_sheet
      template = TemplatePage.new(RDoc::Page::STYLE)
      unless @options.css
        File.open(CSS_NAME, "w") do |f|
          values = { "fonts" => RDoc::Page::FONTS }
          template.write_html_on(f, values)
        end
      end
    end

    ##
    # See the comments at the top for a description of the
    # directory structure

    def gen_sub_directories
      File.makedirs(FILE_DIR, CLASS_DIR)
    rescue 
      $stderr.puts $!.message
      exit 1
    end

    ##
    # Generate:
    #
    # * a list of HtmlFile objects for each TopLevel object.
    # * a list of HtmlClass objects for each first level
    #   class or module in the TopLevel objects
    # * a complete list of all hyperlinkable terms (file,
    #   class, module, and method names)

    def build_indices

      @toplevels.each do |toplevel|
        @files << HtmlFile.new(toplevel, @options, FILE_DIR)
      end

      RDoc::TopLevel.all_classes_and_modules.each do |cls|
        build_class_list(cls, @files[0], CLASS_DIR)
      end
    end

    def build_class_list(from, html_file, class_dir)
      @classes << HtmlClass.new(from, html_file, class_dir, @options)
      from.each_classmodule do |mod|
        build_class_list(mod, html_file, class_dir)
      end
    end

    ##
    # Generate all the HTML
    #
    def generate_html
      # the individual descriptions for files and classes
      gen_into(@files)
      gen_into(@classes)
      # and the index files
      gen_file_index
      gen_class_index
      gen_method_index
      gen_main_index
      
      # this method is defined in the template file
      write_extra_pages if defined? write_extra_pages
    end

    def gen_into(list)
      list.each do |item|
        if item.document_self
          op_file = item.path
          File.makedirs(File.dirname(op_file))
          File.open(op_file, "w") { |file| item.write_on(file) }
        end
      end

    end

    def gen_file_index
      gen_an_index(@files, 'Files', 
                   RDoc::Page::FILE_INDEX, 
                   "fr_file_index.html")
    end

    def gen_class_index
      gen_an_index(@classes, 'Classes',
                   RDoc::Page::CLASS_INDEX,
                   "fr_class_index.html")
    end

    def gen_method_index
      gen_an_index(HtmlMethod.all_methods, 'Methods', 
                   RDoc::Page::METHOD_INDEX,
                   "fr_method_index.html")
    end

    
    def gen_an_index(collection, title, template, filename)
      template = TemplatePage.new(RDoc::Page::FR_INDEX_BODY, template)
      res = []
      collection.sort.each do |f|
        if f.document_self
          res << { "href" => f.path, "name" => f.index_name }
        end
      end

      values = {
        "entries"    => res,
        'list_title' => CGI.escapeHTML(title),
        'index_url'  => main_url,
        'charset'    => @options.charset,
        'style_url'  => style_url('', @options.css),
      }

      File.open(filename, "w") do |f|
        template.write_html_on(f, values)
      end
    end

    # The main index page is mostly a template frameset, but includes
    # the initial page. If the <tt>--main</tt> option was given,
    # we use this as our main page, otherwise we use the
    # first file specified on the command line.

    def gen_main_index
      template = TemplatePage.new(RDoc::Page::INDEX)
      File.open("index.html", "w") do |f|
        values = {
          "initial_page" => main_url,
          'title'        => CGI.escapeHTML(@options.title),
          'charset'      => @options.charset
        }
        if @options.inline_source
          values['inline_source'] = true
        end
        template.write_html_on(f, values)
      end
    end

    # return the url of the main page
    def main_url
      main_page = @options.main_page
      ref = nil
      if main_page
        ref = AllReferences[main_page]
        if ref
          ref = ref.path
        else
          $stderr.puts "Could not find main page #{main_page}"
        end
      end

      unless ref
        for file in @files
          if file.document_self
            ref = file.path 
            break
          end
        end
      end

      unless ref
        $stderr.puts "Couldn't find anything to document"
        $stderr.puts "Perhaps you've used :stopdoc: in all classes"
        exit(1)
      end

      ref
    end


  end


  ######################################################################


  class HTMLGeneratorInOne < HTMLGenerator

    def initialize(*args)
      super
    end

    ##
    # Build the initial indices and output objects
    # based on an array of TopLevel objects containing
    # the extracted information. 

    def generate(info)
      @toplevels  = info
      @files      = []
      @classes    = []
      @hyperlinks = {}

      build_indices
      generate_xml
    end


    ##
    # Generate:
    #
    # * a list of HtmlFile objects for each TopLevel object.
    # * a list of HtmlClass objects for each first level
    #   class or module in the TopLevel objects
    # * a complete list of all hyperlinkable terms (file,
    #   class, module, and method names)

    def build_indices

      @toplevels.each do |toplevel|
        @files << HtmlFile.new(toplevel, @options, FILE_DIR)
      end

      RDoc::TopLevel.all_classes_and_modules.each do |cls|
        build_class_list(cls, @files[0], CLASS_DIR)
      end
    end

    def build_class_list(from, html_file, class_dir)
      @classes << HtmlClass.new(from, html_file, class_dir, @options)
      from.each_classmodule do |mod|
        build_class_list(mod, html_file, class_dir)
      end
    end

    ##
    # Generate all the HTML. For the one-file case, we generate
    # all the information in to one big hash
    #
    def generate_xml
      values = { 
        'charset' => @options.charset,
        'files'   => gen_into(@files),
        'classes' => gen_into(@classes),
        'title'        => CGI.escapeHTML(@options.title),
      }
      
      # this method is defined in the template file
      write_extra_pages if defined? write_extra_pages

      template = TemplatePage.new(RDoc::Page::ONE_PAGE)

      if @options.op_name
        opfile = File.open(@options.op_name, "w")
      else
        opfile = $stdout
      end
      template.write_html_on(opfile, values)
    end

    def gen_into(list)
      res = []
      list.each do |item|
        res << item.value_hash
      end
      res
    end

    def gen_file_index
      gen_an_index(@files, 'Files')
    end

    def gen_class_index
      gen_an_index(@classes, 'Classes')
    end

    def gen_method_index
      gen_an_index(HtmlMethod.all_methods, 'Methods')
    end

    
    def gen_an_index(collection, title)
      res = []
      collection.sort.each do |f|
        if f.document_self
          res << { "href" => f.path, "name" => f.index_name }
        end
      end

      return {
        "entries" => res,
        'list_title' => title,
        'index_url'  => main_url,
      }
    end

  end
end
PK     Z\>4_  _    rdoc/generators/ri_generator.rbnu [        # We're responsible for generating all the HTML files
# from the object tree defined in code_objects.rb. We
# generate:
#
# [files]   an html file for each input file given. These
#           input files appear as objects of class
#           TopLevel
#
# [classes] an html file for each class or module encountered.
#           These classes are not grouped by file: if a file
#           contains four classes, we'll generate an html
#           file for the file itself, and four html files 
#           for the individual classes. 
#
# [indices] we generate three indices for files, classes,
#           and methods. These are displayed in a browser
#           like window with three index panes across the
#           top and the selected description below
#
# Method descriptions appear in whatever entity (file, class,
# or module) that contains them.
#
# We generate files in a structure below a specified subdirectory,
# normally +doc+.
#
#  opdir
#     |
#     |___ files
#     |       |__  per file summaries
#     |
#     |___ classes
#             |__ per class/module descriptions
#
# HTML is generated using the Template class.
#

require 'ftools'

require 'rdoc/options'
require 'rdoc/template'
require 'rdoc/markup/simple_markup'
require 'rdoc/markup/simple_markup/to_flow'
require 'cgi'

require 'rdoc/ri/ri_cache'
require 'rdoc/ri/ri_reader'
require 'rdoc/ri/ri_writer'
require 'rdoc/ri/ri_descriptions'

module Generators


  class RIGenerator

    # Generators may need to return specific subclasses depending
    # on the options they are passed. Because of this
    # we create them using a factory

    def RIGenerator.for(options)
      new(options)
    end

    class <<self
      protected :new
    end

    # Set up a new HTML generator. Basically all we do here is load
    # up the correct output temlate

    def initialize(options) #:not-new:
      @options   = options
      @ri_writer = RI::RiWriter.new(".")
      @markup    = SM::SimpleMarkup.new
      @to_flow   = SM::ToFlow.new
    end


    ##
    # Build the initial indices and output objects
    # based on an array of TopLevel objects containing
    # the extracted information. 

    def generate(toplevels)
      RDoc::TopLevel.all_classes_and_modules.each do |cls|
        process_class(cls)
      end
    end

    def process_class(from_class)
      generate_class_info(from_class)

      # now recure into this classes constituent classess
      from_class.each_classmodule do |mod|
        process_class(mod)
      end
    end

    def generate_class_info(cls)
      if cls === RDoc::NormalModule
        cls_desc = RI::ModuleDescription.new
      else
        cls_desc = RI::ClassDescription.new
        cls_desc.superclass  = cls.superclass
      end
      cls_desc.name        = cls.name
      cls_desc.full_name   = cls.full_name
      cls_desc.comment     = markup(cls.comment)

      cls_desc.attributes =cls.attributes.sort.map do |a|
        RI::Attribute.new(a.name, a.rw, markup(a.comment))
      end

      cls_desc.constants = cls.constants.map do |c|
        RI::Constant.new(c.name, c.value, markup(c.comment))
      end

      cls_desc.includes = cls.includes.map do |i|
        RI::IncludedModule.new(i.name)
      end

      class_methods, instance_methods = method_list(cls)

      cls_desc.class_methods = class_methods.map do |m|
        RI::MethodSummary.new(m.name)
      end
      cls_desc.instance_methods = instance_methods.map do |m|
        RI::MethodSummary.new(m.name)
      end

      update_or_replace(cls_desc)

      class_methods.each do |m|
        generate_method_info(cls_desc, m)
      end

      instance_methods.each do |m|
        generate_method_info(cls_desc, m)
      end
    end


    def generate_method_info(cls_desc, method)
      meth_desc = RI::MethodDescription.new
      meth_desc.name = method.name
      meth_desc.full_name = cls_desc.full_name
      if method.singleton
        meth_desc.full_name += "::"
      else
        meth_desc.full_name += "#"
      end
      meth_desc.full_name << method.name

      meth_desc.comment = markup(method.comment)
      meth_desc.params = params_of(method)
      meth_desc.visibility = method.visibility.to_s
      meth_desc.is_singleton = method.singleton
      meth_desc.block_params = method.block_params

      meth_desc.aliases = method.aliases.map do |a|
        RI::AliasName.new(a.name)
      end

      @ri_writer.add_method(cls_desc, meth_desc)
    end

    private

    # return a list of class and instance methods that we'll be
    # documenting

    def method_list(cls)
      list = cls.method_list
      unless @options.show_all
        list = list.find_all do |m|
          m.visibility == :public || m.visibility == :protected || m.force_documentation
        end
      end

      c = []
      i = []
      list.sort.each do |m|
        if m.singleton
          c << m
        else
          i << m
        end
      end
      return c,i
    end
    
    def params_of(method)
      if method.call_seq
        method.call_seq
      else
        params = method.params || ""
        
        p = params.gsub(/\s*\#.*/, '')
        p = p.tr("\n", " ").squeeze(" ")
        p = "(" + p + ")" unless p[0] == ?(
        
        if (block = method.block_params)
          block.gsub!(/\s*\#.*/, '')
          block = block.tr("\n", " ").squeeze(" ")
          if block[0] == ?(
            block.sub!(/^\(/, '').sub!(/\)/, '')
          end
          p << " {|#{block.strip}| ...}"
        end
        p
      end
    end

    def markup(comment)
      return nil if !comment || comment.empty?

      # Convert leading comment markers to spaces, but only
      # if all non-blank lines have them
      
      if comment =~ /^(?>\s*)[^\#]/
        content = comment
      else
        content = comment.gsub(/^\s*(#+)/)  { $1.tr('#',' ') }
      end
      @markup.convert(content, @to_flow)
    end


    # By default we replace existing classes with the
    # same name. If the --merge option was given, we instead
    # merge this definition into an existing class. We add
    # our methods, aliases, etc to that class, but do not
    # change the class's description.

    def update_or_replace(cls_desc)
      old_cls = nil

      if @options.merge
        rdr = RI::RiReader.new(RI::RiCache.new(@options.op_dir))

        namespace = rdr.top_level_namespace
        namespace = rdr.lookup_namespace_in(cls_desc.name, namespace)
        if namespace.empty?
          $stderr.puts "You asked me to merge this source into existing "
          $stderr.puts "documentation. This file references a class or "
          $stderr.puts "module called #{cls_desc.name} which I don't"
          $stderr.puts "have existing documentation for."
          $stderr.puts 
          $stderr.puts "Perhaps you need to generate its documentation first"
          exit 1
        else
          old_cls = namespace[0]
        end
      end

      if old_cls.nil?
        # no merge: simply overwrite
        @ri_writer.remove_class(cls_desc)
        @ri_writer.add_class(cls_desc)
      else
        # existing class: merge in
        old_desc = rdr.get_class(old_cls)

        old_desc.merge_in(cls_desc)
        @ri_writer.add_class(old_desc)
      end
    end
  end
end
PK     Z\&5L  L     rdoc/generators/chm_generator.rbnu [        require 'rdoc/generators/html_generator'

module Generators

  class CHMGenerator < HTMLGenerator

    HHC_PATH = "c:/Program Files/HTML Help Workshop/hhc.exe"

    # Standard generator factory
    def CHMGenerator.for(options)
      CHMGenerator.new(options)
    end

    
    def initialize(*args)
      super
      @op_name = @options.op_name || "rdoc"
      check_for_html_help_workshop
    end

    def check_for_html_help_workshop
      stat = File.stat(HHC_PATH)
    rescue
      $stderr <<
	"\n.chm output generation requires that Microsoft's Html Help\n" <<
	"Workshop is installed. RDoc looks for it in:\n\n    " <<
	HHC_PATH <<
	"\n\nYou can download a copy for free from:\n\n" <<
	"    http://msdn.microsoft.com/library/default.asp?" <<
	"url=/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp\n\n"
      
      exit 99
    end

    # Generate the html as normal, then wrap it
    # in a help project
    def generate(info)
      super
      @project_name = @op_name + ".hhp"
      create_help_project
    end

    # The project contains the project file, a table of contents
    # and an index
    def create_help_project
      create_project_file
      create_contents_and_index
      compile_project
    end

    # The project file links together all the various
    # files that go to make up the help.

    def create_project_file
      template = TemplatePage.new(RDoc::Page::HPP_FILE)
      values = { "title" => @options.title, "opname" => @op_name }
      files = []
      @files.each do |f|
	files << { "html_file_name" => f.path }
      end

      values['all_html_files'] = files
      
      File.open(@project_name, "w") do |f|
        template.write_html_on(f, values)
      end
    end

    # The contents is a list of all files and modules.
    # For each we include  as sub-entries the list
    # of methods they contain. As we build the contents
    # we also build an index file

    def create_contents_and_index
      contents = []
      index    = []

      (@files+@classes).sort.each do |entry|
	content_entry = { "c_name" => entry.name, "ref" => entry.path }
	index << { "name" => entry.name, "aref" => entry.path }

	internals = []

	methods = entry.build_method_summary_list(entry.path)

	content_entry["methods"] = methods unless methods.empty?
        contents << content_entry
	index.concat methods
      end

      values = { "contents" => contents }
      template = TemplatePage.new(RDoc::Page::CONTENTS)
      File.open("contents.hhc", "w") do |f|
	template.write_html_on(f, values)
      end

      values = { "index" => index }
      template = TemplatePage.new(RDoc::Page::CHM_INDEX)
      File.open("index.hhk", "w") do |f|
	template.write_html_on(f, values)
      end      
    end

    # Invoke the windows help compiler to compiler the project
    def compile_project
      system(HHC_PATH, @project_name)
    end

  end


end
PK     Z\%6w  w  #  rdoc/generators/template/xml/xml.rbnu [        module RDoc
module Page



CONTENTS_XML = %{
IF:description
    <description>
%description%
    </description>
ENDIF:description
    <contents>
IF:requires
      <required-file-list>
START:requires
         <required-file name="%name%"
IF:aref 
                        href="%aref%"
ENDIF:aref
         />
END:requires
      </required-file-list>
ENDIF:requires
IF:attributes
      <attribute-list>
START:attributes
        <attribute name="%name%">
IF:rw
          <attribute-rw>%rw%</attribute-rw>
ENDIF:rw
          <description>%a_desc%</description>
        </attribute>
END:attributes
      </attribute-list>
ENDIF:attributes
IF:includes
      <included-module-list>
START:includes
        <included-module name="%name%"
IF:aref
                         href="%aref%"
ENDIF:aref
        />
END:includes
      </included-module-list>
ENDIF:includes
IF:method_list
      <method-list>
START:method_list
IF:methods
START:methods
        <method name="%name%" type="%type%" category="%category%" id="%aref%">
          <parameters>%params%</parameters>
IF:m_desc
          <description>
%m_desc%
          </description>
ENDIF:m_desc
IF:sourcecode
          <source-code-listing>
%sourcecode%
          </source-code-listing>
ENDIF:sourcecode
        </method>
END:methods
ENDIF:methods
END:method_list
      </method-list>
ENDIF:method_list
     </contents>
}

########################################################################

ONE_PAGE = %{<?xml version="1.0" encoding="utf-8"?>
<rdoc>
<file-list>
START:files
  <file name="%short_name%" id="%href%">
    <file-info>
      <path>%full_path%</path>
      <dtm-modified>%dtm_modified%</dtm-modified>
    </file-info>
} + CONTENTS_XML + %{
  </file>
END:files
</file-list>
<class-module-list>
START:classes
  <%classmod% name="%full_name%" id="%full_name%">
    <classmod-info>
IF:infiles
      <infiles>      
START:infiles
        <infile>HREF:full_path_url:full_path:</infile>
END:infiles
      </infiles>
ENDIF:infiles
IF:parent
     <superclass>HREF:par_url:parent:</superclass>
ENDIF:parent
    </classmod-info>
} + CONTENTS_XML + %{
  </%classmod%>
END:classes
</class-module-list>
</rdoc>
}


end
end
PK     Z\Og	  	  #  rdoc/generators/template/xml/rdf.rbnu [        module RDoc
module Page



CONTENTS_RDF = %{
IF:description
    <description rd:parseType="Literal">
%description%
    </description>
ENDIF:description

IF:requires
START:requires
         <rd:required-file rd:name="%name%" />
END:requires
ENDIF:requires

IF:attributes
START:attributes
        <contents>
        <Attribute rd:name="%name%">
IF:rw
          <attribute-rw>%rw%</attribute-rw>
ENDIF:rw
          <description rdf:parseType="Literal">%a_desc%</description>
        </Attribute>
        </contents>
END:attributes
ENDIF:attributes

IF:includes
      <IncludedModuleList>
START:includes
        <included-module rd:name="%name%"  />
END:includes
      </IncludedModuleList>
ENDIF:includes

IF:method_list
START:method_list
IF:methods
START:methods
	<contents>
        <Method rd:name="%name%" rd:visibility="%type%"
                rd:category="%category%" rd:id="%aref%">
          <parameters>%params%</parameters>
IF:m_desc
          <description rdf:parseType="Literal">
%m_desc%
          </description>
ENDIF:m_desc
IF:sourcecode
          <source-code-listing rdf:parseType="Literal">
%sourcecode%
          </source-code-listing>
ENDIF:sourcecode
        </Method>
       </contents>
END:methods
ENDIF:methods
END:method_list
ENDIF:method_list
     <!-- end method list -->
}

########################################################################

ONE_PAGE = %{<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns="http://pragprog.com/rdoc/rdoc.rdf#"
        xmlns:rd="http://pragprog.com/rdoc/rdoc.rdf#">

<!-- RDoc -->
START:files
  <rd:File rd:name="%short_name%" rd:id="%href%">
      <path>%full_path%</path>
      <dtm-modified>%dtm_modified%</dtm-modified>
} + CONTENTS_RDF + %{
  </rd:File>
END:files
START:classes
  <%classmod% rd:name="%full_name%" rd:id="%full_name%">
    <classmod-info>
IF:infiles
      <InFiles>
START:infiles
        <infile>
          <File rd:name="%full_path%"
IF:full_path_url
                rdf:about="%full_path_url%"
ENDIF:full_path_url
           />
         </infile>
END:infiles
      </InFiles>
ENDIF:infiles
IF:parent
     <superclass>HREF:par_url:parent:</superclass>
ENDIF:parent
    </classmod-info>
} + CONTENTS_RDF + %{
  </%classmod%>
END:classes
<!-- /RDoc -->
</rdf:RDF>
}


end
end

PK     Z\    #  rdoc/generators/template/chm/chm.rbnu [        module RDoc
module Page

require "rdoc/generators/template/html/html"

# This is a nasty little hack, but hhc doesn't support the <?xml
# tag, so...

BODY.sub!(/<\?xml.*\?>/, '')
SRC_PAGE.sub!(/<\?xml.*\?>/, '')

HPP_FILE = %{
[OPTIONS]
Auto Index = Yes
Compatibility=1.1 or later
Compiled file=%opname%.chm
Contents file=contents.hhc
Full-text search=Yes
Index file=index.hhk
Language=0x409 English(United States)
Title=%title%

[FILES]
START:all_html_files
%html_file_name%
END:all_html_files
}

CONTENTS = %{
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
<!-- Sitemap 1.0 -->
</HEAD><BODY>
<OBJECT type="text/site properties">
	<param name="Foreground" value="0x80">
	<param name="Window Styles" value="0x800025">
	<param name="ImageType" value="Folder">
</OBJECT>
<UL>
START:contents
	<LI> <OBJECT type="text/sitemap">
		<param name="Name" value="%c_name%">
		<param name="Local" value="%ref%">
		</OBJECT>
IF:methods
<ul>
START:methods
	<LI> <OBJECT type="text/sitemap">
		<param name="Name" value="%name%">
		<param name="Local" value="%aref%">
		</OBJECT>
END:methods
</ul>
ENDIF:methods
        </LI>
END:contents
</UL>
</BODY></HTML>
}


CHM_INDEX  = %{
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
<!-- Sitemap 1.0 -->
</HEAD><BODY>
<OBJECT type="text/site properties">
	<param name="Foreground" value="0x80">
	<param name="Window Styles" value="0x800025">
	<param name="ImageType" value="Folder">
</OBJECT>
<UL>
START:index
	<LI> <OBJECT type="text/sitemap">
		<param name="Name" value="%name%">
		<param name="Local" value="%aref%">
		</OBJECT>
END:index
</UL>
</BODY></HTML>
}
end
end
PK     Z\aV"  "  &  rdoc/generators/template/html/hefss.rbnu [        module RDoc
module Page


FONTS = "Verdana, Arial, Helvetica, sans-serif"

STYLE = %{
body,p { font-family: Verdana, Arial, Helvetica, sans-serif; 
       color: #000040; background: #BBBBBB;
}

td { font-family: Verdana, Arial, Helvetica, sans-serif; 
       color: #000040;
}

.attr-rw { font-size: small; color: #444488 }

.title-row {color:      #eeeeff;
	    background: #BBBBDD;
}

.big-title-font { color: white;
                  font-family: Verdana, Arial, Helvetica, sans-serif;
                  font-size: large; 
                  height: 50px}

.small-title-font { color: purple;
                    font-family: Verdana, Arial, Helvetica, sans-serif;
                    font-size: small; }

.aqua { color: purple }

.method-name, attr-name {
      font-family: monospace; font-weight: bold;
}

.tablesubtitle {
   width: 100%;
   margin-top: 1ex;
   margin-bottom: .5ex;
   padding: 5px 0px 5px 20px;
   font-size: large;
   color: purple;
   background: #BBBBCC;
}

.tablesubsubtitle {
   width: 100%;
   margin-top: 1ex;
   margin-bottom: .5ex;
   padding: 5px 0px 5px 20px;
   font-size: medium;
   color: white;
   background: #BBBBCC;
}

.name-list {
  font-family: monospace;
  margin-left: 40px;
  margin-bottom: 2ex;
  line-height: 140%;
}

.description {
  margin-left: 40px;
  margin-bottom: 2ex;
  line-height: 140%;
}

.methodtitle {
  font-size: medium;
  text_decoration: none;
  padding: 3px 3px 3px 20px;
  color: #0000AA;
}

.column-title {
  font-size: medium;
  font-weight: bold;
  text_decoration: none;
  padding: 3px 3px 3px 20px;
  color: #3333CC;
  }

.variable-name {
  font-family: monospace;
  font-size: medium;
  text_decoration: none;
  padding: 3px 3px 3px 20px;
  color: #0000AA;
}

.row-name {
  font-size: medium;
  font-weight: medium;
  font-family: monospace;
  text_decoration: none;
  padding: 3px 3px 3px 20px;
}

.paramsig {
   font-size: small;
}

.srcbut { float: right }

}


############################################################################


BODY = %{
<html><head>
  <title>%title%</title>
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%">
  <link rel="stylesheet" href="%style_url%" type="text/css" media="screen" />
  <script type="text/javascript" language="JavaScript">
  <!--
  function popCode(url) {
    parent.frames.source.location = url
  }
  //-->
  </script>
</head>
<body bgcolor="#BBBBBB">

!INCLUDE!  <!-- banner header -->

IF:diagram
<table width="100%"><tr><td align="center">
%diagram%
</td></tr></table>
ENDIF:diagram

IF:description
<div class="description">%description%</div>
ENDIF:description

IF:requires
<table cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Required files</td></tr>
</table><br />
<div class="name-list">
START:requires
HREF:aref:name:
END:requires
ENDIF:requires
</div>

IF:methods
<table cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Subroutines and Functions</td></tr>
</table><br />
<div class="name-list">
START:methods
HREF:aref:name:,
END:methods
</div>
ENDIF:methods

IF:attributes
<table cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Arguments</td></tr>
</table><br />
<table cellspacing="5">
START:attributes
     <tr valign="top">
IF:rw
       <td align="center" class="attr-rw">&nbsp;[%rw%]&nbsp;</td>
ENDIF:rw
IFNOT:rw
       <td></td>
ENDIF:rw
       <td class="attr-name">%name%</td>
       <td>%a_desc%</td>
     </tr>
END:attributes
</table>
ENDIF:attributes

IF:classlist
<table cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Modules</td></tr>
</table><br />
%classlist%<br />
ENDIF:classlist

  !INCLUDE!  <!-- method descriptions -->

</body>
</html>
}

###############################################################################

FILE_PAGE = <<_FILE_PAGE_
<table width="100%">
 <tr class="title-row">
 <td><table width="100%"><tr>
   <td class="big-title-font" colspan="2"><font size="-3"><b>File</b><br /></font>%short_name%</td>
   <td align="right"><table cellspacing="0" cellpadding="2">
         <tr>
           <td  class="small-title-font">Path:</td>
           <td class="small-title-font">%full_path%
IF:cvsurl
				&nbsp;(<a href="%cvsurl%"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
ENDIF:cvsurl
           </td>
         </tr>
         <tr>
           <td class="small-title-font">Modified:</td>
           <td class="small-title-font">%dtm_modified%</td>
         </tr>
        </table>
    </td></tr></table></td>
  </tr>
</table><br />
_FILE_PAGE_

###################################################################

CLASS_PAGE = %{
<table width="100%" border="0" cellspacing="0">
 <tr class="title-row">
 <td class="big-title-font">
   <font size="-3"><b>%classmod%</b><br /></font>%full_name%
 </td>
 <td align="right">
   <table cellspacing="0" cellpadding="2">
     <tr valign="top">
      <td class="small-title-font">In:</td>
      <td class="small-title-font">
START:infiles
HREF:full_path_url:full_path:
IF:cvsurl
&nbsp;(<a href="%cvsurl%"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
ENDIF:cvsurl
END:infiles
      </td>
     </tr>
IF:parent
     <tr>
      <td class="small-title-font">Parent:</td>
      <td class="small-title-font">
IF:par_url
        <a href="%par_url%" class="cyan">
ENDIF:par_url
%parent%
IF:par_url
         </a>
ENDIF:par_url
      </td>
     </tr>
ENDIF:parent
   </table>
  </td>
  </tr>
</table><br />
}

###################################################################

METHOD_LIST = %{
IF:includes
<div class="tablesubsubtitle">Uses</div><br />
<div class="name-list">
START:includes
    <span class="method-name">HREF:aref:name:</span>
END:includes
</div>
ENDIF:includes

IF:method_list
START:method_list
IF:methods
<table cellpadding="5" width="100%">
<tr><td class="tablesubtitle">%type% %category% methods</td></tr>
</table>
START:methods
<table width="100%" cellspacing="0" cellpadding="5" border="0">
<tr><td class="methodtitle">
<a name="%aref%">
<b>%name%</b>%params% 
IF:codeurl
<a href="%codeurl%" target="source" class="srclink">src</a>
ENDIF:codeurl
</a></td></tr>
</table>
IF:m_desc
<div class="description">
%m_desc%
</div>
ENDIF:m_desc
END:methods
ENDIF:methods
END:method_list
ENDIF:method_list
}

=begin
=end

########################## Source code ##########################

SRC_PAGE = %{
<html>
<head><title>%title%</title>
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
<style type="text/css">
  .kw { color: #3333FF; font-weight: bold }
  .cmt { color: green; font-style: italic }
  .str { color: #662222; font-style: italic }
  .re  { color: #662222; }
.ruby-comment    { color: green; font-style: italic }
.ruby-constant   { color: #4433aa; font-weight: bold; }
.ruby-identifier { color: #222222;  }
.ruby-ivar       { color: #2233dd; }
.ruby-keyword    { color: #3333FF; font-weight: bold }
.ruby-node       { color: #777777; }
.ruby-operator   { color: #111111;  }
.ruby-regexp     { color: #662222; }
.ruby-value      { color: #662222; font-style: italic }
</style>
</head>
<body bgcolor="#BBBBBB">
<pre>%code%</pre>
</body>
</html>
}

########################## Index ################################

FR_INDEX_BODY = %{
!INCLUDE!
}

FILE_INDEX = %{
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
<style type="text/css">
<!--
  body {
background-color: #bbbbbb;
     font-family: #{FONTS}; 
       font-size: 11px; 
      font-style: normal;
     line-height: 14px; 
           color: #000040;
  }
div.banner {
  background: #bbbbcc;
  color:      white;
  padding: 1;
  margin: 0;
  font-size: 90%;
  font-weight: bold;
  line-height: 1.1;
  text-align: center;
  width: 100%;
}
  
-->
</style>
<base target="docwin">
</head>
<body>
<div class="banner">%list_title%</div>
START:entries
<a href="%href%">%name%</a><br />
END:entries
</body></html>
}

CLASS_INDEX = FILE_INDEX
METHOD_INDEX = FILE_INDEX

INDEX = %{
<html>
<head>
  <title>%title%</title>
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%">
</head>

<frameset cols="20%,*">
    <frameset rows="15%,35%,50%">
        <frame src="fr_file_index.html"   title="Files" name="Files">
        <frame src="fr_class_index.html"  name="Modules">
        <frame src="fr_method_index.html" name="Subroutines and Functions">
    </frameset>
    <frameset rows="80%,20%">
      <frame  src="%initial_page%" name="docwin">
      <frame  src="blank.html" name="source">
    </frameset>
    <noframes>
          <body bgcolor="#BBBBBB">
            Click <a href="html/index.html">here</a> for a non-frames
            version of this page.
          </body>
    </noframes>
</frameset>

</html>
}

# and a blank page to use as a target
BLANK = %{
<html><body bgcolor="#BBBBBB"></body></html>
}

def write_extra_pages
  template = TemplatePage.new(BLANK)
  File.open("blank.html", "w") { |f| template.write_html_on(f, {}) }
end

end
end
PK     Z\(g%O#  O#  '  rdoc/generators/template/html/kilmer.rbnu [        module RDoc
module Page


FONTS = "Verdana, Arial, Helvetica, sans-serif"

STYLE = %{
body,td,p { font-family: %fonts%; 
       color: #000040;
}

.attr-rw { font-size: xx-small; color: #444488 }

.title-row { background-color: #CCCCFF;
             color:      #000010;
}

.big-title-font { 
  color: black;
  font-weight: bold;
  font-family: %fonts%; 
  font-size: large; 
  height: 60px;
  padding: 10px 3px 10px 3px;
}

.small-title-font { color: black;
                    font-family: %fonts%;
                    font-size:10; }

.aqua { color: black }

.method-name, .attr-name {
      font-family: font-family: %fonts%; 
      font-weight: bold;
      font-size: small;
      margin-left: 20px;
      color: #000033;
}

.tablesubtitle, .tablesubsubtitle {
   width: 100%;
   margin-top: 1ex;
   margin-bottom: .5ex;
   padding: 5px 0px 5px 3px;
   font-size: large;
   color: black;
   background-color: #CCCCFF;
   border: thin;
}

.name-list {
  margin-left: 5px;
  margin-bottom: 2ex;
  line-height: 105%;
}

.description {
  margin-left: 5px;
  margin-bottom: 2ex;
  line-height: 105%;
  font-size: small;
}

.methodtitle {
  font-size: small;
  font-weight: bold;
  text-decoration: none;
  color: #000033;
  background-color: white; 
}

.srclink {
  font-size: small;
  font-weight: bold;
  text-decoration: none;
  color: #0000DD;
  background-color: white;
}

.paramsig {
   font-size: small;
}

.srcbut { float: right }

}


############################################################################


BODY = %{
<html><head>
  <title>%title%</title>
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%">
  <link rel="stylesheet" href="%style_url%" type="text/css" media="screen" />
  <script type="text/javascript" language="JavaScript">
  <!--
  function popCode(url) {
    parent.frames.source.location = url
  }
  //-->
  </script>
</head>
<body bgcolor="white">

!INCLUDE!  <!-- banner header -->

IF:diagram
<table width="100%"><tr><td align="center">
%diagram%
</td></tr></table>
ENDIF:diagram

IF:description
<div class="description">%description%</div>
ENDIF:description

IF:requires
<table cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Required files</td></tr>
</table><br />
<div class="name-list">
START:requires
HREF:aref:name:
END:requires
ENDIF:requires
</div>

IF:methods
<table cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Methods</td></tr>
</table><br />
<div class="name-list">
START:methods
HREF:aref:name:,
END:methods
</div>
ENDIF:methods


START:sections
    <div id="section">
IF:sectitle
      <h2 class="section-title"><a name="%secsequence%">%sectitle%</a></h2>
IF:seccomment
      <div class="section-comment">
        %seccomment%
      </div>      
ENDIF:seccomment
ENDIF:sectitle

IF:attributes
<table cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Attributes</td></tr>
</table><br />
<table cellspacing="5">
START:attributes
     <tr valign="top">
IF:rw
       <td align="center" class="attr-rw">&nbsp;[%rw%]&nbsp;</td>
ENDIF:rw
IFNOT:rw
       <td></td>
ENDIF:rw
       <td class="attr-name">%name%</td>
       <td>%a_desc%</td>
     </tr>
END:attributes
</table>
ENDIF:attributes

IF:classlist
<table cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Classes and Modules</td></tr>
</table><br />
%classlist%<br />
ENDIF:classlist

  !INCLUDE!  <!-- method descriptions -->

END:sections

</body>
</html>
}

###############################################################################

FILE_PAGE = <<_FILE_PAGE_
<table width="100%">
 <tr class="title-row">
 <td><table width="100%"><tr>
   <td class="big-title-font" colspan="2"><font size="-3"><b>File</b><br /></font>%short_name%</td>
   <td align="right"><table cellspacing="0" cellpadding="2">
         <tr>
           <td  class="small-title-font">Path:</td>
           <td class="small-title-font">%full_path%
IF:cvsurl
				&nbsp;(<a href="%cvsurl%"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
ENDIF:cvsurl
           </td>
         </tr>
         <tr>
           <td class="small-title-font">Modified:</td>
           <td class="small-title-font">%dtm_modified%</td>
         </tr>
        </table>
    </td></tr></table></td>
  </tr>
</table><br />
_FILE_PAGE_

###################################################################

CLASS_PAGE = %{
<table width="100%" border="0" cellspacing="0">
 <tr class="title-row">
 <td class="big-title-font">
   <font size="-3"><b>%classmod%</b><br /></font>%full_name%
 </td>
 <td align="right">
   <table cellspacing="0" cellpadding="2">
     <tr valign="top">
      <td class="small-title-font">In:</td>
      <td class="small-title-font">
START:infiles
HREF:full_path_url:full_path:
IF:cvsurl
&nbsp;(<a href="%cvsurl%"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
ENDIF:cvsurl
END:infiles
      </td>
     </tr>
IF:parent
     <tr>
      <td class="small-title-font">Parent:</td>
      <td class="small-title-font">
IF:par_url
        <a href="%par_url%" class="cyan">
ENDIF:par_url
%parent%
IF:par_url
         </a>
ENDIF:par_url
      </td>
     </tr>
ENDIF:parent
   </table>
  </td>
  </tr>
</table><br />
}

###################################################################

METHOD_LIST = %{
IF:includes
<div class="tablesubsubtitle">Included modules</div><br />
<div class="name-list">
START:includes
    <span class="method-name">HREF:aref:name:</span>
END:includes
</div>
ENDIF:includes

IF:method_list
START:method_list
IF:methods
<table cellpadding=5 width="100%">
<tr><td class="tablesubtitle">%type% %category% methods</td></tr>
</table>
START:methods
<table width="100%" cellspacing="0" cellpadding="5" border="0">
<tr><td class="methodtitle">
<a name="%aref%">
IF:callseq
<b>%callseq%</b>
ENDIF:callseq
IFNOT:callseq
 <b>%name%</b>%params%
ENDIF:callseq
IF:codeurl
<a href="%codeurl%" target="source" class="srclink">src</a>
ENDIF:codeurl
</a></td></tr>
</table>
IF:m_desc
<div class="description">
%m_desc%
</div>
ENDIF:m_desc
IF:aka
<div class="aka">
This method is also aliased as
START:aka
<a href="%aref%">%name%</a>
END:aka
</div>
ENDIF:aka
IF:sourcecode
<pre class="source">
%sourcecode%
</pre>
ENDIF:sourcecode
END:methods
ENDIF:methods
END:method_list
ENDIF:method_list
}

=begin
=end

########################## Source code ##########################

SRC_PAGE = %{
<html>
<head><title>%title%</title>
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
<style type="text/css">
.ruby-comment    { color: green; font-style: italic }
.ruby-constant   { color: #4433aa; font-weight: bold; }
.ruby-identifier { color: #222222;  }
.ruby-ivar       { color: #2233dd; }
.ruby-keyword    { color: #3333FF; font-weight: bold }
.ruby-node       { color: #777777; }
.ruby-operator   { color: #111111;  }
.ruby-regexp     { color: #662222; }
.ruby-value      { color: #662222; font-style: italic }
  .kw { color: #3333FF; font-weight: bold }
  .cmt { color: green; font-style: italic }
  .str { color: #662222; font-style: italic }
  .re  { color: #662222; }
</style>
</head>
<body bgcolor="white">
<pre>%code%</pre>
</body>
</html>
}

########################## Index ################################

FR_INDEX_BODY = %{
!INCLUDE!
}

FILE_INDEX = %{
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
<style>
<!--
  body {
background-color: #ddddff;
     font-family: #{FONTS}; 
       font-size: 11px; 
      font-style: normal;
     line-height: 14px; 
           color: #000040;
  }
div.banner {
  background: #0000aa;
  color:      white;
  padding: 1;
  margin: 0;
  font-size: 90%;
  font-weight: bold;
  line-height: 1.1;
  text-align: center;
  width: 100%;
}
  
-->
</style>
<base target="docwin">
</head>
<body>
<div class="banner">%list_title%</div>
START:entries
<a href="%href%">%name%</a><br />
END:entries
</body></html>
}

CLASS_INDEX = FILE_INDEX
METHOD_INDEX = FILE_INDEX

INDEX = %{
<html>
<head>
  <title>%title%</title>
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%">
</head>

<frameset cols="20%,*">
    <frameset rows="15%,35%,50%">
        <frame src="fr_file_index.html"   title="Files" name="Files">
        <frame src="fr_class_index.html"  name="Classes">
        <frame src="fr_method_index.html" name="Methods">
    </frameset>
IF:inline_source
      <frame  src="%initial_page%" name="docwin">
ENDIF:inline_source
IFNOT:inline_source
    <frameset rows="80%,20%">
      <frame  src="%initial_page%" name="docwin">
      <frame  src="blank.html" name="source">
    </frameset>
ENDIF:inline_source
    <noframes>
          <body bgcolor="white">
            Click <a href="html/index.html">here</a> for a non-frames
            version of this page.
          </body>
    </noframes>
</frameset>

</html>
}

# and a blank page to use as a target
BLANK = %{
<html><body bgcolor="white"></body></html>
}

def write_extra_pages
  template = TemplatePage.new(BLANK)
  File.open("blank.html", "w") { |f| template.write_html_on(f, {}) }
end

end
end
PK     Z\d8f?  f?  %  rdoc/generators/template/html/html.rbnu [        #
# = CSS2 RDoc HTML template
#
# This is a template for RDoc that uses XHTML 1.0 Transitional and dictates a
# bit more of the appearance of the output to cascading stylesheets than the
# default. It was designed for clean inline code display, and uses DHTMl to
# toggle the visbility of each method's source with each click on the '[source]'
# link.
#
# == Authors
#
# * Michael Granger <ged@FaerieMUD.org>
#
# Copyright (c) 2002, 2003 The FaerieMUD Consortium. Some rights reserved.
#
# This work is licensed under the Creative Commons Attribution License. To view
# a copy of this license, visit http://creativecommons.org/licenses/by/1.0/ or
# send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California
# 94305, USA.
#

module RDoc
  module Page

    FONTS = "Verdana,Arial,Helvetica,sans-serif"

STYLE = %{
body {
    font-family: Verdana,Arial,Helvetica,sans-serif;
    font-size:   90%;
    margin: 0;
    margin-left: 40px;
    padding: 0;
    background: white;
}

h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
h1 { font-size: 150%; }
h2,h3,h4 { margin-top: 1em; }

a { background: #eef; color: #039; text-decoration: none; }
a:hover { background: #039; color: #eef; }

/* Override the base stylesheet's Anchor inside a table cell */
td > a {
  background: transparent;
  color: #039;
  text-decoration: none;
}

/* and inside a section title */
.section-title > a {
  background: transparent;
  color: #eee;
  text-decoration: none;
}

/* === Structural elements =================================== */

div#index {
    margin: 0;
    margin-left: -40px;
    padding: 0;
    font-size: 90%;
}


div#index a {
    margin-left: 0.7em;
}

div#index .section-bar {
   margin-left: 0px;
   padding-left: 0.7em;
   background: #ccc;
   font-size: small;
}


div#classHeader, div#fileHeader {
    width: auto;
    color: white;
    padding: 0.5em 1.5em 0.5em 1.5em;
    margin: 0;
    margin-left: -40px;
    border-bottom: 3px solid #006;
}

div#classHeader a, div#fileHeader a {
    background: inherit;
    color: white;
}

div#classHeader td, div#fileHeader td {
    background: inherit;
    color: white;
}


div#fileHeader {
    background: #057;
}

div#classHeader {
    background: #048;
}


.class-name-in-header {
  font-size:  180%;
  font-weight: bold;
}


div#bodyContent {
    padding: 0 1.5em 0 1.5em;
}

div#description {
    padding: 0.5em 1.5em;
    background: #efefef;
    border: 1px dotted #999;
}

div#description h1,h2,h3,h4,h5,h6 {
    color: #125;;
    background: transparent;
}

div#validator-badges {
    text-align: center;
}
div#validator-badges img { border: 0; }

div#copyright {
    color: #333;
    background: #efefef;
    font: 0.75em sans-serif;
    margin-top: 5em;
    margin-bottom: 0;
    padding: 0.5em 2em;
}


/* === Classes =================================== */

table.header-table {
    color: white;
    font-size: small;
}

.type-note {
    font-size: small;
    color: #DEDEDE;
}

.xxsection-bar {
    background: #eee;
    color: #333;
    padding: 3px;
}

.section-bar {
   color: #333;
   border-bottom: 1px solid #999;
    margin-left: -20px;
}


.section-title {
    background: #79a;
    color: #eee;
    padding: 3px;
    margin-top: 2em;
    margin-left: -30px;
    border: 1px solid #999;
}

.top-aligned-row {  vertical-align: top }
.bottom-aligned-row { vertical-align: bottom }

/* --- Context section classes ----------------------- */

.context-row { }
.context-item-name { font-family: monospace; font-weight: bold; color: black; }
.context-item-value { font-size: small; color: #448; }
.context-item-desc { color: #333; padding-left: 2em; }

/* --- Method classes -------------------------- */
.method-detail {
    background: #efefef;
    padding: 0;
    margin-top: 0.5em;
    margin-bottom: 1em;
    border: 1px dotted #ccc;
}
.method-heading {
  color: black;
  background: #ccc;
  border-bottom: 1px solid #666;
  padding: 0.2em 0.5em 0 0.5em;
}
.method-signature { color: black; background: inherit; }
.method-name { font-weight: bold; }
.method-args { font-style: italic; }
.method-description { padding: 0 0.5em 0 0.5em; }

/* --- Source code sections -------------------- */

a.source-toggle { font-size: 90%; }
div.method-source-code {
    background: #262626;
    color: #ffdead;
    margin: 1em;
    padding: 0.5em;
    border: 1px dashed #999;
    overflow: hidden;
}

div.method-source-code pre { color: #ffdead; overflow: hidden; }

/* --- Ruby keyword styles --------------------- */

.standalone-code { background: #221111; color: #ffdead; overflow: hidden; }

.ruby-constant  { color: #7fffd4; background: transparent; }
.ruby-keyword { color: #00ffff; background: transparent; }
.ruby-ivar    { color: #eedd82; background: transparent; }
.ruby-operator  { color: #00ffee; background: transparent; }
.ruby-identifier { color: #ffdead; background: transparent; }
.ruby-node    { color: #ffa07a; background: transparent; }
.ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
.ruby-regexp  { color: #ffa07a; background: transparent; }
.ruby-value   { color: #7fffd4; background: transparent; }
}


#####################################################################
### H E A D E R   T E M P L A T E  
#####################################################################

XHTML_PREAMBLE = %{<?xml version="1.0" encoding="%charset%"?>
<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
}

HEADER = XHTML_PREAMBLE + %{
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>%title%</title>
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
  <meta http-equiv="Content-Script-Type" content="text/javascript" />
  <link rel="stylesheet" href="%style_url%" type="text/css" media="screen" />
  <script type="text/javascript">
  // <![CDATA[

  function popupCode( url ) {
    window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
  }

  function toggleCode( id ) {
    if ( document.getElementById )
      elem = document.getElementById( id );
    else if ( document.all )
      elem = eval( "document.all." + id );
    else
      return false;

    elemStyle = elem.style;
    
    if ( elemStyle.display != "block" ) {
      elemStyle.display = "block"
    } else {
      elemStyle.display = "none"
    }

    return true;
  }
  
  // Make codeblocks hidden by default
  document.writeln( "<style type=\\"text/css\\">div.method-source-code { display: none }</style>" )
  
  // ]]>
  </script>

</head>
<body>
}


#####################################################################
### C O N T E X T   C O N T E N T   T E M P L A T E
#####################################################################

CONTEXT_CONTENT = %{
}


#####################################################################
### F O O T E R   T E M P L A T E
#####################################################################
FOOTER = %{
<div id="validator-badges">
  <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>

</body>
</html>
}


#####################################################################
### F I L E   P A G E   H E A D E R   T E M P L A T E
#####################################################################

FILE_PAGE = %{
  <div id="fileHeader">
    <h1>%short_name%</h1>
    <table class="header-table">
    <tr class="top-aligned-row">
      <td><strong>Path:</strong></td>
      <td>%full_path%
IF:cvsurl
        &nbsp;(<a href="%cvsurl%"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
ENDIF:cvsurl
      </td>
    </tr>
    <tr class="top-aligned-row">
      <td><strong>Last Update:</strong></td>
      <td>%dtm_modified%</td>
    </tr>
    </table>
  </div>
}


#####################################################################
### C L A S S   P A G E   H E A D E R   T E M P L A T E
#####################################################################

CLASS_PAGE = %{
    <div id="classHeader">
        <table class="header-table">
        <tr class="top-aligned-row">
          <td><strong>%classmod%</strong></td>
          <td class="class-name-in-header">%full_name%</td>
        </tr>
        <tr class="top-aligned-row">
            <td><strong>In:</strong></td>
            <td>
START:infiles
IF:full_path_url
                <a href="%full_path_url%">
ENDIF:full_path_url
                %full_path%
IF:full_path_url
                </a>
ENDIF:full_path_url
IF:cvsurl
        &nbsp;(<a href="%cvsurl%"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
ENDIF:cvsurl
        <br />
END:infiles
            </td>
        </tr>

IF:parent
        <tr class="top-aligned-row">
            <td><strong>Parent:</strong></td>
            <td>
IF:par_url
                <a href="%par_url%">
ENDIF:par_url
                %parent%
IF:par_url
               </a>
ENDIF:par_url
            </td>
        </tr>
ENDIF:parent
        </table>
    </div>
}


#####################################################################
### M E T H O D   L I S T   T E M P L A T E
#####################################################################

METHOD_LIST = %{

  <div id="contextContent">
IF:diagram
    <div id="diagram">
      %diagram%
    </div>
ENDIF:diagram

IF:description
    <div id="description">
      %description%
    </div>
ENDIF:description

IF:requires
    <div id="requires-list">
      <h3 class="section-bar">Required files</h3>

      <div class="name-list">
START:requires
      HREF:aref:name:&nbsp;&nbsp;
END:requires
      </div>
    </div>
ENDIF:requires

IF:toc
    <div id="contents-list">
      <h3 class="section-bar">Contents</h3>
      <ul>
START:toc
      <li><a href="#%href%">%secname%</a></li>
END:toc
     </ul>
ENDIF:toc
   </div>

IF:methods
    <div id="method-list">
      <h3 class="section-bar">Methods</h3>

      <div class="name-list">
START:methods
      HREF:aref:name:&nbsp;&nbsp;
END:methods
      </div>
    </div>
ENDIF:methods

  </div>


    <!-- if includes -->
IF:includes
    <div id="includes">
      <h3 class="section-bar">Included Modules</h3>

      <div id="includes-list">
START:includes
        <span class="include-name">HREF:aref:name:</span>
END:includes
      </div>
    </div>
ENDIF:includes

START:sections
    <div id="section">
IF:sectitle
      <h2 class="section-title"><a name="%secsequence%">%sectitle%</a></h2>
IF:seccomment
      <div class="section-comment">
        %seccomment%
      </div>      
ENDIF:seccomment
ENDIF:sectitle

IF:classlist
    <div id="class-list">
      <h3 class="section-bar">Classes and Modules</h3>

      %classlist%
    </div>
ENDIF:classlist

IF:constants
    <div id="constants-list">
      <h3 class="section-bar">Constants</h3>

      <div class="name-list">
        <table summary="Constants">
START:constants
        <tr class="top-aligned-row context-row">
          <td class="context-item-name">%name%</td>
          <td>=</td>
          <td class="context-item-value">%value%</td>
IF:desc
          <td width="3em">&nbsp;</td>
          <td class="context-item-desc">%desc%</td>
ENDIF:desc
        </tr>
END:constants
        </table>
      </div>
    </div>
ENDIF:constants

IF:aliases
    <div id="aliases-list">
      <h3 class="section-bar">External Aliases</h3>

      <div class="name-list">
                        <table summary="aliases">
START:aliases
        <tr class="top-aligned-row context-row">
          <td class="context-item-name">%old_name%</td>
          <td>-&gt;</td>
          <td class="context-item-value">%new_name%</td>
        </tr>
IF:desc
      <tr class="top-aligned-row context-row">
        <td>&nbsp;</td>
        <td colspan="2" class="context-item-desc">%desc%</td>
      </tr>
ENDIF:desc
END:aliases
                        </table>
      </div>
    </div>
ENDIF:aliases


IF:attributes
    <div id="attribute-list">
      <h3 class="section-bar">Attributes</h3>

      <div class="name-list">
        <table>
START:attributes
        <tr class="top-aligned-row context-row">
          <td class="context-item-name">%name%</td>
IF:rw
          <td class="context-item-value">&nbsp;[%rw%]&nbsp;</td>
ENDIF:rw
IFNOT:rw
          <td class="context-item-value">&nbsp;&nbsp;</td>
ENDIF:rw
          <td class="context-item-desc">%a_desc%</td>
        </tr>
END:attributes
        </table>
      </div>
    </div>
ENDIF:attributes
      


    <!-- if method_list -->
IF:method_list
    <div id="methods">
START:method_list
IF:methods
      <h3 class="section-bar">%type% %category% methods</h3>

START:methods
      <div id="method-%aref%" class="method-detail">
        <a name="%aref%"></a>

        <div class="method-heading">
IF:codeurl
          <a href="%codeurl%" target="Code" class="method-signature"
            onclick="popupCode('%codeurl%');return false;">
ENDIF:codeurl
IF:sourcecode
          <a href="#%aref%" class="method-signature">
ENDIF:sourcecode
IF:callseq
          <span class="method-name">%callseq%</span>
ENDIF:callseq
IFNOT:callseq
          <span class="method-name">%name%</span><span class="method-args">%params%</span>
ENDIF:callseq
IF:codeurl
          </a>
ENDIF:codeurl
IF:sourcecode
          </a>
ENDIF:sourcecode
        </div>
      
        <div class="method-description">
IF:m_desc
          %m_desc%
ENDIF:m_desc
IF:sourcecode
          <p><a class="source-toggle" href="#"
            onclick="toggleCode('%aref%-source');return false;">[Source]</a></p>
          <div class="method-source-code" id="%aref%-source">
<pre>
%sourcecode%
</pre>
          </div>
ENDIF:sourcecode
        </div>
      </div>

END:methods
ENDIF:methods
END:method_list

    </div>
ENDIF:method_list
END:sections
}


#####################################################################
### B O D Y   T E M P L A T E
#####################################################################

BODY = HEADER + %{

!INCLUDE!  <!-- banner header -->

  <div id="bodyContent">

} +  METHOD_LIST + %{

  </div>

} + FOOTER



#####################################################################
### S O U R C E   C O D E   T E M P L A T E
#####################################################################

SRC_PAGE = XHTML_PREAMBLE + %{
<html>
<head>
  <title>%title%</title>
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
  <link rel="stylesheet" href="%style_url%" type="text/css" media="screen" />
</head>
<body class="standalone-code">
  <pre>%code%</pre>
</body>
</html>
}


#####################################################################
### I N D E X   F I L E   T E M P L A T E S
#####################################################################

FR_INDEX_BODY = %{
!INCLUDE!
}

FILE_INDEX = XHTML_PREAMBLE + %{
<!--

    %list_title%

  -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>%list_title%</title>
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
  <link rel="stylesheet" href="%style_url%" type="text/css" />
  <base target="docwin" />
</head>
<body>
<div id="index">
  <h1 class="section-bar">%list_title%</h1>
  <div id="index-entries">
START:entries
    <a href="%href%">%name%</a><br />
END:entries
  </div>
</div>
</body>
</html>
}

CLASS_INDEX = FILE_INDEX
METHOD_INDEX = FILE_INDEX

INDEX = %{<?xml version="1.0" encoding="%charset%"?>
<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

<!--

    %title%

  -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>%title%</title>
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
</head>
<frameset rows="20%, 80%">
    <frameset cols="25%,35%,45%">
        <frame src="fr_file_index.html"   title="Files" name="Files" />
        <frame src="fr_class_index.html"  name="Classes" />
        <frame src="fr_method_index.html" name="Methods" />
    </frameset>
    <frame src="%initial_page%" name="docwin" />
</frameset>
</html>
}



  end # module Page
end # class RDoc

require 'rdoc/generators/template/html/one_page_html'
PK     Z\%`C  C  )  rdoc/generators/template/html/old_html.rbnu [        module RDoc

# This is how you define the HTML that RDoc generates. Simply create
# a file in rdoc/generators/html_templates that creates the
# module RDoc::Page and populate it as described below. Then invoke
# rdoc using the --template <name of your file> option, and
# your template will be used.
#
# The constants defining pages use a simple templating system:
#
# * The templating system is passed a hash. Keys in the hash correspond
#   to tags on this page. The tag %abc% is looked up in the hash,
#   and is replaced by the corresponding hash value.
#
# * Some tags are optional. You can detect this using IF/ENDIF
#
#      IF: title
#      The value of title is %title%
#      ENDIF: title
#
# * Some entries in the hash have values that are arrays, where each
#   entry in the array is itself a hash. These are used to generate
#   lists using the START: construct. For example, given a hash
#   containing
# 
#      { 'people' => [ { 'name' => 'Fred', 'age' => '12' },
#                      { 'name' => 'Mary', 'age' => '21' } ]
#
#   You could generate a simple table using
#
#      <table>
#      START:people
#        <tr><td>%name%<td>%age%</tr>
#      END:people
#      </table>
#
#   These lists can be nested to an arbitrary depth
#
# * the construct HREF:url:name: generates <a href="%url%">%name%</a>
#   if +url+ is defined in the hash, or %name% otherwise.
#
#
# Your file must contain the following constants
#
# [*FONTS*]  a list of fonts to be used
# [*STYLE*]  a CSS section (without the <style> or comments). This is
#            used to generate a style.css file
#
# [*BODY*] 
#   The main body of all non-index RDoc pages. BODY will contain
#   two !INCLUDE!s. The first is used to include a document-type
#   specific header (FILE_PAGE or CLASS_PAGE). The second include
#   is for the method list (METHOD_LIST). THe body is passed:
#
#   %title%::
#       the page's title
#
#   %style_url%::
#       the url of a style sheet for this page
#
#   %diagram%::
#       the optional URL of a diagram for this page
#
#   %description%::
#       a (potentially multi-paragraph) string containing the
#       description for th file/class/module.
#
#   %requires%::
#       an optional list of %aref%/%name% pairs, one for each module
#       required by this file.
#
#   %methods%::
#       an optional list of %aref%/%name%, one for each method
#       documented on this page. This is intended to be an index.
#
#   %attributes%::  
#       An optional list. For each attribute it contains:
#       %name%::   the attribute name
#       %rw%::     r/o, w/o, or r/w
#       %a_desc%:: description of the attribute
#
#   %classlist%:: 
#       An optional string containing an already-formatted list of
#       classes and modules documented in this file
#
#   For FILE_PAGE entries, the body will be passed
#
#   %short_name%::  
#       The name of the file
#
#   %full_path%::
#       The full path to the file
#
#   %dtm_modified%::
#       The date/time the file was last changed
#
#   For class and module pages, the body will be passed
#
#   %classmod%::
#       The name of the class or module
#
#   %files%::
#       A list. For each file this class is defined in, it contains:
#       %full_path_url%:: an (optional) URL of the RDoc page
#                         for this file
#       %full_path%::     the name of the file
#
#   %par_url%::
#       The (optional) URL of the RDoc page documenting this class's
#       parent class
#
#   %parent%::
#       The name of this class's parent.
#
#   For both files and classes, the body is passed the following information
#   on includes and methods:
#
#   %includes%::    
#       Optional list of included modules. For each, it receives
#       %aref%:: optional URL to RDoc page for the module
#       %name%:: the name of the module
#
#   %method_list%::
#       Optional list of methods of a particular class and category.
#
#   Each method list entry contains:
#
#   %type%::        public/private/protected
#   %category%::    instance/class
#   %methods%::     a list of method descriptions
#
#   Each method description contains:
#
#   %aref%::        a target aref, used when referencing this method
#                   description. You should code this as <a name="%aref%">
#   %codeurl%::     the optional URL to the page containing this method's
#                   source code.
#   %name%::        the method's name
#   %params%::      the method's parameters
#   %callseq%::     a full calling sequence
#   %m_desc%::      the (potentially multi-paragraph) description of
#                   this method.
#
# [*CLASS_PAGE*]
#         Header for pages documenting classes and modules. See
#         BODY above for the available parameters.
#
# [*FILE_PAGE*]
#         Header for pages documenting files. See
#         BODY above for the available parameters.
#
# [*METHOD_LIST*]
#         Controls the display of the listing of methods. See BODY for
#         parameters.
#
# [*INDEX*]
#         The top-level index page. For a browser-like environment
#         define a frame set that includes the file, class, and 
#         method indices. Passed
#         %title%:: title of page
#         %initial_page% :: url of initial page to display
#
# [*CLASS_INDEX*]
#         Individual files for the three indexes. Passed:
#         %index_url%:: URL of main index page
#         %entries%::   List of
#                       %name%:: name of an index entry
#                       %href%:: url of corresponding page
# [*METHOD_INDEX*]
#         Same as CLASS_INDEX for methods
#
# [*FILE_INDEX*]
#         Same as CLASS_INDEX for methods
#
# [*FR_INDEX_BODY*]
#         A wrapper around CLASS_INDEX, METHOD_INDEX, and FILE_INDEX.
#         If those index strings contain the complete HTML for the
#         output, then FR_INDEX_BODY can simply be !INCLUDE!
#
# [*SRC_PAGE*]
#         Page used to display source code. Passed %title% and %code%,
#         the latter being a multi-line string of code.

module Page

FONTS = "Verdana, Arial, Helvetica, sans-serif"

STYLE = %{
body,td,p { font-family: %fonts%; 
       color: #000040;
}

.attr-rw { font-size: x-small; color: #444488 }

.title-row { background: #0000aa;
             color:      #eeeeff;
}

.big-title-font { color: white;
                  font-family: %fonts%;
                  font-size: large; 
                  height: 50px}

.small-title-font { color: aqua;
                    font-family: %fonts%;
                    font-size: xx-small; }

.aqua { color: aqua }

.method-name, attr-name {
      font-family: monospace; font-weight: bold;
}

.tablesubtitle, .tablesubsubtitle {
   width: 100%;
   margin-top: 1ex;
   margin-bottom: .5ex;
   padding: 5px 0px 5px 20px;
   font-size: large;
   color: aqua;
   background: #3333cc;
}

.name-list {
  font-family: monospace;
  margin-left: 40px;
  margin-bottom: 2ex;
  line-height: 140%;
}

.description {
  margin-left: 40px;
  margin-top: -2ex;
  margin-bottom: 2ex;
}

.description p {
  line-height: 140%;
}

.aka {
  margin-left: 40px;
  margin-bottom: 2ex;
  line-height: 100%;
  font-size:   small;
  color:       #808080;
}

.methodtitle {
  font-size: medium;
  text-decoration: none;
  color: #0000AA;
  background: white; 
}

.paramsig {
   font-size: small;
}

.srcbut { float: right }

pre { font-size: 1.2em; }
tt  { font-size: 1.2em; }

pre.source {
  border-style: groove;
  background-color: #ddddff;
  margin-left:  40px;
  padding: 1em 0em 1em 2em;
}

.classlist {
  margin-left: 40px;
  margin-bottom: 2ex;
  line-height: 140%;
}

li {
  display:    list-item;
  margin-top: .6em;
}

.ruby-comment    { color: green; font-style: italic }
.ruby-constant   { color: #4433aa; font-weight: bold; }
.ruby-identifier { color: #222222;  }
.ruby-ivar       { color: #2233dd; }
.ruby-keyword    { color: #3333FF; font-weight: bold }
.ruby-node       { color: #777777; }
.ruby-operator   { color: #111111;  }
.ruby-regexp     { color: #662222; }
.ruby-value      { color: #662222; font-style: italic }

}


############################################################################


HEADER = %{
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>%title%</title>
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
  <link rel=StyleSheet href="%style_url%" type="text/css" media="screen" />
  <script type="text/javascript" language="JavaScript">
  <!--
  function popCode(url) {
    window.open(url, "Code", 
          "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
  }
  //-->
  </script>
</head>
}


###################################################################

METHOD_LIST = %{
IF:includes
<table summary="Included modules" cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Included modules</td></tr>
</table>
<div class="name-list">
START:includes
    <span class="method-name">HREF:aref:name:</span>
END:includes
</div>
ENDIF:includes

IF:method_list
START:method_list
IF:methods
<table summary="Method list" cellpadding="5" width="100%">
<tr><td class="tablesubtitle">%type% %category% methods</td></tr>
</table>
START:methods
<table summary="method"  width="100%" cellspacing="0" cellpadding="5" border="0">
<tr><td class="methodtitle">
<a name="%aref%"></a>
IF:codeurl
<a href="%codeurl%" target="Code" class="methodtitle"
 onClick="popCode('%codeurl%');return false;">
ENDIF:codeurl
IF:callseq
<b>%callseq%</b>
ENDIF:callseq
IFNOT:callseq
<b>%name%</b>%params%
ENDIF:callseq
IF:codeurl
</a>
ENDIF:codeurl
</td></tr>
</table>
IF:m_desc
<div class="description">
%m_desc%
</div>
ENDIF:m_desc
IF:aka
<div class="aka">
This method is also aliased as
START:aka
<a href="%aref%">%name%</a>
END:aka
</div>
ENDIF:aka
IF:sourcecode
<pre class="source">
%sourcecode%
</pre>
ENDIF:sourcecode
END:methods
ENDIF:methods
END:method_list
ENDIF:method_list
}

###################################################################

CONTEXT_CONTENT = %{
IF:diagram
<table summary="Diagram of classes and modules" width="100%">
<tr><td align="center">
%diagram%
</td></tr></table>
ENDIF:diagram


IF:description
<div class="description">%description%</div>
ENDIF:description

IF:requires
<table summary="Requires" cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Required files</td></tr>
</table>
<div class="name-list">
START:requires
HREF:aref:name:&nbsp; &nbsp;
END:requires
</div>
ENDIF:requires

IF:methods
<table summary="Methods" cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Methods</td></tr>
</table>
<div class="name-list">
START:methods
HREF:aref:name:&nbsp; &nbsp;
END:methods
</div>
ENDIF:methods

IF:constants
<table summary="Constants" cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Constants</td></tr>
</table>
<table cellpadding="5">
START:constants
<tr valign="top"><td>%name%</td><td>=</td><td>%value%</td></tr>
IF:desc
<tr><td></td><td></td><td>%desc%</td></tr>
ENDIF:desc
END:constants
</table>
ENDIF:constants

IF:aliases
<table summary="Aliases" cellpadding="5" width="100%">
<tr><td class="tablesubtitle">External Aliases</td></tr>
</table>
<div class="name-list">
START:aliases
%old_name% -> %new_name%<br />
END:aliases
</div>
ENDIF:aliases

IF:attributes
<table summary="Attributes" cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Attributes</td></tr>
</table>
<table summary="Attribute details" cellspacing="5">
START:attributes
     <tr valign="top">
       <td class="attr-name">%name%</td>
IF:rw
       <td align="center" class="attr-rw">&nbsp;[%rw%]&nbsp;</td>
ENDIF:rw
IFNOT:rw
       <td></td>
ENDIF:rw
       <td>%a_desc%</td>
     </tr>
END:attributes
</table>
ENDIF:attributes

IF:classlist
<table summary="List of classes" cellpadding="5" width="100%">
<tr><td class="tablesubtitle">Classes and Modules</td></tr>
</table>
<div class="classlist">
%classlist%
</div>
ENDIF:classlist
}

###############################################################################

BODY = HEADER + %{
<body bgcolor="white">
!INCLUDE!  <!-- banner header -->
} +
CONTEXT_CONTENT + METHOD_LIST +
%{
</body>
</html>
}


###############################################################################

FILE_PAGE = <<_FILE_PAGE_
<table summary="Information on file" width="100%">
 <tr class="title-row">
 <td><table summary="layout" width="100%"><tr>
   <td class="big-title-font" colspan="2">%short_name%</td>
   <td align="right"><table summary="layout" cellspacing="0" cellpadding="2">
         <tr>
           <td  class="small-title-font">Path:</td>
           <td class="small-title-font">%full_path%
IF:cvsurl
				&nbsp;(<a href="%cvsurl%"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
ENDIF:cvsurl
           </td>
         </tr>
         <tr>
           <td class="small-title-font">Modified:</td>
           <td class="small-title-font">%dtm_modified%</td>
         </tr>
        </table>
    </td></tr></table></td>
  </tr>
</table>
_FILE_PAGE_

###################################################################

CLASS_PAGE = %{
<table summary="Information on class" width="100%" border="0" cellspacing="0">
 <tr class="title-row">
 <td class="big-title-font">
   <sup><font color="aqua">%classmod%</font></sup> %full_name%
 </td>
 <td align="right">
   <table summary="layout" cellspacing="0" cellpadding="2">
     <tr valign="top">
      <td class="small-title-font">In:</td>
      <td class="small-title-font">
START:infiles
IF:full_path_url
        <a href="%full_path_url%" class="aqua">
ENDIF:full_path_url
%full_path%
IF:full_path_url
         </a>
ENDIF:full_path_url
IF:cvsurl
         &nbsp;(<a href="%cvsurl%"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
ENDIF:cvsurl
<br />
END:infiles
      </td>
     </tr>
IF:parent
     <tr>
      <td class="small-title-font">Parent:</td>
      <td class="small-title-font">
IF:par_url
        <a href="%par_url%" class="aqua">
ENDIF:par_url
%parent%
IF:par_url
         </a>
ENDIF:par_url
      </td>
     </tr>
ENDIF:parent
   </table>
  </td>
  </tr>
</table>
}

=begin
=end

########################## Source code ##########################

SRC_PAGE = %{
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
<title>%title%</title>
<link rel="stylesheet" href="%style_url%" type="text/css" media="screen" />
</head>
<body bgcolor="white">
<pre>%code%</pre>
</body>
</html>
}

########################## Index ################################

FR_INDEX_BODY = %{
!INCLUDE!
}

FILE_INDEX = %{
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
<title>%list_title%</title>
<style type="text/css">
<!--
  body {
background-color: #ddddff;
     font-family: #{FONTS}; 
       font-size: 11px; 
      font-style: normal;
     line-height: 14px; 
           color: #000040;
  }
div.banner {
  background: #0000aa;
  color:      white;
  padding: 1;
  margin: 0;
  font-size: 90%;
  font-weight: bold;
  line-height: 1.1;
  text-align: center;
  width: 100%;
}

A.xx { color: white; font-weight: bold; }
-->
</style>
<base target="docwin">
</head>
<body>
<div class="banner"><a href="%index_url%" class="xx">%list_title%</a></div>
START:entries
<a href="%href%">%name%</a><br />
END:entries
</body></html>
}

CLASS_INDEX = FILE_INDEX
METHOD_INDEX = FILE_INDEX

INDEX = %{
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
<title>%title%</title></head>

<frameset rows="20%, 80%">
    <frameset cols="25%,35%,45%">
        <frame src="fr_file_index.html"   title="Files" name="Files">
        <frame src="fr_class_index.html"  name="Classes">
        <frame src="fr_method_index.html" name="Methods">
    </frameset>
    <frame  src="%initial_page%" name="docwin">
    <noframes>
          <body bgcolor="white">
            Sorry, RDoc currently only generates HTML using frames.
          </body>
    </noframes>
</frameset>

</html>
}

######################################################################
#
# The following is used for the -1 option
#

CONTENTS_XML = %{
IF:description
%description%
ENDIF:description

IF:requires
<h4>Requires:</h4>
<ul>
START:requires
IF:aref
<li><a href="%aref%">%name%</a></li>
ENDIF:aref
IFNOT:aref
<li>%name%</li>
ENDIF:aref 
END:requires
</ul>
ENDIF:requires

IF:attributes
<h4>Attributes</h4>
<table>
START:attributes
<tr><td>%name%</td><td>%rw%</td><td>%a_desc%</td></tr>
END:attributes
</table>
ENDIF:attributes

IF:includes
<h4>Includes</h4>
<ul>
START:includes
IF:aref
<li><a href="%aref%">%name%</a></li>
ENDIF:aref
IFNOT:aref
<li>%name%</li>
ENDIF:aref 
END:includes
</ul>
ENDIF:includes

IF:method_list
<h3>Methods</h3>
START:method_list
IF:methods
START:methods
<h4>%type% %category% method: <a name="%aref%">%name%%params%</a></h4>

IF:m_desc
%m_desc%
ENDIF:m_desc

IF:sourcecode
<blockquote><pre>
%sourcecode%
</pre></blockquote>
ENDIF:sourcecode
END:methods
ENDIF:methods
END:method_list
ENDIF:method_list
}


end
end

require 'rdoc/generators/template/html/one_page_html'
PK     Z\.S͇    .  rdoc/generators/template/html/one_page_html.rbnu [        module RDoc
module Page
######################################################################
#
# The following is used for the -1 option
#

CONTENTS_XML = %{
IF:description
%description%
ENDIF:description

IF:requires
<h4>Requires:</h4>
<ul>
START:requires
IF:aref
<li><a href="%aref%">%name%</a></li>
ENDIF:aref
IFNOT:aref
<li>%name%</li>
ENDIF:aref 
END:requires
</ul>
ENDIF:requires

IF:attributes
<h4>Attributes</h4>
<table>
START:attributes
<tr><td>%name%</td><td>%rw%</td><td>%a_desc%</td></tr>
END:attributes
</table>
ENDIF:attributes

IF:includes
<h4>Includes</h4>
<ul>
START:includes
IF:aref
<li><a href="%aref%">%name%</a></li>
ENDIF:aref
IFNOT:aref
<li>%name%</li>
ENDIF:aref 
END:includes
</ul>
ENDIF:includes

IF:method_list
<h3>Methods</h3>
START:method_list
IF:methods
START:methods
<h4>%type% %category% method: 
IF:callseq
<a name="%aref%">%callseq%</a>
ENDIF:callseq
IFNOT:callseq
<a name="%aref%">%name%%params%</a></h4>
ENDIF:callseq

IF:m_desc
%m_desc%
ENDIF:m_desc

IF:sourcecode
<blockquote><pre>
%sourcecode%
</pre></blockquote>
ENDIF:sourcecode
END:methods
ENDIF:methods
END:method_list
ENDIF:method_list
}

########################################################################

ONE_PAGE = %{
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <title>%title%</title>
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
</head>
<body>
START:files
<h2>File: %short_name%</h2>
<table>
  <tr><td>Path:</td><td>%full_path%</td></tr>
  <tr><td>Modified:</td><td>%dtm_modified%</td></tr>
</table>
} + CONTENTS_XML + %{
END:files

IF:classes
<h2>Classes</h2>
START:classes
IF:parent
<h3>%classmod% %full_name% &lt; HREF:par_url:parent:</h3>
ENDIF:parent
IFNOT:parent
<h3>%classmod% %full_name%</h3>
ENDIF:parent

IF:infiles
(in files
START:infiles
HREF:full_path_url:full_path:
END:infiles
)
ENDIF:infiles
} + CONTENTS_XML + %{
END:classes
ENDIF:classes
</body>
</html>
}

end
end
PK     Z\^.s       rdoc/generators/xml_generator.rbnu [        
require 'ftools'

require 'rdoc/options'
require 'rdoc/markup/simple_markup'
require 'rdoc/markup/simple_markup/to_html'
require 'rdoc/generators/html_generator'

module Generators

  # Generate XML output as one big file

  class XMLGenerator < HTMLGenerator

    # Standard generator factory
    def XMLGenerator.for(options)
      XMLGenerator.new(options)
    end

    
    def initialize(*args)
      super
    end

    ##
    # Build the initial indices and output objects
    # based on an array of TopLevel objects containing
    # the extracted information. 

    def generate(info)
      @info       = info
      @files      = []
      @classes    = []
      @hyperlinks = {}

      build_indices
      generate_xml
    end


    ##
    # Generate:
    #
    # * a list of HtmlFile objects for each TopLevel object.
    # * a list of HtmlClass objects for each first level
    #   class or module in the TopLevel objects
    # * a complete list of all hyperlinkable terms (file,
    #   class, module, and method names)

    def build_indices

      @info.each do |toplevel|
        @files << HtmlFile.new(toplevel, @options, FILE_DIR)
      end

      RDoc::TopLevel.all_classes_and_modules.each do |cls|
        build_class_list(cls, @files[0], CLASS_DIR)
      end
    end

    def build_class_list(from, html_file, class_dir)
      @classes << HtmlClass.new(from, html_file, class_dir, @options)
      from.each_classmodule do |mod|
        build_class_list(mod, html_file, class_dir)
      end
    end

    ##
    # Generate all the HTML. For the one-file case, we generate
    # all the information in to one big hash
    #
    def generate_xml
      values = { 
        'charset' => @options.charset,
        'files'   => gen_into(@files),
        'classes' => gen_into(@classes)
      }
      
      # this method is defined in the template file
      write_extra_pages if defined? write_extra_pages

      template = TemplatePage.new(RDoc::Page::ONE_PAGE)

      if @options.op_name
        opfile = File.open(@options.op_name, "w")
      else
        opfile = $stdout
      end
      template.write_html_on(opfile, values)
    end

    def gen_into(list)
      res = []
      list.each do |item|
        res << item.value_hash
      end
      res
    end

    def gen_file_index
      gen_an_index(@files, 'Files')
    end

    def gen_class_index
      gen_an_index(@classes, 'Classes')
    end

    def gen_method_index
      gen_an_index(HtmlMethod.all_methods, 'Methods')
    end

    
    def gen_an_index(collection, title)
      res = []
      collection.sort.each do |f|
        if f.document_self
          res << { "href" => f.path, "name" => f.index_name }
        end
      end

      return {
        "entries" => res,
        'list_title' => title,
        'index_url'  => main_url,
      }
    end

  end

end
PK     Z\\      rdoc/usage.rbnu [        # = Synopsis
#
# This library allows command-line tools to encapsulate their usage
# as a comment at the top of the main file. Calling <tt>RDoc::usage</tt>
# then displays some or all of that comment, and optionally exits
# the program with an exit status. We always look for the comment
# in the main program file, so it is safe to call this method
# from anywhere in the executing program.
#
# = Usage
#
#   RDoc::usage( [ exit_status ], [ section, ...])
#   RDoc::usage_no_exit( [ section, ...])
#
# where:
#
# exit_status::
#     the integer exit code (default zero). RDoc::usage will exit
#     the calling program with this status.
#
# section::
#     an optional list of section names. If specified, only the
#     sections with the given names as headings will be output.
#     For example, this section is named 'Usage', and the next
#     section is named 'Examples'. The section names are case
#     insensitive.
#
# = Examples
#
#    # Comment block describing usage
#    # with (optional) section headings
#    # . . .
#
#    require 'rdoc/usage'
#
#    # Display all usage and exit with a status of 0
#
#    RDoc::usage
#
#    # Display all usage and exit with a status of 99
#
#    RDoc::usage(99)
#
#    # Display usage in the 'Summary' section only, then
#    # exit with a status of 99
#
#    RDoc::usage(99, 'Summary')
#
#    # Display information in the Author and Copyright
#    # sections, then exit 0.
#    
#    RDoc::usage('Author', 'Copyright')
#
#    # Display information in the Author and Copyright
#    # sections, but don't exit
#  
#    RDoc::usage_no_exit('Author', 'Copyright')
#
# = Author
#
# Dave Thomas, The Pragmatic Programmers, LLC
#
# = Copyright
#
# Copyright (c) 2004 Dave Thomas.
# Licensed under the same terms as Ruby
#

require 'rdoc/markup/simple_markup'
require 'rdoc/markup/simple_markup/to_flow'
require 'rdoc/ri/ri_formatter'
require 'rdoc/ri/ri_options'

module RDoc

  # Display usage information from the comment at the top of
  # the file. String arguments identify specific sections of the
  # comment to display. An optional integer first argument
  # specifies the exit status  (defaults to 0)

  def RDoc.usage(*args)
    exit_code = 0

    if args.size > 0
      status = args[0]
      if status.respond_to?(:to_int)
        exit_code = status.to_int
        args.shift
      end
    end

    # display the usage and exit with the given code
    usage_no_exit(*args)
    exit(exit_code)
  end

  # Display usage
  def RDoc.usage_no_exit(*args)
    main_program_file = caller[-1].sub(/:\d+$/, '')
    comment = File.open(main_program_file) do |file|
      find_comment(file)
    end

    comment = comment.gsub(/^\s*#/, '')

    markup = SM::SimpleMarkup.new
    flow_convertor = SM::ToFlow.new
    
    flow = markup.convert(comment, flow_convertor)

    format = "plain"

    unless args.empty?
      flow = extract_sections(flow, args)
    end

    options = RI::Options.instance
    if args = ENV["RI"]
      options.parse(args.split)
    end
    formatter = options.formatter.new(options, "")
    formatter.display_flow(flow)
  end

  ######################################################################

  private

  # Find the first comment in the file (that isn't a shebang line)
  # If the file doesn't start with a comment, report the fact
  # and return empty string

  def RDoc.gets(file)
    if (line = file.gets) && (line =~ /^#!/) # shebang
      throw :exit, find_comment(file)
    else
      line
    end
  end

  def RDoc.find_comment(file)
    catch(:exit) do
      # skip leading blank lines
      0 while (line = gets(file)) && (line =~ /^\s*$/)

      comment = []
      while line && line =~ /^\s*#/
        comment << line
        line = gets(file)
      end

      0 while line && (line = gets(file))
      return no_comment if comment.empty?
      return comment.join
    end
  end


  #####
  # Given an array of flow items and an array of section names, extract those
  # sections from the flow which have headings corresponding to
  # a section name in the list. Return them in the order
  # of names in the +sections+ array.

  def RDoc.extract_sections(flow, sections)
    result = []
    sections.each do |name|
      name = name.downcase
      copy_upto_level = nil

      flow.each do |item|
        case item
        when SM::Flow::H
          if copy_upto_level && item.level >= copy_upto_level
            copy_upto_level = nil
          else
            if item.text.downcase == name
              result << item
              copy_upto_level = item.level
            end
          end
        else
          if copy_upto_level
            result << item
          end
        end
      end
    end
    if result.empty?
      puts "Note to developer: requested section(s) [#{sections.join(', ')}] " +
           "not found"
      result = flow
    end
    result
  end

  #####
  # Report the fact that no doc comment count be found
  def RDoc.no_comment
    $stderr.puts "No usage information available for this program"
    ""
  end
end


if $0 == __FILE__

  RDoc::usage(*ARGV)

end
PK     Z\Lف/  /    rdoc/diagram.rbnu [        # A wonderful hack by to draw package diagrams using the dot package.
# Originally written by  Jah, team Enticla.
#
# You must have the V1.7 or later in your path
# http://www.research.att.com/sw/tools/graphviz/

require "rdoc/dot/dot"
require 'rdoc/options'

module RDoc

  # Draw a set of diagrams representing the modules and classes in the
  # system. We draw one diagram for each file, and one for each toplevel
  # class or module. This means there will be overlap. However, it also
  # means that you'll get better context for objects.
  #
  # To use, simply
  #
  #   d = Diagram.new(info)   # pass in collection of top level infos
  #   d.draw
  #
  # The results will be written to the +dot+ subdirectory. The process
  # also sets the +diagram+ attribute in each object it graphs to
  # the name of the file containing the image. This can be used
  # by output generators to insert images.

  class Diagram

    FONT = "Arial"

    DOT_PATH = "dot"

    # Pass in the set of top level objects. The method also creates
    # the subdirectory to hold the images

    def initialize(info, options)
      @info = info
      @options = options
      @counter = 0
      File.makedirs(DOT_PATH)
      @diagram_cache = {}
    end

    # Draw the diagrams. We traverse the files, drawing a diagram for
    # each. We also traverse each top-level class and module in that
    # file drawing a diagram for these too. 

    def draw
      unless @options.quiet
        $stderr.print "Diagrams: "
        $stderr.flush
      end

      @info.each_with_index do |i, file_count|
        @done_modules = {}
        @local_names = find_names(i)
        @global_names = []
        @global_graph = graph = DOT::DOTDigraph.new('name' => 'TopLevel',
                                    'fontname' => FONT,
                                    'fontsize' => '8',
                                    'bgcolor'  => 'lightcyan1',
                                    'compound' => 'true')
        
        # it's a little hack %) i'm too lazy to create a separate class
        # for default node
        graph << DOT::DOTNode.new('name' => 'node',
                                  'fontname' => FONT,
                                  'color' => 'black',
                                  'fontsize' => 8)
        
        i.modules.each do |mod|
          draw_module(mod, graph, true, i.file_relative_name)
        end
        add_classes(i, graph, i.file_relative_name)

        i.diagram = convert_to_png("f_#{file_count}", graph)
        
        # now go through and document each top level class and
        # module independently
        i.modules.each_with_index do |mod, count|
          @done_modules = {}
          @local_names = find_names(mod)
          @global_names = []

          @global_graph = graph = DOT::DOTDigraph.new('name' => 'TopLevel',
                                      'fontname' => FONT,
                                      'fontsize' => '8',
                                      'bgcolor'  => 'lightcyan1',
                                      'compound' => 'true')

          graph << DOT::DOTNode.new('name' => 'node',
                                    'fontname' => FONT,
                                    'color' => 'black',
                                    'fontsize' => 8)
          draw_module(mod, graph, true)
          mod.diagram = convert_to_png("m_#{file_count}_#{count}", 
                                       graph) 
        end
      end
      $stderr.puts unless @options.quiet
    end

    #######
    private
    #######

    def find_names(mod)
      return [mod.full_name] + mod.classes.collect{|cl| cl.full_name} +
        mod.modules.collect{|m| find_names(m)}.flatten
    end

    def find_full_name(name, mod)
      full_name = name.dup
      return full_name if @local_names.include?(full_name)
      mod_path = mod.full_name.split('::')[0..-2]
      unless mod_path.nil?
        until mod_path.empty?
          full_name = mod_path.pop + '::' + full_name
          return full_name if @local_names.include?(full_name)
        end
      end
      return name
    end

    def draw_module(mod, graph, toplevel = false, file = nil)
      return if  @done_modules[mod.full_name] and not toplevel

      @counter += 1
      url = mod.http_url("classes")
      m = DOT::DOTSubgraph.new('name' => "cluster_#{mod.full_name.gsub( /:/,'_' )}",
                               'label' => mod.name,
                               'fontname' => FONT,
                               'color' => 'blue', 
                               'style' => 'filled', 
                               'URL'   => %{"#{url}"},
                               'fillcolor' => toplevel ? 'palegreen1' : 'palegreen3')
      
      @done_modules[mod.full_name] = m
      add_classes(mod, m, file)
      graph << m

      unless mod.includes.empty?
        mod.includes.each do |m|
          m_full_name = find_full_name(m.name, mod)
          if @local_names.include?(m_full_name)
            @global_graph << DOT::DOTEdge.new('from' => "#{m_full_name.gsub( /:/,'_' )}",
                                      'to' => "#{mod.full_name.gsub( /:/,'_' )}",
                                      'ltail' => "cluster_#{m_full_name.gsub( /:/,'_' )}",
                                      'lhead' => "cluster_#{mod.full_name.gsub( /:/,'_' )}")
          else
            unless @global_names.include?(m_full_name)
              path = m_full_name.split("::")
              url = File.join('classes', *path) + ".html"
              @global_graph << DOT::DOTNode.new('name' => "#{m_full_name.gsub( /:/,'_' )}",
                                        'shape' => 'box',
                                        'label' => "#{m_full_name}",
                                        'URL'   => %{"#{url}"})
              @global_names << m_full_name
            end
            @global_graph << DOT::DOTEdge.new('from' => "#{m_full_name.gsub( /:/,'_' )}",
                                      'to' => "#{mod.full_name.gsub( /:/,'_' )}",
                                      'lhead' => "cluster_#{mod.full_name.gsub( /:/,'_' )}")
          end
        end
      end
    end

    def add_classes(container, graph, file = nil )

      use_fileboxes = Options.instance.fileboxes

      files = {}

      # create dummy node (needed if empty and for module includes)
      if container.full_name
        graph << DOT::DOTNode.new('name'     => "#{container.full_name.gsub( /:/,'_' )}",
                                  'label'    => "",
                                  'width'  => (container.classes.empty? and 
                                               container.modules.empty?) ? 
                                  '0.75' : '0.01',
                                  'height' => '0.01',
                                  'shape' => 'plaintext')
      end
      container.classes.each_with_index do |cl, cl_index|
        last_file = cl.in_files[-1].file_relative_name

        if use_fileboxes && !files.include?(last_file)
          @counter += 1
          files[last_file] =
            DOT::DOTSubgraph.new('name'     => "cluster_#{@counter}",
                                 'label'    => "#{last_file}",
                                 'fontname' => FONT,
                                 'color'=>
                                 last_file == file ? 'red' : 'black')
        end

        next if cl.name == 'Object' || cl.name[0,2] == "<<"

        url = cl.http_url("classes")
        
        label = cl.name.dup
        if use_fileboxes && cl.in_files.length > 1
          label <<  '\n[' + 
                        cl.in_files.collect {|i|
                             i.file_relative_name 
                        }.sort.join( '\n' ) +
                    ']'
        end 
                
        attrs = {
          'name' => "#{cl.full_name.gsub( /:/, '_' )}",
          'fontcolor' => 'black',
          'style'=>'filled',
          'color'=>'palegoldenrod',
          'label' => label,
          'shape' => 'ellipse',
          'URL'   => %{"#{url}"}
        }

        c = DOT::DOTNode.new(attrs)
        
        if use_fileboxes
          files[last_file].push c 
        else
          graph << c
        end
      end
      
      if use_fileboxes
        files.each_value do |val|
          graph << val
        end
      end
      
      unless container.classes.empty?
        container.classes.each_with_index do |cl, cl_index|
          cl.includes.each do |m|
            m_full_name = find_full_name(m.name, cl)
            if @local_names.include?(m_full_name)
              @global_graph << DOT::DOTEdge.new('from' => "#{m_full_name.gsub( /:/,'_' )}",
                                      'to' => "#{cl.full_name.gsub( /:/,'_' )}",
                                      'ltail' => "cluster_#{m_full_name.gsub( /:/,'_' )}")
            else
              unless @global_names.include?(m_full_name)
                path = m_full_name.split("::")
                url = File.join('classes', *path) + ".html"
                @global_graph << DOT::DOTNode.new('name' => "#{m_full_name.gsub( /:/,'_' )}",
                                          'shape' => 'box',
                                          'label' => "#{m_full_name}",
                                          'URL'   => %{"#{url}"})
                @global_names << m_full_name
              end
              @global_graph << DOT::DOTEdge.new('from' => "#{m_full_name.gsub( /:/,'_' )}",
                                      'to' => "#{cl.full_name.gsub( /:/, '_')}")
            end
          end

          sclass = cl.superclass
          next if sclass.nil? || sclass == 'Object'
          sclass_full_name = find_full_name(sclass,cl)
          unless @local_names.include?(sclass_full_name) or @global_names.include?(sclass_full_name)
            path = sclass_full_name.split("::")
            url = File.join('classes', *path) + ".html"
            @global_graph << DOT::DOTNode.new(
                       'name' => "#{sclass_full_name.gsub( /:/, '_' )}",
                       'label' => sclass_full_name,
                       'URL'   => %{"#{url}"})
            @global_names << sclass_full_name
          end
          @global_graph << DOT::DOTEdge.new('from' => "#{sclass_full_name.gsub( /:/,'_' )}",
                                    'to' => "#{cl.full_name.gsub( /:/, '_')}")
        end
      end

      container.modules.each do |submod|
        draw_module(submod, graph)
      end
      
    end

    def convert_to_png(file_base, graph)
      str = graph.to_s
      return @diagram_cache[str] if @diagram_cache[str]
      op_type = Options.instance.image_format
      dotfile = File.join(DOT_PATH, file_base)
      src = dotfile + ".dot"
      dot = dotfile + "." + op_type

      unless @options.quiet
        $stderr.print "."
        $stderr.flush
      end

      File.open(src, 'w+' ) do |f|
        f << str << "\n"
      end
      
      system "dot", "-T#{op_type}", src, "-o", dot

      # Now construct the imagemap wrapper around
      # that png

      ret = wrap_in_image_map(src, dot)
      @diagram_cache[str] = ret
      return ret
    end

    # Extract the client-side image map from dot, and use it
    # to generate the imagemap proper. Return the whole
    # <map>..<img> combination, suitable for inclusion on
    # the page

    def wrap_in_image_map(src, dot)
      res = %{<map id="map" name="map">\n}
      dot_map = `dot -Tismap #{src}`
      dot_map.each do |area|
        unless area =~ /^rectangle \((\d+),(\d+)\) \((\d+),(\d+)\) ([\/\w.]+)\s*(.*)/
          $stderr.puts "Unexpected output from dot:\n#{area}"
          return nil
        end
        
        xs, ys = [$1.to_i, $3.to_i], [$2.to_i, $4.to_i]
        url, area_name = $5, $6

        res <<  %{  <area shape="rect" coords="#{xs.min},#{ys.min},#{xs.max},#{ys.max}" }
        res <<  %{     href="#{url}" alt="#{area_name}" />\n}
      end
      res << "</map>\n"
#      map_file = src.sub(/.dot/, '.map')
#      system("dot -Timap #{src} -o #{map_file}")
      res << %{<img src="#{dot}" usemap="#map" border="0" alt="#{dot}">}
      return res
    end
  end
end
PK     Z\%Ȅ      rdoc/tokenstream.rbnu [        # A TokenStream is a list of tokens, gathered during the parse
# of some entity (say a method). Entities populate these streams
# by being registered with the lexer. Any class can collect tokens
# by including TokenStream. From the outside, you use such an object
# by calling the start_collecting_tokens method, followed by calls
# to add_token and pop_token

module TokenStream
  def token_stream
    @token_stream
  end

  def start_collecting_tokens
    @token_stream = []
  end
  def add_token(tk)
    @token_stream << tk
  end
  def add_tokens(tks)
    tks.each  {|tk| add_token(tk)}
  end
  def pop_token
    @token_stream.pop
  end
end
PK     Z\VC      mathn.rbnu [        #
#   mathn.rb - 
#   	$Release Version: 0.5 $
#   	$Revision: 1.1.1.1.4.1 $
#   	$Date: 1998/01/16 12:36:05 $
#   	by Keiju ISHITSUKA(SHL Japan Inc.)
#
# --
#
#   
#

require "complex.rb"
require "rational.rb"
require "matrix.rb"

class Integer

  def gcd2(int)
    a = self.abs
    b = int.abs
    a, b = b, a if a < b
    
    pd_a = a.prime_division
    pd_b = b.prime_division
    
    gcd = 1
    for pair in pd_a
      as = pd_b.assoc(pair[0])
      if as
	gcd *= as[0] ** [as[1], pair[1]].min
      end
    end
    return gcd
  end
  
  def Integer.from_prime_division(pd)
    value = 1
    for prime, index in pd
      value *= prime**index
    end
    value
  end
  
  def prime_division
    raise ZeroDivisionError if self == 0
    ps = Prime.new
    value = self
    pv = []
    for prime in ps
      count = 0
      while (value1, mod = value.divmod(prime)
	     mod) == 0
	value = value1
	count += 1
      end
      if count != 0
	pv.push [prime, count]
      end
      break if prime * prime  >= value
    end
    if value > 1
      pv.push [value, 1]
    end
    return pv
  end
end
  
class Prime
  include Enumerable

  def initialize
    @seed = 1
    @primes = []
    @counts = []
  end
  
  def succ
    i = -1
    size = @primes.size
    while i < size
      if i == -1
	@seed += 1
	i += 1
      else
	while @seed > @counts[i]
	  @counts[i] += @primes[i]
	end
	if @seed != @counts[i]
	  i += 1
	else
	  i = -1
	end
      end
    end
    @primes.push @seed
    @counts.push @seed + @seed
    return @seed
  end
  alias next succ

  def each
    loop do
      yield succ
    end
  end
end

class Fixnum
  alias / quo
end

class Bignum
  alias / quo
end

class Rational
  Unify = true

  def inspect
    format "%s/%s", numerator.inspect, denominator.inspect
  end

  alias power! **

  def ** (other)
    if other.kind_of?(Rational)
      other2 = other
      if self < 0
	return Complex.new!(self, 0) ** other
      elsif other == 0
	return Rational(1,1)
      elsif self == 0
	return Rational(0,1)
      elsif self == 1
	return Rational(1,1)
      end
      
      npd = numerator.prime_division
      dpd = denominator.prime_division
      if other < 0
	other = -other
	npd, dpd = dpd, npd
      end
      
      for elm in npd
	elm[1] = elm[1] * other
	if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
         return Float(self) ** other2
	end
	elm[1] = elm[1].to_i
      end
      
      for elm in dpd
	elm[1] = elm[1] * other
	if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
         return Float(self) ** other2
	end
	elm[1] = elm[1].to_i
      end
      
      num = Integer.from_prime_division(npd)
      den = Integer.from_prime_division(dpd)
      
      Rational(num,den)
      
    elsif other.kind_of?(Integer)
      if other > 0
	num = numerator ** other
	den = denominator ** other
      elsif other < 0
	num = denominator ** -other
	den = numerator ** -other
      elsif other == 0
	num = 1
	den = 1
      end
      Rational.new!(num, den)
    elsif other.kind_of?(Float)
      Float(self) ** other
    else
      x , y = other.coerce(self)
      x ** y
    end
  end

  def power2(other)
    if other.kind_of?(Rational)
      if self < 0
	return Complex(self, 0) ** other
      elsif other == 0
	return Rational(1,1)
      elsif self == 0
	return Rational(0,1)
      elsif self == 1
	return Rational(1,1)
      end
      
      dem = nil
      x = self.denominator.to_f.to_i
      neard = self.denominator.to_f ** (1.0/other.denominator.to_f)
      loop do
	if (neard**other.denominator == self.denominator)
	  dem = neaed
	  break
	end
      end
      nearn = self.numerator.to_f ** (1.0/other.denominator.to_f)
      Rational(num,den)
      
    elsif other.kind_of?(Integer)
      if other > 0
	num = numerator ** other
	den = denominator ** other
      elsif other < 0
	num = denominator ** -other
	den = numerator ** -other
      elsif other == 0
	num = 1
	den = 1
      end
      Rational.new!(num, den)
    elsif other.kind_of?(Float)
      Float(self) ** other
    else
      x , y = other.coerce(self)
      x ** y
    end
  end
end

module Math
  def sqrt(a)
    if a.kind_of?(Complex)
      abs = sqrt(a.real*a.real + a.image*a.image)
#      if not abs.kind_of?(Rational)
#	return a**Rational(1,2)
#      end
      x = sqrt((a.real + abs)/Rational(2))
      y = sqrt((-a.real + abs)/Rational(2))
#      if !(x.kind_of?(Rational) and y.kind_of?(Rational))
#	return a**Rational(1,2)
#      end
      if a.image >= 0 
	Complex(x, y)
      else
	Complex(x, -y)
      end
    elsif a >= 0
      rsqrt(a)
    else
      Complex(0,rsqrt(-a))
    end
  end
  
  def rsqrt(a)
    if a.kind_of?(Float)
      sqrt!(a)
    elsif a.kind_of?(Rational)
      rsqrt(a.numerator)/rsqrt(a.denominator)
    else
      src = a
      max = 2 ** 32
      byte_a = [src & 0xffffffff]
      # ruby's bug
      while (src >= max) and (src >>= 32)
	byte_a.unshift src & 0xffffffff
      end
      
      answer = 0
      main = 0
      side = 0
      for elm in byte_a
	main = (main << 32) + elm
	side <<= 16
	if answer != 0
	  if main * 4  < side * side
	    applo = main.div(side)
	  else 
	    applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1
	  end
	else
	  applo = sqrt!(main).to_i + 1
	end
	
	while (x = (side + applo) * applo) > main
	  applo -= 1
	end
	main -= x
	answer = (answer << 16) + applo
	side += applo * 2
      end
      if main == 0
	answer
      else
	sqrt!(a)
      end
    end
  end

  module_function :sqrt
  module_function :rsqrt
end

class Complex
  Unify = true
end

PK     Z\qc      finalize.rbnu [        #--
#   finalizer.rb - 
#   	$Release Version: 0.3$
#   	$Revision: 1.4 $
#   	$Date: 1998/02/27 05:34:33 $
#   	by Keiju ISHITSUKA
#++
#
# Usage:
#
# add dependency R_method(obj, dependant)
#   add(obj, dependant, method = :finalize, *opt)
#   add_dependency(obj, dependant, method = :finalize, *opt)
#
# delete dependency R_method(obj, dependant)
#   delete(obj_or_id, dependant, method = :finalize)
#   delete_dependency(obj_or_id, dependant, method = :finalize)
#
# delete dependency R_*(obj, dependant)
#   delete_all_dependency(obj_or_id, dependant)
#
# delete dependency R_method(*, dependant)
#   delete_by_dependant(dependant, method = :finalize)
#
# delete dependency R_*(*, dependant)
#   delete_all_by_dependant(dependant)
#
# delete all dependency R_*(*, *)
#   delete_all
#
# finalize the dependant connected by dependency R_method(obj, dependtant).
#   finalize(obj_or_id, dependant, method = :finalize)
#   finalize_dependency(obj_or_id, dependant, method = :finalize)
#
# finalize all dependants connected by dependency R_*(obj, dependtant).
#   finalize_all_dependency(obj_or_id, dependant)
#
# finalize the dependant connected by dependency R_method(*, dependtant).
#   finalize_by_dependant(dependant, method = :finalize)
#
# finalize all dependants connected by dependency R_*(*, dependant).
#   finalize_all_by_dependant(dependant)
#
# finalize all dependency registered to the Finalizer.
#   finalize_all
#
# stop invoking Finalizer on GC.
#   safe{..}
#

module Finalizer
  RCS_ID='-$Id: finalize.rb,v 1.4 1998/02/27 05:34:33 keiju Exp keiju $-'

  class <<self
    # @dependency: {id => [[dependant, method, *opt], ...], ...}

    # add dependency R_method(obj, dependant)
    def add_dependency(obj, dependant, method = :finalize, *opt)
      ObjectSpace.call_finalizer(obj)
      method = method.intern unless method.kind_of?(Integer)
      assoc = [dependant, method].concat(opt)
      if dep = @dependency[obj.object_id]
	dep.push assoc
      else
	@dependency[obj.object_id] = [assoc]
      end
    end
    alias add add_dependency

    # delete dependency R_method(obj, dependant)
    def delete_dependency(id, dependant, method = :finalize)
      id = id.object_id unless id.kind_of?(Integer)
      method = method.intern unless method.kind_of?(Integer)
      for assoc in @dependency[id]
	assoc.delete_if do
	  |d, m, *o|
	  d == dependant && m == method
	end
	@dependency.delete(id) if assoc.empty?
      end
    end
    alias delete delete_dependency

    # delete dependency R_*(obj, dependant)
    def delete_all_dependency(id, dependant)
      id = id.object_id unless id.kind_of?(Integer)
      method = method.intern unless method.kind_of?(Integer)
      for assoc in @dependency[id]
	assoc.delete_if do
	  |d, m, *o|
	  d == dependant
	end
	@dependency.delete(id) if assoc.empty?
      end
    end

    # delete dependency R_method(*, dependant)
    def delete_by_dependant(dependant, method = :finalize)
      method = method.intern unless method.kind_of?(Integer)
      for id in @dependency.keys
	delete(id, dependant, method)
      end
    end

    # delete dependency R_*(*, dependant)
    def delete_all_by_dependant(dependant)
      for id in @dependency.keys
	delete_all_dependency(id, dependant)
      end
    end

    # finalize the depandant connected by dependency R_method(obj, dependtant)
    def finalize_dependency(id, dependant, method = :finalize)
      id = id.object_id unless id.kind_of?(Integer)
      method = method.intern unless method.kind_of?(Integer)
      for assocs in @dependency[id]
	assocs.delete_if do
	  |d, m, *o|
	  d.send(m, id, *o) if ret = d == dependant && m == method
	  ret
	end
	@dependency.delete(id) if assoc.empty?
      end
    end
    alias finalize finalize_dependency

    # finalize all dependants connected by dependency R_*(obj, dependtant)
    def finalize_all_dependency(id, dependant)
      id = id.object_id unless id.kind_of?(Integer)
      method = method.intern unless method.kind_of?(Integer)
      for assoc in @dependency[id]
	assoc.delete_if do
	  |d, m, *o|
	  d.send(m, id, *o) if ret = d == dependant
	end
	@dependency.delete(id) if assoc.empty?
      end
    end

    # finalize the dependant connected by dependency R_method(*, dependtant)
    def finalize_by_dependant(dependant, method = :finalize)
      method = method.intern unless method.kind_of?(Integer)
      for id in @dependency.keys
	finalize(id, dependant, method)
      end
    end

    # finalize all dependants connected by dependency R_*(*, dependtant)
    def finalize_all_by_dependant(dependant)
      for id in @dependency.keys
	finalize_all_dependency(id, dependant)
      end
    end

    # finalize all dependants registered to the Finalizer.
    def finalize_all
      for id, assocs in @dependency
	for dependant, method, *opt in assocs
	  dependant.send(method, id, *opt)
	end
	assocs.clear
      end
    end

    # method to call finalize_* safely.
    def safe
      old_status = Thread.critical
      Thread.critical = true
      ObjectSpace.remove_finalizer(@proc)
      begin
	yield
      ensure
	ObjectSpace.add_finalizer(@proc)
	Thread.critical = old_status
      end
    end

    private

    # registering function to ObjectSpace#add_finalizer
    def final_of(id)
      if assocs = @dependency.delete(id)
	for dependant, method, *opt in assocs
	  dependant.send(method, id, *opt)
	end
      end
    end

  end
  @dependency = Hash.new
  @proc = proc{|id| final_of(id)}
  ObjectSpace.add_finalizer(@proc)
end
PK     Z\uSɂ;  ;    getoptlong.rbnu [        #
# GetoptLong for Ruby
#
# Copyright (C) 1998, 1999, 2000  Motoyuki Kasahara.
#
# You may redistribute and/or modify this library under the same license
# terms as Ruby.
#
# See GetoptLong for documentation.
#
# Additional documents and the latest version of `getoptlong.rb' can be
# found at http://www.sra.co.jp/people/m-kasahr/ruby/getoptlong/

# The GetoptLong class allows you to parse command line options similarly to
# the GNU getopt_long() C library call. Note, however, that GetoptLong is a 
# pure Ruby implementation.
#
# GetoptLong allows for POSIX-style options like <tt>--file</tt> as well 
# as single letter options like <tt>-f</tt>
#
# The empty option <tt>--</tt> (two minus symbols) is used to end option
# processing. This can be particularly important if options have optional
# arguments.
#
# Here is a simple example of usage:
#
#     # == Synopsis
#     #
#     # hello: greets user, demonstrates command line parsing
#     #
#     # == Usage
#     #
#     # hello [OPTION] ... DIR
#     #
#     # -h, --help:
#     #    show help
#     #
#     # --repeat x, -n x:
#     #    repeat x times
#     #
#     # --name [name]:
#     #    greet user by name, if name not supplied default is John
#     #
#     # DIR: The directory in which to issue the greeting.
#     
#     require 'getoptlong'
#     require 'rdoc/usage'
#     
#     opts = GetoptLong.new(
#       [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
#       [ '--repeat', '-n', GetoptLong::REQUIRED_ARGUMENT ],
#       [ '--name', GetoptLong::OPTIONAL_ARGUMENT ]
#     )
#     
#     dir = nil
#     name = nil
#     repetitions = 1
#     opts.each do |opt, arg|
#       case opt
#         when '--help'
#           RDoc::usage
#         when '--repeat'
#           repetitions = arg.to_i
#         when '--name'
#           if arg == ''
#             name = 'John'
#           else
#             name = arg
#           end
#       end
#     end
#     
#     if ARGV.length != 1
#       puts "Missing dir argument (try --help)"
#       exit 0
#     end
#     
#     dir = ARGV.shift
#     
#     Dir.chdir(dir)
#     for i in (1..repetitions)
#       print "Hello"
#       if name
#         print ", #{name}"
#       end
#       puts
#     end
#
# Example command line:
#
#     hello -n 6 --name -- /tmp
#
class GetoptLong
  #
  # Orderings.
  #
  ORDERINGS = [REQUIRE_ORDER = 0, PERMUTE = 1, RETURN_IN_ORDER = 2]

  #
  # Argument flags.
  #
  ARGUMENT_FLAGS = [NO_ARGUMENT = 0, REQUIRED_ARGUMENT = 1,
    OPTIONAL_ARGUMENT = 2]

  #
  # Status codes.
  #
  STATUS_YET, STATUS_STARTED, STATUS_TERMINATED = 0, 1, 2

  #
  # Error types.
  #
  class Error  < StandardError; end
  class AmbigousOption   < Error; end
  class NeedlessArgument < Error; end
  class MissingArgument  < Error; end
  class InvalidOption    < Error; end

  #
  # Set up option processing.
  #
  # The options to support are passed to new() as an array of arrays.
  # Each sub-array contains any number of String option names which carry 
  # the same meaning, and one of the following flags:
  #
  # GetoptLong::NO_ARGUMENT :: Option does not take an argument.
  #
  # GetoptLong::REQUIRED_ARGUMENT :: Option always takes an argument.
  #
  # GetoptLong::OPTIONAL_ARGUMENT :: Option may or may not take an argument.
  #
  # The first option name is considered to be the preferred (canonical) name.
  # Other than that, the elements of each sub-array can be in any order.
  #
  def initialize(*arguments)
    #
    # Current ordering.
    #
    if ENV.include?('POSIXLY_CORRECT')
      @ordering = REQUIRE_ORDER
    else
      @ordering = PERMUTE
    end

    #
    # Hash table of option names.
    # Keys of the table are option names, and their values are canonical
    # names of the options.
    #
    @canonical_names = Hash.new

    #
    # Hash table of argument flags.
    # Keys of the table are option names, and their values are argument
    # flags of the options.
    #
    @argument_flags = Hash.new

    #
    # Whether error messages are output to $deferr.
    #
    @quiet = FALSE

    #
    # Status code.
    #
    @status = STATUS_YET

    #
    # Error code.
    #
    @error = nil

    #
    # Error message.
    #
    @error_message = nil

    #
    # Rest of catenated short options.
    #
    @rest_singles = ''

    #
    # List of non-option-arguments.
    # Append them to ARGV when option processing is terminated.
    #
    @non_option_arguments = Array.new

    if 0 < arguments.length
      set_options(*arguments)
    end
  end

  #
  # Set the handling of the ordering of options and arguments.
  # A RuntimeError is raised if option processing has already started.
  #
  # The supplied value must be a member of GetoptLong::ORDERINGS. It alters
  # the processing of options as follows:
  #
  # <b>REQUIRE_ORDER</b> :
  # 
  # Options are required to occur before non-options.
  #
  # Processing of options ends as soon as a word is encountered that has not
  # been preceded by an appropriate option flag.
  #
  # For example, if -a and -b are options which do not take arguments,
  # parsing command line arguments of '-a one -b two' would result in 
  # 'one', '-b', 'two' being left in ARGV, and only ('-a', '') being 
  # processed as an option/arg pair.
  #
  # This is the default ordering, if the environment variable
  # POSIXLY_CORRECT is set. (This is for compatibility with GNU getopt_long.)
  #
  # <b>PERMUTE</b> :
  #  
  # Options can occur anywhere in the command line parsed. This is the 
  # default behavior.
  #
  # Every sequence of words which can be interpreted as an option (with or
  # without argument) is treated as an option; non-option words are skipped.
  #
  # For example, if -a does not require an argument and -b optionally takes
  # an argument, parsing '-a one -b two three' would result in ('-a','') and
  # ('-b', 'two') being processed as option/arg pairs, and 'one','three'
  # being left in ARGV.
  #
  # If the ordering is set to PERMUTE but the environment variable
  # POSIXLY_CORRECT is set, REQUIRE_ORDER is used instead. This is for
  # compatibility with GNU getopt_long.
  #
  # <b>RETURN_IN_ORDER</b> :
  #
  # All words on the command line are processed as options. Words not 
  # preceded by a short or long option flag are passed as arguments
  # with an option of '' (empty string).
  #
  # For example, if -a requires an argument but -b does not, a command line
  # of '-a one -b two three' would result in option/arg pairs of ('-a', 'one')
  # ('-b', ''), ('', 'two'), ('', 'three') being processed.
  #
  def ordering=(ordering)
    #
    # The method is failed if option processing has already started.
    #
    if @status != STATUS_YET
      set_error(ArgumentError, "argument error")
      raise RuntimeError,
	"invoke ordering=, but option processing has already started"
    end

    #
    # Check ordering.
    #
    if !ORDERINGS.include?(ordering)
      raise ArgumentError, "invalid ordering `#{ordering}'"
    end
    if ordering == PERMUTE && ENV.include?('POSIXLY_CORRECT')
      @ordering = REQUIRE_ORDER
    else
      @ordering = ordering
    end
  end

  #
  # Return ordering.
  #
  attr_reader :ordering

  #
  # Set options. Takes the same argument as GetoptLong.new.
  #
  # Raises a RuntimeError if option processing has already started.
  #
  def set_options(*arguments)
    #
    # The method is failed if option processing has already started.
    #
    if @status != STATUS_YET
      raise RuntimeError, 
	"invoke set_options, but option processing has already started"
    end

    #
    # Clear tables of option names and argument flags.
    #
    @canonical_names.clear
    @argument_flags.clear

    arguments.each do |arg|
      #
      # Each argument must be an Array.
      #
      if !arg.is_a?(Array)
	raise ArgumentError, "the option list contains non-Array argument"
      end

      #
      # Find an argument flag and it set to `argument_flag'.
      #
      argument_flag = nil
      arg.each do |i|
	if ARGUMENT_FLAGS.include?(i)
	  if argument_flag != nil
	    raise ArgumentError, "too many argument-flags"
	  end
	  argument_flag = i
	end
      end
      raise ArgumentError, "no argument-flag" if argument_flag == nil

      canonical_name = nil
      arg.each do |i|
	#
	# Check an option name.
	#
	next if i == argument_flag
	begin
	  if !i.is_a?(String) || i !~ /^-([^-]|-.+)$/
	    raise ArgumentError, "an invalid option `#{i}'"
	  end
	  if (@canonical_names.include?(i))
	    raise ArgumentError, "option redefined `#{i}'"
	  end
	rescue
	  @canonical_names.clear
	  @argument_flags.clear
	  raise
	end

	#
	# Register the option (`i') to the `@canonical_names' and 
	# `@canonical_names' Hashes.
	#
	if canonical_name == nil
	  canonical_name = i
	end
	@canonical_names[i] = canonical_name
	@argument_flags[i] = argument_flag
      end
      raise ArgumentError, "no option name" if canonical_name == nil
    end
    return self
  end

  #
  # Set/Unset `quiet' mode.
  #
  attr_writer :quiet

  #
  # Return the flag of `quiet' mode.
  #
  attr_reader :quiet

  #
  # `quiet?' is an alias of `quiet'.
  #
  alias quiet? quiet

  #
  # Explicitly terminate option processing.
  #
  def terminate
    return nil if @status == STATUS_TERMINATED
    raise RuntimeError, "an error has occured" if @error != nil

    @status = STATUS_TERMINATED
    @non_option_arguments.reverse_each do |argument|
      ARGV.unshift(argument)
    end

    @canonical_names = nil
    @argument_flags = nil
    @rest_singles = nil
    @non_option_arguments = nil

    return self
  end

  #
  # Returns true if option processing has terminated, false otherwise.
  #
  def terminated?
    return @status == STATUS_TERMINATED
  end

  #
  # Set an error (protected).
  #
  def set_error(type, message)
    $deferr.print("#{$0}: #{message}\n") if !@quiet

    @error = type
    @error_message = message
    @canonical_names = nil
    @argument_flags = nil
    @rest_singles = nil
    @non_option_arguments = nil

    raise type, message
  end
  protected :set_error

  #
  # Examine whether an option processing is failed.
  #
  attr_reader :error

  #
  # `error?' is an alias of `error'.
  #
  alias error? error

  # Return the appropriate error message in POSIX-defined format.
  # If no error has occurred, returns nil.
  #
  def error_message
    return @error_message
  end

  #
  # Get next option name and its argument, as an Array of two elements.
  #
  # The option name is always converted to the first (preferred)
  # name given in the original options to GetoptLong.new.
  #
  # Example: ['--option', 'value']
  #
  # Returns nil if the processing is complete (as determined by
  # STATUS_TERMINATED).
  #
  def get
    option_name, option_argument = nil, ''

    #
    # Check status.
    #
    return nil if @error != nil
    case @status
    when STATUS_YET
      @status = STATUS_STARTED
    when STATUS_TERMINATED
      return nil
    end

    #
    # Get next option argument.
    #
    if 0 < @rest_singles.length
      argument = '-' + @rest_singles
    elsif (ARGV.length == 0)
      terminate
      return nil
    elsif @ordering == PERMUTE
      while 0 < ARGV.length && ARGV[0] !~ /^-./
	@non_option_arguments.push(ARGV.shift)
      end
      if ARGV.length == 0
	terminate
	return nil
      end
      argument = ARGV.shift
    elsif @ordering == REQUIRE_ORDER 
      if (ARGV[0] !~ /^-./)
	terminate
	return nil
      end
      argument = ARGV.shift
    else
      argument = ARGV.shift
    end

    #
    # Check the special argument `--'.
    # `--' indicates the end of the option list.
    #
    if argument == '--' && @rest_singles.length == 0
      terminate
      return nil
    end

    #
    # Check for long and short options.
    #
    if argument =~ /^(--[^=]+)/ && @rest_singles.length == 0
      #
      # This is a long style option, which start with `--'.
      #
      pattern = $1
      if @canonical_names.include?(pattern)
	option_name = pattern
      else
	#
	# The option `option_name' is not registered in `@canonical_names'.
	# It may be an abbreviated.
	#
	match_count = 0
	@canonical_names.each_key do |key|
	  if key.index(pattern) == 0
	    option_name = key
	    match_count += 1
	  end
	end
	if 2 <= match_count
	  set_error(AmbigousOption, "option `#{argument}' is ambiguous")
	elsif match_count == 0
	  set_error(InvalidOption, "unrecognized option `#{argument}'")
	end
      end

      #
      # Check an argument to the option.
      #
      if @argument_flags[option_name] == REQUIRED_ARGUMENT
	if argument =~ /=(.*)$/
	  option_argument = $1
	elsif 0 < ARGV.length
	  option_argument = ARGV.shift
	else
	  set_error(MissingArgument,
	            "option `#{argument}' requires an argument")
	end
      elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
	if argument =~ /=(.*)$/
	  option_argument = $1
	elsif 0 < ARGV.length && ARGV[0] !~ /^-./
	  option_argument = ARGV.shift
	else
	  option_argument = ''
	end
      elsif argument =~ /=(.*)$/
	set_error(NeedlessArgument,
		  "option `#{option_name}' doesn't allow an argument")
      end

    elsif argument =~ /^(-(.))(.*)/
      #
      # This is a short style option, which start with `-' (not `--').
      # Short options may be catenated (e.g. `-l -g' is equivalent to
      # `-lg').
      #
      option_name, ch, @rest_singles = $1, $2, $3

      if @canonical_names.include?(option_name)
	#
	# The option `option_name' is found in `@canonical_names'.
	# Check its argument.
	#
	if @argument_flags[option_name] == REQUIRED_ARGUMENT
	  if 0 < @rest_singles.length
	    option_argument = @rest_singles
	    @rest_singles = ''
	  elsif 0 < ARGV.length
	    option_argument = ARGV.shift
	  else
	    # 1003.2 specifies the format of this message.
	    set_error(MissingArgument, "option requires an argument -- #{ch}")
	  end
	elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
	  if 0 < @rest_singles.length
	    option_argument = @rest_singles
	    @rest_singles = ''
	  elsif 0 < ARGV.length && ARGV[0] !~ /^-./
	    option_argument = ARGV.shift
	  else
	    option_argument = ''
	  end
	end
      else
	#
	# This is an invalid option.
	# 1003.2 specifies the format of this message.
	#
	if ENV.include?('POSIXLY_CORRECT')
	  set_error(InvalidOption, "illegal option -- #{ch}")
	else
	  set_error(InvalidOption, "invalid option -- #{ch}")
	end
      end
    else
      #
      # This is a non-option argument.
      # Only RETURN_IN_ORDER falled into here.
      #
      return '', argument
    end

    return @canonical_names[option_name], option_argument
  end

  #
  # `get_option' is an alias of `get'.
  #
  alias get_option get

  # Iterator version of `get'.
  #
  # The block is called repeatedly with two arguments:
  # The first is the option name.
  # The second is the argument which followed it (if any). 
  # Example: ('--opt', 'value')
  #
  # The option name is always converted to the first (preferred)
  # name given in the original options to GetoptLong.new.
  #
  def each
    loop do
      option_name, option_argument = get_option
      break if option_name == nil
      yield option_name, option_argument
    end
  end

  #
  # `each_option' is an alias of `each'.
  #
  alias each_option each
end
PK     Z\BD  D  	  thwait.rbnu [        #
#   thwait.rb - thread synchronization class
#   	$Release Version: 0.9 $
#   	$Revision: 1.3 $
#   	$Date: 1998/06/26 03:19:34 $
#   	by Keiju ISHITSUKA(Nihpon Rational Software Co.,Ltd.)
#
# --
#  feature:
#  provides synchronization for multiple threads.
#
#  class methods:
#  * ThreadsWait.all_waits(thread1,...)
#    waits until all of specified threads are terminated.
#    if a block is supplied for the method, evaluates it for
#    each thread termination.
#  * th = ThreadsWait.new(thread1,...)
#    creates synchronization object, specifying thread(s) to wait.
#  
#  methods:
#  * th.threads
#    list threads to be synchronized
#  * th.empty?
#    is there any thread to be synchronized.
#  * th.finished?
#    is there already terminated thread.
#  * th.join(thread1,...) 
#    wait for specified thread(s).
#  * th.join_nowait(threa1,...)
#    specifies thread(s) to wait.  non-blocking.
#  * th.next_wait
#    waits until any of specified threads is terminated.
#  * th.all_waits
#    waits until all of specified threads are terminated.
#    if a block is supplied for the method, evaluates it for
#    each thread termination.
#

require "thread.rb"
require "e2mmap.rb"

#
# This class watches for termination of multiple threads.  Basic functionality
# (wait until specified threads have terminated) can be accessed through the
# class method ThreadsWait::all_waits.  Finer control can be gained using
# instance methods.
#
# Example:
#
#   ThreadsWait.all_wait(thr1, thr2, ...) do |t|
#     STDERR.puts "Thread #{t} has terminated."
#   end
#
class ThreadsWait
  RCS_ID='-$Id: thwait.rb,v 1.3 1998/06/26 03:19:34 keiju Exp keiju $-'
  
  Exception2MessageMapper.extend_to(binding)
  def_exception("ErrNoWaitingThread", "No threads for waiting.")
  def_exception("ErrNoFinishedThread", "No finished threads.")
  
  #
  # Waits until all specified threads have terminated.  If a block is provided,
  # it is executed for each thread termination.
  #
  def ThreadsWait.all_waits(*threads) # :yield: thread
    tw = ThreadsWait.new(*threads)
    if block_given?
      tw.all_waits do |th|
	yield th
      end
    else
      tw.all_waits
    end
  end
  
  #
  # Creates a ThreadsWait object, specifying the threads to wait on.
  # Non-blocking.
  #
  def initialize(*threads)
    @threads = []
    @wait_queue = Queue.new
    join_nowait(*threads) unless threads.empty?
  end
  
  # Returns the array of threads in the wait queue.
  attr :threads
  
  #
  # Returns +true+ if there are no threads to be synchronized.
  #
  def empty?
    @threads.empty?
  end
  
  #
  # Returns +true+ if any thread has terminated.
  #
  def finished?
    !@wait_queue.empty?
  end
  
  #
  # Waits for specified threads to terminate, and returns when one of
  # the threads terminated.
  #
  def join(*threads)
    join_nowait(*threads)
    next_wait
  end
  
  #
  # Specifies the threads that this object will wait for, but does not actually
  # wait.
  #
  def join_nowait(*threads)
    threads.flatten!
    @threads.concat threads
    for th in threads
      Thread.start(th) do |t|
	begin
	  t.join
	ensure
	  @wait_queue.push t
	end
      end
    end
  end
  
  #
  # Waits until any of the specified threads has terminated, and returns the one
  # that does.
  #
  # If there is no thread to wait, raises +ErrNoWaitingThread+.  If +nonblock+
  # is true, and there is no terminated thread, raises +ErrNoFinishedThread+.
  #
  def next_wait(nonblock = nil)
    ThreadsWait.fail ErrNoWaitingThread if @threads.empty?
    begin
      @threads.delete(th = @wait_queue.pop(nonblock))
      th
    rescue ThreadError
      ThreadsWait.fail ErrNoFinishedThread
    end
  end
  
  #
  # Waits until all of the specified threads are terminated.  If a block is
  # supplied for the method, it is executed for each thread termination.
  #
  # Raises exceptions in the same manner as +next_wait+.
  #
  def all_waits
    until @threads.empty?
      th = next_wait
      yield th if block_given?
    end
  end
end

ThWait = ThreadsWait


# Documentation comments:
#  - Source of documentation is evenly split between Nutshell, existing
#    comments, and my own rephrasing.
#  - I'm not particularly confident that the comments are all exactly correct.
#  - The history, etc., up the top appears in the RDoc output.  Perhaps it would
#    be better to direct that not to appear, and put something else there
#    instead.
PK     Z\P-wu  u    pathname.rbnu [        #
# = pathname.rb
#
# Object-Oriented Pathname Class
#
# Author:: Tanaka Akira <akr@m17n.org>
# Documentation:: Author and Gavin Sinclair
#
# For documentation, see class Pathname.
#
# <tt>pathname.rb</tt> is distributed with Ruby since 1.8.0.
#

#
# == Pathname
#
# Pathname represents a pathname which locates a file in a filesystem.
# The pathname depends on OS: Unix, Windows, etc.
# Pathname library works with pathnames of local OS.
# However non-Unix pathnames are supported experimentally.
#
# It does not represent the file itself.
# A Pathname can be relative or absolute.  It's not until you try to
# reference the file that it even matters whether the file exists or not.
#
# Pathname is immutable.  It has no method for destructive update.
#
# The value of this class is to manipulate file path information in a neater
# way than standard Ruby provides.  The examples below demonstrate the
# difference.  *All* functionality from File, FileTest, and some from Dir and
# FileUtils is included, in an unsurprising way.  It is essentially a facade for
# all of these, and more.
#
# == Examples
#
# === Example 1: Using Pathname
#
#   require 'pathname'
#   p = Pathname.new("/usr/bin/ruby")
#   size = p.size              # 27662
#   isdir = p.directory?       # false
#   dir  = p.dirname           # Pathname:/usr/bin
#   base = p.basename          # Pathname:ruby
#   dir, base = p.split        # [Pathname:/usr/bin, Pathname:ruby]
#   data = p.read
#   p.open { |f| _ } 
#   p.each_line { |line| _ }
#
# === Example 2: Using standard Ruby
#
#   p = "/usr/bin/ruby"
#   size = File.size(p)        # 27662
#   isdir = File.directory?(p) # false
#   dir  = File.dirname(p)     # "/usr/bin"
#   base = File.basename(p)    # "ruby"
#   dir, base = File.split(p)  # ["/usr/bin", "ruby"]
#   data = File.read(p)
#   File.open(p) { |f| _ } 
#   File.foreach(p) { |line| _ }
#
# === Example 3: Special features
#
#   p1 = Pathname.new("/usr/lib")   # Pathname:/usr/lib
#   p2 = p1 + "ruby/1.8"            # Pathname:/usr/lib/ruby/1.8
#   p3 = p1.parent                  # Pathname:/usr
#   p4 = p2.relative_path_from(p3)  # Pathname:lib/ruby/1.8
#   pwd = Pathname.pwd              # Pathname:/home/gavin
#   pwd.absolute?                   # true
#   p5 = Pathname.new "."           # Pathname:.
#   p5 = p5 + "music/../articles"   # Pathname:music/../articles
#   p5.cleanpath                    # Pathname:articles
#   p5.realpath                     # Pathname:/home/gavin/articles
#   p5.children                     # [Pathname:/home/gavin/articles/linux, ...]
# 
# == Breakdown of functionality
#
# === Core methods
#
# These methods are effectively manipulating a String, because that's all a path
# is.  Except for #mountpoint?, #children, and #realpath, they don't access the
# filesystem.
#
# - +
# - #join
# - #parent
# - #root?
# - #absolute?
# - #relative?
# - #relative_path_from
# - #each_filename
# - #cleanpath
# - #realpath
# - #children
# - #mountpoint?
#
# === File status predicate methods
#
# These methods are a facade for FileTest:
# - #blockdev?
# - #chardev?
# - #directory?
# - #executable?
# - #executable_real?
# - #exist?
# - #file?
# - #grpowned?
# - #owned?
# - #pipe?
# - #readable?
# - #world_readable?
# - #readable_real?
# - #setgid?
# - #setuid?
# - #size
# - #size?
# - #socket?
# - #sticky?
# - #symlink?
# - #writable?
# - #world_writable?
# - #writable_real?
# - #zero?
#
# === File property and manipulation methods
#
# These methods are a facade for File:
# - #atime
# - #ctime
# - #mtime
# - #chmod(mode)
# - #lchmod(mode)
# - #chown(owner, group)
# - #lchown(owner, group)
# - #fnmatch(pattern, *args)
# - #fnmatch?(pattern, *args)
# - #ftype
# - #make_link(old)
# - #open(*args, &block)
# - #readlink
# - #rename(to)
# - #stat
# - #lstat
# - #make_symlink(old)
# - #truncate(length)
# - #utime(atime, mtime)
# - #basename(*args)
# - #dirname
# - #extname
# - #expand_path(*args)
# - #split
#
# === Directory methods
#
# These methods are a facade for Dir:
# - Pathname.glob(*args)
# - Pathname.getwd / Pathname.pwd
# - #rmdir
# - #entries
# - #each_entry(&block)
# - #mkdir(*args)
# - #opendir(*args)
#
# === IO
#
# These methods are a facade for IO:
# - #each_line(*args, &block)
# - #read(*args)
# - #readlines(*args)
# - #sysopen(*args)
#
# === Utilities
#
# These methods are a mixture of Find, FileUtils, and others:
# - #find(&block)
# - #mkpath
# - #rmtree
# - #unlink / #delete
#
#
# == Method documentation
#
# As the above section shows, most of the methods in Pathname are facades.  The
# documentation for these methods generally just says, for instance, "See
# FileTest.writable?", as you should be familiar with the original method
# anyway, and its documentation (e.g. through +ri+) will contain more
# information.  In some cases, a brief description will follow.
#
class Pathname

  # :stopdoc:
  if RUBY_VERSION < "1.9"
    TO_PATH = :to_str
  else
    # to_path is implemented so Pathname objects are usable with File.open, etc.
    TO_PATH = :to_path
  end

  SAME_PATHS = if File::FNM_SYSCASE.nonzero?
    proc {|a, b| a.casecmp(b).zero?}
  else
    proc {|a, b| a == b}
  end

  # :startdoc:

  #
  # Create a Pathname object from the given String (or String-like object).
  # If +path+ contains a NUL character (<tt>\0</tt>), an ArgumentError is raised.
  #
  def initialize(path)
    path = path.__send__(TO_PATH) if path.respond_to? TO_PATH
    @path = path.dup

    if /\0/ =~ @path
      raise ArgumentError, "pathname contains \\0: #{@path.inspect}"
    end

    self.taint if @path.tainted?
  end

  def freeze() super; @path.freeze; self end
  def taint() super; @path.taint; self end
  def untaint() super; @path.untaint; self end

  #
  # Compare this pathname with +other+.  The comparison is string-based.
  # Be aware that two different paths (<tt>foo.txt</tt> and <tt>./foo.txt</tt>)
  # can refer to the same file.
  #
  def ==(other)
    return false unless Pathname === other
    other.to_s == @path
  end
  alias === ==
  alias eql? ==

  # Provides for comparing pathnames, case-sensitively.
  def <=>(other)
    return nil unless Pathname === other
    @path.tr('/', "\0") <=> other.to_s.tr('/', "\0")
  end

  def hash # :nodoc:
    @path.hash
  end

  # Return the path as a String.
  def to_s
    @path.dup
  end

  # to_path is implemented so Pathname objects are usable with File.open, etc.
  alias_method TO_PATH, :to_s

  def inspect # :nodoc:
    "#<#{self.class}:#{@path}>"
  end

  # Return a pathname which is substituted by String#sub.
  def sub(pattern, *rest, &block)
    if block
      path = @path.sub(pattern, *rest) {|*args|
        begin
          old = Thread.current[:pathname_sub_matchdata]
          Thread.current[:pathname_sub_matchdata] = $~
          eval("$~ = Thread.current[:pathname_sub_matchdata]", block.binding)
        ensure
          Thread.current[:pathname_sub_matchdata] = old
        end
        yield(*args)
      }
    else
      path = @path.sub(pattern, *rest)
    end
    self.class.new(path)
  end

  if File::ALT_SEPARATOR
    SEPARATOR_PAT = /[#{Regexp.quote File::ALT_SEPARATOR}#{Regexp.quote File::SEPARATOR}]/
  else
    SEPARATOR_PAT = /#{Regexp.quote File::SEPARATOR}/
  end

  # chop_basename(path) -> [pre-basename, basename] or nil
  def chop_basename(path)
    base = File.basename(path)
    if /\A#{SEPARATOR_PAT}?\z/ =~ base
      return nil
    else
      return path[0, path.rindex(base)], base
    end
  end
  private :chop_basename

  # split_names(path) -> prefix, [name, ...]
  def split_names(path)
    names = []
    while r = chop_basename(path)
      path, basename = r
      names.unshift basename
    end
    return path, names
  end
  private :split_names

  def prepend_prefix(prefix, relpath)
    if relpath.empty?
      File.dirname(prefix)
    elsif /#{SEPARATOR_PAT}/ =~ prefix
      prefix = File.dirname(prefix)
      prefix = File.join(prefix, "") if File.basename(prefix + 'a') != 'a'
      prefix + relpath
    else
      prefix + relpath
    end
  end
  private :prepend_prefix

  # Returns clean pathname of +self+ with consecutive slashes and useless dots
  # removed.  The filesystem is not accessed.
  #
  # If +consider_symlink+ is +true+, then a more conservative algorithm is used
  # to avoid breaking symbolic linkages.  This may retain more <tt>..</tt>
  # entries than absolutely necessary, but without accessing the filesystem,
  # this can't be avoided.  See #realpath.
  #
  def cleanpath(consider_symlink=false)
    if consider_symlink
      cleanpath_conservative
    else
      cleanpath_aggressive
    end
  end

  #
  # Clean the path simply by resolving and removing excess "." and ".." entries.
  # Nothing more, nothing less.
  #
  def cleanpath_aggressive
    path = @path
    names = []
    pre = path
    while r = chop_basename(pre)
      pre, base = r
      case base
      when '.'
      when '..'
        names.unshift base
      else
        if names[0] == '..'
          names.shift
        else
          names.unshift base
        end
      end
    end
    if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
      names.shift while names[0] == '..'
    end
    self.class.new(prepend_prefix(pre, File.join(*names)))
  end
  private :cleanpath_aggressive

  # has_trailing_separator?(path) -> bool
  def has_trailing_separator?(path)
    if r = chop_basename(path)
      pre, basename = r
      pre.length + basename.length < path.length
    else
      false
    end
  end
  private :has_trailing_separator?

  # add_trailing_separator(path) -> path
  def add_trailing_separator(path)
    if File.basename(path + 'a') == 'a'
      path
    else
      File.join(path, "") # xxx: Is File.join is appropriate to add separator?
    end
  end
  private :add_trailing_separator

  def del_trailing_separator(path)
    if r = chop_basename(path)
      pre, basename = r
      pre + basename
    elsif /#{SEPARATOR_PAT}+\z/o =~ path
      $` + File.dirname(path)[/#{SEPARATOR_PAT}*\z/o]
    else
      path
    end
  end
  private :del_trailing_separator

  def cleanpath_conservative
    path = @path
    names = []
    pre = path
    while r = chop_basename(pre)
      pre, base = r
      names.unshift base if base != '.'
    end
    if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
      names.shift while names[0] == '..'
    end
    if names.empty?
      self.class.new(File.dirname(pre))
    else
      if names.last != '..' && File.basename(path) == '.'
        names << '.'
      end
      result = prepend_prefix(pre, File.join(*names))
      if /\A(?:\.|\.\.)\z/ !~ names.last && has_trailing_separator?(path)
        self.class.new(add_trailing_separator(result))
      else
        self.class.new(result)
      end
    end
  end
  private :cleanpath_conservative

  def realpath_rec(prefix, unresolved, h)
    resolved = []
    until unresolved.empty?
      n = unresolved.shift
      if n == '.'
        next
      elsif n == '..'
        resolved.pop
      else
        path = prepend_prefix(prefix, File.join(*(resolved + [n])))
        if h.include? path
          if h[path] == :resolving
            raise Errno::ELOOP.new(path)
          else
            prefix, *resolved = h[path]
          end
        else
          s = File.lstat(path)
          if s.symlink?
            h[path] = :resolving
            link_prefix, link_names = split_names(File.readlink(path))
            if link_prefix == ''
              prefix, *resolved = h[path] = realpath_rec(prefix, resolved + link_names, h)
            else
              prefix, *resolved = h[path] = realpath_rec(link_prefix, link_names, h)
            end
          else
            resolved << n
            h[path] = [prefix, *resolved]
          end
        end
      end
    end
    return prefix, *resolved
  end
  private :realpath_rec

  #
  # Returns a real (absolute) pathname of +self+ in the actual filesystem.
  # The real pathname doesn't contain symlinks or useless dots.
  #
  # No arguments should be given; the old behaviour is *obsoleted*. 
  #
  def realpath
    path = @path
    prefix, names = split_names(path)
    if prefix == ''
      prefix, names2 = split_names(Dir.pwd)
      names = names2 + names
    end
    prefix, *names = realpath_rec(prefix, names, {})
    self.class.new(prepend_prefix(prefix, File.join(*names)))
  end

  # #parent returns the parent directory.
  #
  # This is same as <tt>self + '..'</tt>.
  def parent
    self + '..'
  end

  # #mountpoint? returns +true+ if <tt>self</tt> points to a mountpoint.
  def mountpoint?
    begin
      stat1 = self.lstat
      stat2 = self.parent.lstat
      stat1.dev == stat2.dev && stat1.ino == stat2.ino ||
        stat1.dev != stat2.dev
    rescue Errno::ENOENT
      false
    end
  end

  #
  # #root? is a predicate for root directories.  I.e. it returns +true+ if the
  # pathname consists of consecutive slashes.
  #
  # It doesn't access actual filesystem.  So it may return +false+ for some
  # pathnames which points to roots such as <tt>/usr/..</tt>.
  #
  def root?
    !!(chop_basename(@path) == nil && /#{SEPARATOR_PAT}/o =~ @path)
  end

  # Predicate method for testing whether a path is absolute.
  # It returns +true+ if the pathname begins with a slash.
  def absolute?
    !relative?
  end

  # The opposite of #absolute?
  def relative?
    path = @path
    while r = chop_basename(path)
      path, basename = r
    end
    path == ''
  end

  #
  # Iterates over each component of the path.
  #
  #   Pathname.new("/usr/bin/ruby").each_filename {|filename| ... }
  #     # yields "usr", "bin", and "ruby".
  #
  def each_filename # :yield: filename
    prefix, names = split_names(@path)
    names.each {|filename| yield filename }
    nil
  end

  # Iterates over and yields a new Pathname object
  # for each element in the given path in descending order.
  #
  #  Pathname.new('/path/to/some/file.rb').descend {|v| p v}
  #     #<Pathname:/>
  #     #<Pathname:/path>
  #     #<Pathname:/path/to>
  #     #<Pathname:/path/to/some>
  #     #<Pathname:/path/to/some/file.rb>
  #
  #  Pathname.new('path/to/some/file.rb').descend {|v| p v}
  #     #<Pathname:path>
  #     #<Pathname:path/to>
  #     #<Pathname:path/to/some>
  #     #<Pathname:path/to/some/file.rb>
  #
  # It doesn't access actual filesystem.
  #
  # This method is available since 1.8.5.
  #
  def descend
    vs = []
    ascend {|v| vs << v }
    vs.reverse_each {|v| yield v }
    nil
  end

  # Iterates over and yields a new Pathname object
  # for each element in the given path in ascending order.
  #
  #  Pathname.new('/path/to/some/file.rb').ascend {|v| p v}
  #     #<Pathname:/path/to/some/file.rb>
  #     #<Pathname:/path/to/some>
  #     #<Pathname:/path/to>
  #     #<Pathname:/path>
  #     #<Pathname:/>
  #
  #  Pathname.new('path/to/some/file.rb').ascend {|v| p v}
  #     #<Pathname:path/to/some/file.rb>
  #     #<Pathname:path/to/some>
  #     #<Pathname:path/to>
  #     #<Pathname:path>
  #
  # It doesn't access actual filesystem.
  #
  # This method is available since 1.8.5.
  #
  def ascend
    path = @path
    yield self
    while r = chop_basename(path)
      path, name = r
      break if path.empty?
      yield self.class.new(del_trailing_separator(path))
    end
  end

  #
  # Pathname#+ appends a pathname fragment to this one to produce a new Pathname
  # object.
  #
  #   p1 = Pathname.new("/usr")      # Pathname:/usr
  #   p2 = p1 + "bin/ruby"           # Pathname:/usr/bin/ruby
  #   p3 = p1 + "/etc/passwd"        # Pathname:/etc/passwd
  #
  # This method doesn't access the file system; it is pure string manipulation. 
  #
  def +(other)
    other = Pathname.new(other) unless Pathname === other
    Pathname.new(plus(@path, other.to_s))
  end

  def plus(path1, path2) # -> path
    prefix2 = path2
    index_list2 = []
    basename_list2 = []
    while r2 = chop_basename(prefix2)
      prefix2, basename2 = r2
      index_list2.unshift prefix2.length
      basename_list2.unshift basename2
    end
    return path2 if prefix2 != ''
    prefix1 = path1
    while true
      while !basename_list2.empty? && basename_list2.first == '.'
        index_list2.shift
        basename_list2.shift
      end
      break unless r1 = chop_basename(prefix1)
      prefix1, basename1 = r1
      next if basename1 == '.'
      if basename1 == '..' || basename_list2.empty? || basename_list2.first != '..'
        prefix1 = prefix1 + basename1
        break
      end
      index_list2.shift
      basename_list2.shift
    end
    r1 = chop_basename(prefix1)
    if !r1 && /#{SEPARATOR_PAT}/o =~ File.basename(prefix1)
      while !basename_list2.empty? && basename_list2.first == '..'
        index_list2.shift
        basename_list2.shift
      end
    end
    if !basename_list2.empty?
      suffix2 = path2[index_list2.first..-1]
      r1 ? File.join(prefix1, suffix2) : prefix1 + suffix2
    else
      r1 ? prefix1 : File.dirname(prefix1)
    end
  end
  private :plus

  #
  # Pathname#join joins pathnames.
  #
  # <tt>path0.join(path1, ..., pathN)</tt> is the same as
  # <tt>path0 + path1 + ... + pathN</tt>.
  #
  def join(*args)
    args.unshift self
    result = args.pop
    result = Pathname.new(result) unless Pathname === result
    return result if result.absolute?
    args.reverse_each {|arg|
      arg = Pathname.new(arg) unless Pathname === arg
      result = arg + result
      return result if result.absolute?
    }
    result
  end

  #
  # Returns the children of the directory (files and subdirectories, not
  # recursive) as an array of Pathname objects.  By default, the returned
  # pathnames will have enough information to access the files.  If you set
  # +with_directory+ to +false+, then the returned pathnames will contain the
  # filename only.
  #
  # For example:
  #   p = Pathname("/usr/lib/ruby/1.8")
  #   p.children
  #       # -> [ Pathname:/usr/lib/ruby/1.8/English.rb,
  #              Pathname:/usr/lib/ruby/1.8/Env.rb,
  #              Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ]
  #   p.children(false)
  #       # -> [ Pathname:English.rb, Pathname:Env.rb, Pathname:abbrev.rb, ... ]
  #
  # Note that the result never contain the entries <tt>.</tt> and <tt>..</tt> in
  # the directory because they are not children.
  #
  # This method has existed since 1.8.1.
  #
  def children(with_directory=true)
    with_directory = false if @path == '.'
    result = []
    Dir.foreach(@path) {|e|
      next if e == '.' || e == '..'
      if with_directory
        result << self.class.new(File.join(@path, e))
      else
        result << self.class.new(e)
      end
    }
    result
  end

  #
  # #relative_path_from returns a relative path from the argument to the
  # receiver.  If +self+ is absolute, the argument must be absolute too.  If
  # +self+ is relative, the argument must be relative too.
  #
  # #relative_path_from doesn't access the filesystem.  It assumes no symlinks.
  #
  # ArgumentError is raised when it cannot find a relative path.
  #
  # This method has existed since 1.8.1.
  #
  def relative_path_from(base_directory)
    dest_directory = self.cleanpath.to_s
    base_directory = base_directory.cleanpath.to_s
    dest_prefix = dest_directory
    dest_names = []
    while r = chop_basename(dest_prefix)
      dest_prefix, basename = r
      dest_names.unshift basename if basename != '.'
    end
    base_prefix = base_directory
    base_names = []
    while r = chop_basename(base_prefix)
      base_prefix, basename = r
      base_names.unshift basename if basename != '.'
    end
    unless SAME_PATHS[dest_prefix, base_prefix]
      raise ArgumentError, "different prefix: #{dest_prefix.inspect} and #{base_directory.inspect}"
    end
    while !dest_names.empty? &&
          !base_names.empty? &&
          SAME_PATHS[dest_names.first, base_names.first]
      dest_names.shift
      base_names.shift
    end
    if base_names.include? '..'
      raise ArgumentError, "base_directory has ..: #{base_directory.inspect}"
    end
    base_names.fill('..')
    relpath_names = base_names + dest_names
    if relpath_names.empty?
      Pathname.new('.')
    else
      Pathname.new(File.join(*relpath_names))
    end
  end
end

class Pathname    # * IO *
  #
  # #each_line iterates over the line in the file.  It yields a String object
  # for each line.
  #
  # This method has existed since 1.8.1.
  #
  def each_line(*args, &block) # :yield: line
    IO.foreach(@path, *args, &block)
  end

  # Pathname#foreachline is *obsoleted* at 1.8.1.  Use #each_line.
  def foreachline(*args, &block)
    warn "Pathname#foreachline is obsoleted.  Use Pathname#each_line."
    each_line(*args, &block)
  end

  # See <tt>IO.read</tt>.  Returns all the bytes from the file, or the first +N+
  # if specified.
  def read(*args) IO.read(@path, *args) end

  # See <tt>IO.readlines</tt>.  Returns all the lines from the file.
  def readlines(*args) IO.readlines(@path, *args) end

  # See <tt>IO.sysopen</tt>.
  def sysopen(*args) IO.sysopen(@path, *args) end
end


class Pathname    # * File *

  # See <tt>File.atime</tt>.  Returns last access time.
  def atime() File.atime(@path) end

  # See <tt>File.ctime</tt>.  Returns last (directory entry, not file) change time.
  def ctime() File.ctime(@path) end

  # See <tt>File.mtime</tt>.  Returns last modification time.
  def mtime() File.mtime(@path) end

  # See <tt>File.chmod</tt>.  Changes permissions.
  def chmod(mode) File.chmod(mode, @path) end

  # See <tt>File.lchmod</tt>.
  def lchmod(mode) File.lchmod(mode, @path) end

  # See <tt>File.chown</tt>.  Change owner and group of file.
  def chown(owner, group) File.chown(owner, group, @path) end

  # See <tt>File.lchown</tt>.
  def lchown(owner, group) File.lchown(owner, group, @path) end

  # See <tt>File.fnmatch</tt>.  Return +true+ if the receiver matches the given
  # pattern.
  def fnmatch(pattern, *args) File.fnmatch(pattern, @path, *args) end

  # See <tt>File.fnmatch?</tt> (same as #fnmatch).
  def fnmatch?(pattern, *args) File.fnmatch?(pattern, @path, *args) end

  # See <tt>File.ftype</tt>.  Returns "type" of file ("file", "directory",
  # etc).
  def ftype() File.ftype(@path) end

  # See <tt>File.link</tt>.  Creates a hard link.
  def make_link(old) File.link(old, @path) end

  # See <tt>File.open</tt>.  Opens the file for reading or writing.
  def open(*args, &block) # :yield: file
    File.open(@path, *args, &block)
  end

  # See <tt>File.readlink</tt>.  Read symbolic link.
  def readlink() self.class.new(File.readlink(@path)) end

  # See <tt>File.rename</tt>.  Rename the file.
  def rename(to) File.rename(@path, to) end

  # See <tt>File.stat</tt>.  Returns a <tt>File::Stat</tt> object.
  def stat() File.stat(@path) end

  # See <tt>File.lstat</tt>.
  def lstat() File.lstat(@path) end

  # See <tt>File.symlink</tt>.  Creates a symbolic link.
  def make_symlink(old) File.symlink(old, @path) end

  # See <tt>File.truncate</tt>.  Truncate the file to +length+ bytes.
  def truncate(length) File.truncate(@path, length) end

  # See <tt>File.utime</tt>.  Update the access and modification times.
  def utime(atime, mtime) File.utime(atime, mtime, @path) end

  # See <tt>File.basename</tt>.  Returns the last component of the path.
  def basename(*args) self.class.new(File.basename(@path, *args)) end

  # See <tt>File.dirname</tt>.  Returns all but the last component of the path.
  def dirname() self.class.new(File.dirname(@path)) end

  # See <tt>File.extname</tt>.  Returns the file's extension.
  def extname() File.extname(@path) end

  # See <tt>File.expand_path</tt>.
  def expand_path(*args) self.class.new(File.expand_path(@path, *args)) end

  # See <tt>File.split</tt>.  Returns the #dirname and the #basename in an
  # Array.
  def split() File.split(@path).map {|f| self.class.new(f) } end

  # Pathname#link is confusing and *obsoleted* because the receiver/argument
  # order is inverted to corresponding system call.
  def link(old)
    warn 'Pathname#link is obsoleted.  Use Pathname#make_link.'
    File.link(old, @path)
  end

  # Pathname#symlink is confusing and *obsoleted* because the receiver/argument
  # order is inverted to corresponding system call.
  def symlink(old)
    warn 'Pathname#symlink is obsoleted.  Use Pathname#make_symlink.'
    File.symlink(old, @path)
  end
end


class Pathname    # * FileTest *

  # See <tt>FileTest.blockdev?</tt>.
  def blockdev?() FileTest.blockdev?(@path) end

  # See <tt>FileTest.chardev?</tt>.
  def chardev?() FileTest.chardev?(@path) end

  # See <tt>FileTest.executable?</tt>.
  def executable?() FileTest.executable?(@path) end

  # See <tt>FileTest.executable_real?</tt>.
  def executable_real?() FileTest.executable_real?(@path) end

  # See <tt>FileTest.exist?</tt>.
  def exist?() FileTest.exist?(@path) end

  # See <tt>FileTest.grpowned?</tt>.
  def grpowned?() FileTest.grpowned?(@path) end

  # See <tt>FileTest.directory?</tt>.
  def directory?() FileTest.directory?(@path) end

  # See <tt>FileTest.file?</tt>.
  def file?() FileTest.file?(@path) end

  # See <tt>FileTest.pipe?</tt>.
  def pipe?() FileTest.pipe?(@path) end

  # See <tt>FileTest.socket?</tt>.
  def socket?() FileTest.socket?(@path) end

  # See <tt>FileTest.owned?</tt>.
  def owned?() FileTest.owned?(@path) end

  # See <tt>FileTest.readable?</tt>.
  def readable?() FileTest.readable?(@path) end

  # See <tt>FileTest.world_readable?</tt>.
  def world_readable?() FileTest.world_readable?(@path) end

  # See <tt>FileTest.readable_real?</tt>.
  def readable_real?() FileTest.readable_real?(@path) end

  # See <tt>FileTest.setuid?</tt>.
  def setuid?() FileTest.setuid?(@path) end

  # See <tt>FileTest.setgid?</tt>.
  def setgid?() FileTest.setgid?(@path) end

  # See <tt>FileTest.size</tt>.
  def size() FileTest.size(@path) end

  # See <tt>FileTest.size?</tt>.
  def size?() FileTest.size?(@path) end

  # See <tt>FileTest.sticky?</tt>.
  def sticky?() FileTest.sticky?(@path) end

  # See <tt>FileTest.symlink?</tt>.
  def symlink?() FileTest.symlink?(@path) end

  # See <tt>FileTest.writable?</tt>.
  def writable?() FileTest.writable?(@path) end

  # See <tt>FileTest.world_writable?</tt>.
  def world_writable?() FileTest.world_writable?(@path) end

  # See <tt>FileTest.writable_real?</tt>.
  def writable_real?() FileTest.writable_real?(@path) end

  # See <tt>FileTest.zero?</tt>.
  def zero?() FileTest.zero?(@path) end
end


class Pathname    # * Dir *
  # See <tt>Dir.glob</tt>.  Returns or yields Pathname objects.
  def Pathname.glob(*args) # :yield: p
    if block_given?
      Dir.glob(*args) {|f| yield self.new(f) }
    else
      Dir.glob(*args).map {|f| self.new(f) }
    end
  end

  # See <tt>Dir.getwd</tt>.  Returns the current working directory as a Pathname.
  def Pathname.getwd() self.new(Dir.getwd) end
  class << self; alias pwd getwd end

  # Pathname#chdir is *obsoleted* at 1.8.1.
  def chdir(&block)
    warn "Pathname#chdir is obsoleted.  Use Dir.chdir."
    Dir.chdir(@path, &block)
  end

  # Pathname#chroot is *obsoleted* at 1.8.1.
  def chroot
    warn "Pathname#chroot is obsoleted.  Use Dir.chroot."
    Dir.chroot(@path)
  end

  # Return the entries (files and subdirectories) in the directory, each as a
  # Pathname object.
  def entries() Dir.entries(@path).map {|f| self.class.new(f) } end

  # Iterates over the entries (files and subdirectories) in the directory.  It
  # yields a Pathname object for each entry.
  #
  # This method has existed since 1.8.1.
  def each_entry(&block) # :yield: p
    Dir.foreach(@path) {|f| yield self.class.new(f) }
  end

  # Pathname#dir_foreach is *obsoleted* at 1.8.1.
  def dir_foreach(*args, &block)
    warn "Pathname#dir_foreach is obsoleted.  Use Pathname#each_entry."
    each_entry(*args, &block)
  end

  # See <tt>Dir.mkdir</tt>.  Create the referenced directory.
  def mkdir(*args) Dir.mkdir(@path, *args) end

  # See <tt>Dir.rmdir</tt>.  Remove the referenced directory.
  def rmdir() Dir.rmdir(@path) end

  # See <tt>Dir.open</tt>.
  def opendir(&block) # :yield: dir
    Dir.open(@path, &block)
  end
end


class Pathname    # * Find *
  #
  # Pathname#find is an iterator to traverse a directory tree in a depth first
  # manner.  It yields a Pathname for each file under "this" directory.
  #
  # Since it is implemented by <tt>find.rb</tt>, <tt>Find.prune</tt> can be used
  # to control the traverse.
  #
  # If +self+ is <tt>.</tt>, yielded pathnames begin with a filename in the
  # current directory, not <tt>./</tt>.
  #
  def find(&block) # :yield: p
    require 'find'
    if @path == '.'
      Find.find(@path) {|f| yield self.class.new(f.sub(%r{\A\./}, '')) }
    else
      Find.find(@path) {|f| yield self.class.new(f) }
    end
  end
end


class Pathname    # * FileUtils *
  # See <tt>FileUtils.mkpath</tt>.  Creates a full path, including any
  # intermediate directories that don't yet exist.
  def mkpath
    require 'fileutils'
    FileUtils.mkpath(@path)
    nil
  end

  # See <tt>FileUtils.rm_r</tt>.  Deletes a directory and all beneath it.
  def rmtree
    # The name "rmtree" is borrowed from File::Path of Perl.
    # File::Path provides "mkpath" and "rmtree".
    require 'fileutils'
    FileUtils.rm_r(@path)
    nil
  end
end


class Pathname    # * mixed *
  # Removes a file or directory, using <tt>File.unlink</tt> or
  # <tt>Dir.unlink</tt> as necessary.
  def unlink()
    begin
      Dir.unlink @path
    rescue Errno::ENOTDIR
      File.unlink @path
    end
  end
  alias delete unlink

  # This method is *obsoleted* at 1.8.1.  Use #each_line or #each_entry.
  def foreach(*args, &block)
    warn "Pathname#foreach is obsoleted.  Use each_line or each_entry."
    if FileTest.directory? @path
      # For polymorphism between Dir.foreach and IO.foreach,
      # Pathname#foreach doesn't yield Pathname object.
      Dir.foreach(@path, *args, &block)
    else
      IO.foreach(@path, *args, &block)
    end
  end
end

module Kernel
  # create a pathname object.
  #
  # This method is available since 1.8.5.
  def Pathname(path) # :doc:
    Pathname.new(path)
  end
  private :Pathname
end
PK     Z\$+j      irb.rbnu [        #
#   irb.rb - irb main module
#   	$Release Version: 0.9.5 $
#   	$Revision: 24483 $
#   	$Date: 2009-08-09 17:44:15 +0900 (Sun, 09 Aug 2009) $
#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#
#
require "e2mmap"

require "irb/init"
require "irb/context"
require "irb/extend-command"
#require "irb/workspace"

require "irb/ruby-lex"
require "irb/input-method"
require "irb/locale"

STDOUT.sync = true

module IRB
  @RCS_ID='-$Id: irb.rb 24483 2009-08-09 08:44:15Z shyouhei $-'

  class Abort < Exception;end

  #
  @CONF = {}

  def IRB.conf
    @CONF
  end

  # IRB version method
  def IRB.version
    if v = @CONF[:VERSION] then return v end

    require "irb/version"
    rv = @RELEASE_VERSION.sub(/\.0/, "")
    @CONF[:VERSION] = format("irb %s(%s)", rv, @LAST_UPDATE_DATE)
  end

  def IRB.CurrentContext
    IRB.conf[:MAIN_CONTEXT]
  end

  # initialize IRB and start TOP_LEVEL irb
  def IRB.start(ap_path = nil)
    $0 = File::basename(ap_path, ".rb") if ap_path

    IRB.setup(ap_path)

    if @CONF[:SCRIPT]
      irb = Irb.new(nil, @CONF[:SCRIPT])
    else
      irb = Irb.new
    end

    @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
    @CONF[:MAIN_CONTEXT] = irb.context

    trap("SIGINT") do
      irb.signal_handle
    end

    begin
      catch(:IRB_EXIT) do
	irb.eval_input
      end
    ensure
      irb_at_exit
    end
#    print "\n"
  end

  def IRB.irb_at_exit
    @CONF[:AT_EXIT].each{|hook| hook.call}
  end

  def IRB.irb_exit(irb, ret)
    throw :IRB_EXIT, ret
  end

  def IRB.irb_abort(irb, exception = Abort)
    if defined? Thread
      irb.context.thread.raise exception, "abort then interrupt!!"
    else
      raise exception, "abort then interrupt!!"
    end
  end

  #
  # irb interpriter main routine 
  #
  class Irb
    def initialize(workspace = nil, input_method = nil, output_method = nil)
      @context = Context.new(self, workspace, input_method, output_method)
      @context.main.extend ExtendCommandBundle
      @signal_status = :IN_IRB

      @scanner = RubyLex.new
      @scanner.exception_on_syntax_error = false
    end
    attr_reader :context
    attr_accessor :scanner

    def eval_input
      @scanner.set_prompt do
	|ltype, indent, continue, line_no|
	if ltype
	  f = @context.prompt_s
	elsif continue
	  f = @context.prompt_c
	elsif indent > 0
	  f = @context.prompt_n
	else @context.prompt_i
	  f = @context.prompt_i
	end
	f = "" unless f
	if @context.prompting?
	  @context.io.prompt = p = prompt(f, ltype, indent, line_no)
	else
	  @context.io.prompt = p = ""
	end
	if @context.auto_indent_mode
	  unless ltype
            ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
	      indent * 2 - p.size
	    ind += 2 if continue
	    @context.io.prompt = p + " " * ind if ind > 0
	  end
	end
      end
       
      @scanner.set_input(@context.io) do
	signal_status(:IN_INPUT) do
	  if l = @context.io.gets
	    print l if @context.verbose?
	  else
	    if @context.ignore_eof? and @context.io.readable_atfer_eof?
	      l = "\n"
	      if @context.verbose?
		printf "Use \"exit\" to leave %s\n", @context.ap_name
	      end
	    end
	  end
	  l
	end
      end

      @scanner.each_top_level_statement do |line, line_no|
	signal_status(:IN_EVAL) do
	  begin
            line.untaint
	    @context.evaluate(line, line_no)
	    output_value if @context.echo?
	    exc = nil
	  rescue Interrupt => exc
	  rescue SystemExit, SignalException
	    raise
	  rescue Exception => exc
	  end
	  if exc
	    print exc.class, ": ", exc, "\n"
	    if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/
	      irb_bug = true 
	    else
	      irb_bug = false
	    end
	    
	    messages = []
	    lasts = []
	    levels = 0
	    for m in exc.backtrace
	      m = @context.workspace.filter_backtrace(m) unless irb_bug
	      if m
		if messages.size < @context.back_trace_limit
		  messages.push "\tfrom "+m
		else
		  lasts.push "\tfrom "+m
		  if lasts.size > @context.back_trace_limit
		    lasts.shift 
		    levels += 1
		  end
		end
	      end
	    end
	    print messages.join("\n"), "\n"
	    unless lasts.empty?
	      printf "... %d levels...\n", levels if levels > 0
	      print lasts.join("\n")
	    end
	    print "Maybe IRB bug!!\n" if irb_bug
	  end
          if $SAFE > 2
            abort "Error: irb does not work for $SAFE level higher than 2"
          end
	end
      end
    end

    def suspend_name(path = nil, name = nil)
      @context.irb_path, back_path = path, @context.irb_path if path
      @context.irb_name, back_name = name, @context.irb_name if name
      begin
	yield back_path, back_name
      ensure
	@context.irb_path = back_path if path
	@context.irb_name = back_name if name
      end
    end

    def suspend_workspace(workspace)
      @context.workspace, back_workspace = workspace, @context.workspace
      begin
	yield back_workspace
      ensure
	@context.workspace = back_workspace
      end
    end

    def suspend_input_method(input_method)
      back_io = @context.io
      @context.instance_eval{@io = input_method}
      begin
	yield back_io
      ensure
	@context.instance_eval{@io = back_io}
      end
    end

    def suspend_context(context)
      @context, back_context = context, @context
      begin
	yield back_context
      ensure
	@context = back_context
      end
    end

    def signal_handle
      unless @context.ignore_sigint?
	print "\nabort!!\n" if @context.verbose?
	exit
      end

      case @signal_status
      when :IN_INPUT
	print "^C\n"
	raise RubyLex::TerminateLineInput
      when :IN_EVAL
	IRB.irb_abort(self)
      when :IN_LOAD
	IRB.irb_abort(self, LoadAbort)
      when :IN_IRB
	# ignore
      else
	# ignore other cases as well
      end
    end

    def signal_status(status)
      return yield if @signal_status == :IN_LOAD

      signal_status_back = @signal_status
      @signal_status = status
      begin
	yield
      ensure
	@signal_status = signal_status_back
      end
    end

    def prompt(prompt, ltype, indent, line_no)
      p = prompt.dup
      p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
	case $2
	when "N"
	  @context.irb_name
	when "m"
	  @context.main.to_s
	when "M"
	  @context.main.inspect
	when "l"
	  ltype
	when "i"
	  if $1 
	    format("%" + $1 + "d", indent)
	  else
	    indent.to_s
	  end
	when "n"
	  if $1 
	    format("%" + $1 + "d", line_no)
	  else
	    line_no.to_s
	  end
	when "%"
	  "%"
	end
      end
      p
    end

    def output_value
      if @context.inspect?
        printf @context.return_format, @context.last_value.inspect
      else
        printf @context.return_format, @context.last_value
      end
    end

    def inspect
      ary = []
      for iv in instance_variables
	case iv
	when "@signal_status"
	  ary.push format("%s=:%s", iv, @signal_status.id2name)
	when "@context"
	  ary.push format("%s=%s", iv, eval(iv).__to_s__)
	else
	  ary.push format("%s=%s", iv, eval(iv))
	end
      end
      format("#<%s: %s>", self.class, ary.join(", "))
    end
  end

  # Singleton method
  def @CONF.inspect
    IRB.version unless self[:VERSION]

    array = []
    for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
      case k
      when :MAIN_CONTEXT, :__TMP__EHV__
	array.push format("CONF[:%s]=...myself...", k.id2name)
      when :PROMPT
	s = v.collect{
	  |kk, vv|
	  ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
	  format(":%s=>{%s}", kk.id2name, ss.join(", "))
	}
	array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
      else
	array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
      end
    end
    array.join("\n")
  end
end
PK     Z\U      uri/https.rbnu [        #
# = uri/https.rb
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# License:: You can redistribute it and/or modify it under the same term as Ruby.
# Revision:: $Id: https.rb 11747 2007-02-15 02:41:45Z knu $
#

require 'uri/http'

module URI

  # The default port for HTTPS URIs is 443, and the scheme is 'https:' rather
  # than 'http:'. Other than that, HTTPS URIs are identical to HTTP URIs;
  # see URI::HTTP.
  class HTTPS < HTTP
    DEFAULT_PORT = 443
  end
  @@schemes['HTTPS'] = HTTPS
end
PK     Z\?      uri/ldaps.rbnu [        require 'uri/ldap'

module URI

  # The default port for LDAPS URIs is 636, and the scheme is 'ldaps:' rather
  # than 'ldap:'. Other than that, LDAPS URIs are identical to LDAP URIs;
  # see URI::LDAP.
  class LDAPS < LDAP
    DEFAULT_PORT = 636
  end
  @@schemes['LDAPS'] = LDAPS
end
PK     Z\(p0Z
  Z
    uri/http.rbnu [        #
# = uri/http.rb
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# License:: You can redistribute it and/or modify it under the same term as Ruby.
# Revision:: $Id: http.rb 11747 2007-02-15 02:41:45Z knu $
#

require 'uri/generic'

module URI

  #
  # The syntax of HTTP URIs is defined in RFC1738 section 3.3.
  #
  # Note that the Ruby URI library allows HTTP URLs containing usernames and
  # passwords. This is not legal as per the RFC, but used to be 
  # supported in Internet Explorer 5 and 6, before the MS04-004 security 
  # update. See <URL:http://support.microsoft.com/kb/834489>.
  #
  class HTTP < Generic
    DEFAULT_PORT = 80

    COMPONENT = [
      :scheme, 
      :userinfo, :host, :port, 
      :path, 
      :query, 
      :fragment
    ].freeze

    #
    # == Description
    #
    # Create a new URI::HTTP object from components, with syntax checking.
    #
    # The components accepted are userinfo, host, port, path, query and
    # fragment.
    #
    # The components should be provided either as an Array, or as a Hash 
    # with keys formed by preceding the component names with a colon. 
    #
    # If an Array is used, the components must be passed in the order
    # [userinfo, host, port, path, query, fragment].
    #
    # Example:
    #
    #     newuri = URI::HTTP.build({:host => 'www.example.com', 
    #       :path> => '/foo/bar'})
    #
    #     newuri = URI::HTTP.build([nil, "www.example.com", nil, "/path", 
    #       "query", 'fragment'])
    #
    # Currently, if passed userinfo components this method generates 
    # invalid HTTP URIs as per RFC 1738.
    #
    def self.build(args)
      tmp = Util::make_components_hash(self, args)
      return super(tmp)
    end

    #
    # == Description
    #
    # Create a new URI::HTTP object from generic URI components as per
    # RFC 2396. No HTTP-specific syntax checking (as per RFC 1738) is 
    # performed.
    #
    # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+, 
    # +opaque+, +query+ and +fragment+, in that order.
    #
    # Example:
    #
    #     uri = URI::HTTP.new(['http', nil, "www.example.com", nil, "/path",
    #       "query", 'fragment'])
    #
    def initialize(*arg)
      super(*arg)
    end

    #
    # == Description
    #
    # Returns the full path for an HTTP request, as required by Net::HTTP::Get.
    #
    # If the URI contains a query, the full path is URI#path + '?' + URI#query.
    # Otherwise, the path is simply URI#path.
    #
    def request_uri
      r = path_query
      if r[0] != ?/
        r = '/' + r
      end

      r
    end
  end

  @@schemes['HTTP'] = HTTP
end
PK     Z\OKi      uri/ldap.rbnu [        #
# = uri/ldap.rb
#
# Author:: 
#  Takaaki Tateishi <ttate@jaist.ac.jp>
#  Akira Yamada <akira@ruby-lang.org>
# License:: 
#   URI::LDAP is copyrighted free software by Takaaki Tateishi and Akira Yamada.
#   You can redistribute it and/or modify it under the same term as Ruby.
# Revision:: $Id: ldap.rb 11708 2007-02-12 23:01:19Z shyouhei $
#

require 'uri/generic'

module URI

  #
  # LDAP URI SCHEMA (described in RFC2255)
  # ldap://<host>/<dn>[?<attrs>[?<scope>[?<filter>[?<extensions>]]]]
  #
  class LDAP < Generic

    DEFAULT_PORT = 389
    
    COMPONENT = [
      :scheme,
      :host, :port,
      :dn,
      :attributes,
      :scope,
      :filter,
      :extensions,
    ].freeze

    SCOPE = [
      SCOPE_ONE = 'one',
      SCOPE_SUB = 'sub',
      SCOPE_BASE = 'base',
    ].freeze

    def self.build(args)
      tmp = Util::make_components_hash(self, args)

      if tmp[:dn]
        tmp[:path] = tmp[:dn]
      end

      query = []
      [:extensions, :filter, :scope, :attributes].collect do |x|
        next if !tmp[x] && query.size == 0
        query.unshift(tmp[x])
      end

      tmp[:query] = query.join('?')

      return super(tmp)
    end

    def initialize(*arg)
      super(*arg)

      if @fragment
        raise InvalidURIError, 'bad LDAP URL'
      end

      parse_dn
      parse_query
    end

    def parse_dn
      @dn = @path[1..-1]
    end
    private :parse_dn

    def parse_query
      @attributes = nil
      @scope      = nil
      @filter     = nil
      @extensions = nil

      if @query
        attrs, scope, filter, extensions = @query.split('?')

        @attributes = attrs if attrs && attrs.size > 0
        @scope      = scope if scope && scope.size > 0
        @filter     = filter if filter && filter.size > 0
        @extensions = extensions if extensions && extensions.size > 0
      end
    end
    private :parse_query

    def build_path_query
      @path = '/' + @dn

      query = []
      [@extensions, @filter, @scope, @attributes].each do |x|
        next if !x && query.size == 0
        query.unshift(x)
      end
      @query = query.join('?')
    end
    private :build_path_query

    def dn
      @dn
    end

    def set_dn(val)
      @dn = val
      build_path_query
      @dn
    end
    protected :set_dn

    def dn=(val)
      set_dn(val)
      val
    end

    def attributes
      @attributes
    end

    def set_attributes(val)
      @attributes = val
      build_path_query
      @attributes
    end
    protected :set_attributes

    def attributes=(val)
      set_attributes(val)
      val
    end

    def scope
      @scope
    end

    def set_scope(val)
      @scope = val
      build_path_query
      @scope
    end
    protected :set_scope

    def scope=(val)
      set_scope(val)
      val
    end

    def filter
      @filter
    end

    def set_filter(val)
      @filter = val
      build_path_query
      @filter
    end
    protected :set_filter

    def filter=(val)
      set_filter(val)
      val
    end

    def extensions
      @extensions
    end

    def set_extensions(val)
      @extensions = val
      build_path_query
      @extensions
    end
    protected :set_extensions

    def extensions=(val)
      set_extensions(val)
      val
    end

    def hierarchical?
      false
    end
  end

  @@schemes['LDAP'] = LDAP
end
PK     Z\͇MX^  X^    uri/generic.rbnu [        #
# = uri/generic.rb
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# License:: You can redistribute it and/or modify it under the same term as Ruby.
# Revision:: $Id: generic.rb 31666 2011-05-20 22:29:17Z shyouhei $
#

require 'uri/common'

module URI
  
  #
  # Base class for all URI classes.
  # Implements generic URI syntax as per RFC 2396.
  #
  class Generic
    include URI
    include REGEXP

    DEFAULT_PORT = nil

    #
    # Returns default port
    #
    def self.default_port
      self::DEFAULT_PORT
    end

    def default_port
      self.class.default_port
    end

    COMPONENT = [
      :scheme, 
      :userinfo, :host, :port, :registry, 
      :path, :opaque, 
      :query, 
      :fragment
    ].freeze

    #
    # Components of the URI in the order.
    #
    def self.component
      self::COMPONENT
    end

    USE_REGISTRY = false

    #
    # DOC: FIXME!
    #
    def self.use_registry
      self::USE_REGISTRY
    end

    #
    # == Synopsis
    #
    # See #new
    #
    # == Description
    #
    # At first, tries to create a new URI::Generic instance using
    # URI::Generic::build. But, if exception URI::InvalidComponentError is raised, 
    # then it URI::Escape.escape all URI components and tries again.
    #
    #
    def self.build2(args)
      begin
        return self.build(args)
      rescue InvalidComponentError
        if args.kind_of?(Array)
          return self.build(args.collect{|x| 
            if x
              URI.escape(x)
            else
              x
            end
          })
        elsif args.kind_of?(Hash)
          tmp = {}
          args.each do |key, value|
            tmp[key] = if value
                URI.escape(value)
              else
                value
              end
          end
          return self.build(tmp)
        end
      end
    end

    #
    # == Synopsis
    #
    # See #new
    #
    # == Description
    #
    # Creates a new URI::Generic instance from components of URI::Generic
    # with check.  Components are: scheme, userinfo, host, port, registry, path,
    # opaque, query and fragment. You can provide arguments either by an Array or a Hash.
    # See #new for hash keys to use or for order of array items.
    #
    def self.build(args)
      if args.kind_of?(Array) &&
          args.size == ::URI::Generic::COMPONENT.size
        tmp = args
      elsif args.kind_of?(Hash)
        tmp = ::URI::Generic::COMPONENT.collect do |c|
          if args.include?(c)
            args[c]
          else
            nil
          end
        end
      else
        raise ArgumentError, 
        "expected Array of or Hash of components of #{self.class} (#{self.class.component.join(', ')})"
      end

      tmp << true
      return self.new(*tmp)
    end
    #
    # == Args
    #
    # +scheme+::
    #   Protocol scheme, i.e. 'http','ftp','mailto' and so on.
    # +userinfo+::
    #   User name and password, i.e. 'sdmitry:bla'
    # +host+::
    #   Server host name
    # +port+::
    #   Server port
    # +registry+::
    #   DOC: FIXME!
    # +path+::
    #   Path on server
    # +opaque+::
    #   DOC: FIXME!
    # +query+::
    #   Query data
    # +fragment+::
    #   A part of URI after '#' sign
    # +arg_check+::
    #   Check arguments [false by default]
    #
    # == Description
    #
    # Creates a new URI::Generic instance from ``generic'' components without check.
    #
    def initialize(scheme, 
                   userinfo, host, port, registry, 
                   path, opaque, 
                   query, 
                   fragment,
                   arg_check = false)
      @scheme = nil
      @user = nil
      @password = nil
      @host = nil
      @port = nil
      @path = nil
      @query = nil
      @opaque = nil
      @registry = nil
      @fragment = nil

      if arg_check
        self.scheme = scheme
        self.userinfo = userinfo
        self.host = host
        self.port = port
        self.path = path
        self.query = query
        self.opaque = opaque
        self.registry = registry
        self.fragment = fragment
      else
        self.set_scheme(scheme)
        self.set_userinfo(userinfo)
        self.set_host(host)
        self.set_port(port)
        self.set_path(path)
        self.set_query(query)
        self.set_opaque(opaque)
        self.set_registry(registry)
        self.set_fragment(fragment)
      end
      if @registry && !self.class.use_registry
        raise InvalidURIError, 
          "the scheme #{@scheme} does not accept registry part: #{@registry} (or bad hostname?)"
      end
      
      @scheme.freeze if @scheme
      self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2)
      self.set_port(self.default_port) if self.default_port && !@port
    end
    attr_reader :scheme
    attr_reader :host
    attr_reader :port
    attr_reader :registry
    attr_reader :path
    attr_reader :query
    attr_reader :opaque
    attr_reader :fragment

    # replace self by other URI object
    def replace!(oth)
      if self.class != oth.class
        raise ArgumentError, "expected #{self.class} object"
      end

      component.each do |c|
        self.__send__("#{c}=", oth.__send__(c))
      end
    end
    private :replace!

    def component
      self.class.component
    end

    def check_scheme(v)
      if v && SCHEME !~ v
        raise InvalidComponentError,
          "bad component(expected scheme component): #{v}"
      end

      return true
    end
    private :check_scheme

    def set_scheme(v)
      @scheme = v
    end
    protected :set_scheme

    def scheme=(v)
      check_scheme(v)
      set_scheme(v)
      v
    end

    def check_userinfo(user, password = nil)
      if !password
        user, password = split_userinfo(user)
      end
      check_user(user)
      check_password(password, user)

      return true
    end
    private :check_userinfo

    def check_user(v)
      if @registry || @opaque
        raise InvalidURIError, 
          "can not set user with registry or opaque"
      end

      return v unless v

      if USERINFO !~ v
        raise InvalidComponentError,
          "bad component(expected userinfo component or user component): #{v}"
      end

      return true
    end
    private :check_user

    def check_password(v, user = @user)
      if @registry || @opaque
        raise InvalidURIError, 
          "can not set password with registry or opaque"
      end
      return v unless v

      if !user
        raise InvalidURIError,
          "password component depends user component"
      end

      if USERINFO !~ v
        raise InvalidComponentError,
          "bad component(expected user component): #{v}"
      end

      return true
    end
    private :check_password

    #
    # Sets userinfo, argument is string like 'name:pass'
    #
    def userinfo=(userinfo)
      if userinfo.nil?
        return nil
      end
      check_userinfo(*userinfo)
      set_userinfo(*userinfo)
      # returns userinfo
    end

    def user=(user)
      check_user(user)
      set_user(user)
      # returns user
    end
    
    def password=(password)
      check_password(password)
      set_password(password)
      # returns password
    end

    def set_userinfo(user, password = nil)
      unless password 
        user, password = split_userinfo(user)
      end
      @user     = user
      @password = password if password

      [@user, @password]
    end
    protected :set_userinfo

    def set_user(v)
      set_userinfo(v, @password)
      v
    end
    protected :set_user

    def set_password(v)
      @password = v
      # returns v
    end
    protected :set_password

    def split_userinfo(ui)
      return nil, nil unless ui
      user, password = ui.split(/:/, 2)

      return user, password
    end
    private :split_userinfo

    def escape_userpass(v)
      v = URI.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/
    end
    private :escape_userpass

    def userinfo
      if @user.nil?
        nil
      elsif @password.nil?
        @user
      else
        @user + ':' + @password
      end
    end

    def user
      @user
    end

    def password
      @password
    end

    def check_host(v)
      return v unless v

      if @registry || @opaque
        raise InvalidURIError, 
          "can not set host with registry or opaque"
      elsif HOST !~ v
        raise InvalidComponentError,
          "bad component(expected host component): #{v}"
      end

      return true
    end
    private :check_host

    def set_host(v)
      @host = v
    end
    protected :set_host

    def host=(v)
      check_host(v)
      set_host(v)
      v
    end

    def check_port(v)
      return v unless v

      if @registry || @opaque
        raise InvalidURIError, 
          "can not set port with registry or opaque"
      elsif !v.kind_of?(Fixnum) && PORT !~ v
        raise InvalidComponentError,
          "bad component(expected port component): #{v}"
      end

      return true
    end
    private :check_port

    def set_port(v)
      unless !v || v.kind_of?(Fixnum)
        if v.empty?
          v = nil
        else
          v = v.to_i
        end
      end
      @port = v
    end
    protected :set_port

    def port=(v)
      check_port(v)
      set_port(v)
      port
    end

    def check_registry(v)
      return v unless v

      # raise if both server and registry are not nil, because:
      # authority     = server | reg_name
      # server        = [ [ userinfo "@" ] hostport ]
      if @host || @port || @user # userinfo = @user + ':' + @password
        raise InvalidURIError, 
          "can not set registry with host, port, or userinfo"
      elsif v && REGISTRY !~ v
        raise InvalidComponentError,
          "bad component(expected registry component): #{v}"
      end

      return true
    end
    private :check_registry

    def set_registry(v)
      @registry = v
    end
    protected :set_registry

    def registry=(v)
      check_registry(v)
      set_registry(v)
      v
    end

    def check_path(v)
      # raise if both hier and opaque are not nil, because:
      # absoluteURI   = scheme ":" ( hier_part | opaque_part )
      # hier_part     = ( net_path | abs_path ) [ "?" query ]
      if v && @opaque
        raise InvalidURIError, 
          "path conflicts with opaque"
      end

      if @scheme
        if v && v != '' && ABS_PATH !~ v
          raise InvalidComponentError, 
            "bad component(expected absolute path component): #{v}"
        end
      else
        if v && v != '' && ABS_PATH !~ v && REL_PATH !~ v
          raise InvalidComponentError, 
            "bad component(expected relative path component): #{v}"
        end
      end

      return true
    end
    private :check_path

    def set_path(v)
      @path = v
    end
    protected :set_path

    def path=(v)
      check_path(v)
      set_path(v)
      v
    end

    def check_query(v)
      return v unless v

      # raise if both hier and opaque are not nil, because:
      # absoluteURI   = scheme ":" ( hier_part | opaque_part )
      # hier_part     = ( net_path | abs_path ) [ "?" query ]
      if @opaque
        raise InvalidURIError, 
          "query conflicts with opaque"
      end

      if v && v != '' && QUERY !~ v
          raise InvalidComponentError, 
            "bad component(expected query component): #{v}"
        end

      return true
    end
    private :check_query

    def set_query(v)
      @query = v
    end
    protected :set_query

    def query=(v)
      check_query(v)
      set_query(v)
      v
    end

    def check_opaque(v)
      return v unless v

      # raise if both hier and opaque are not nil, because:
      # absoluteURI   = scheme ":" ( hier_part | opaque_part )
      # hier_part     = ( net_path | abs_path ) [ "?" query ]
      if @host || @port || @user || @path  # userinfo = @user + ':' + @password
        raise InvalidURIError, 
          "can not set opaque with host, port, userinfo or path"
      elsif v && OPAQUE !~ v
        raise InvalidComponentError,
          "bad component(expected opaque component): #{v}"
      end

      return true
    end
    private :check_opaque

    def set_opaque(v)
      @opaque = v
    end
    protected :set_opaque

    def opaque=(v)
      check_opaque(v)
      set_opaque(v)
      v
    end

    def check_fragment(v)
      return v unless v

      if v && v != '' && FRAGMENT !~ v
        raise InvalidComponentError, 
          "bad component(expected fragment component): #{v}"
      end

      return true
    end
    private :check_fragment

    def set_fragment(v)
      @fragment = v
    end
    protected :set_fragment

    def fragment=(v)
      check_fragment(v)
      set_fragment(v)
      v
    end

    #
    # Checks if URI has a path
    #
    def hierarchical?
      if @path
        true
      else
        false
      end
    end

    #
    # Checks if URI is an absolute one
    #
    def absolute?
      if @scheme
        true
      else
        false
      end
    end
    alias absolute absolute?

    #
    # Checks if URI is relative
    #
    def relative?
      !absolute?
    end

    def split_path(path)
      path.split(%r{/+}, -1)
    end
    private :split_path

    def merge_path(base, rel)

      # RFC2396, Section 5.2, 5)
      # RFC2396, Section 5.2, 6)
      base_path = split_path(base)
      rel_path  = split_path(rel)

      # RFC2396, Section 5.2, 6), a)
      base_path << '' if base_path.last == '..'
      while i = base_path.index('..')
        base_path.slice!(i - 1, 2)
      end

      if (first = rel_path.first) and first.empty?
        base_path.clear
        rel_path.shift
      end

      # RFC2396, Section 5.2, 6), c)
      # RFC2396, Section 5.2, 6), d)
      rel_path.push('') if rel_path.last == '.' || rel_path.last == '..'
      rel_path.delete('.')

      # RFC2396, Section 5.2, 6), e)
      tmp = []
      rel_path.each do |x|
        if x == '..' &&
            !(tmp.empty? || tmp.last == '..')
          tmp.pop
        else
          tmp << x
        end
      end

      add_trailer_slash = !tmp.empty?
      if base_path.empty?
        base_path = [''] # keep '/' for root directory
      elsif add_trailer_slash
        base_path.pop
      end
      while x = tmp.shift
        if x == '..'
          # RFC2396, Section 4
          # a .. or . in an absolute path has no special meaning
          base_path.pop if base_path.size > 1
        else
          # if x == '..'
          #   valid absolute (but abnormal) path "/../..."
          # else
          #   valid absolute path
          # end
          base_path << x
          tmp.each {|t| base_path << t}
          add_trailer_slash = false
          break
        end
      end
      base_path.push('') if add_trailer_slash

      return base_path.join('/')
    end
    private :merge_path

    #
    # == Args
    #
    # +oth+::
    #    URI or String
    #
    # == Description
    #
    # Destructive form of #merge
    #
    # == Usage
    #
    #   require 'uri'
    #
    #   uri = URI.parse("http://my.example.com")
    #   uri.merge!("/main.rbx?page=1")
    #   p uri
    #   # =>  #<URI::HTTP:0x2021f3b0 URL:http://my.example.com/main.rbx?page=1>
    #
    def merge!(oth)
      t = merge(oth)
      if self == t
        nil
      else
        replace!(t)
        self
      end
    end

    #
    # == Args
    #
    # +oth+::
    #    URI or String
    #
    # == Description
    #
    # Merges two URI's.
    #
    # == Usage
    #
    #   require 'uri'
    #
    #   uri = URI.parse("http://my.example.com")
    #   p uri.merge("/main.rbx?page=1")
    #   # =>  #<URI::HTTP:0x2021f3b0 URL:http://my.example.com/main.rbx?page=1>
    #
    def merge(oth)
      begin
        base, rel = merge0(oth)
      rescue
        raise $!.class, $!.message
      end

      if base == rel
        return base
      end

      authority = rel.userinfo || rel.host || rel.port

      # RFC2396, Section 5.2, 2)
      if (rel.path.nil? || rel.path.empty?) && !authority && !rel.query
        base.set_fragment(rel.fragment) if rel.fragment
        return base
      end

      base.set_query(nil)
      base.set_fragment(nil)

      # RFC2396, Section 5.2, 4)
      if !authority
        base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path
      else
        # RFC2396, Section 5.2, 4)
        base.set_path(rel.path) if rel.path
      end

      # RFC2396, Section 5.2, 7)
      base.set_userinfo(rel.userinfo) if rel.userinfo
      base.set_host(rel.host)         if rel.host
      base.set_port(rel.port)         if rel.port
      base.set_query(rel.query)       if rel.query
      base.set_fragment(rel.fragment) if rel.fragment

      return base
    end # merge
    alias + merge

    # return base and rel.
    # you can modify `base', but can not `rel'.
    def merge0(oth)
      case oth
      when Generic
      when String
        oth = URI.parse(oth)
      else
        raise ArgumentError,
          "bad argument(expected URI object or URI string)"
      end

      if self.relative? && oth.relative?
        raise BadURIError, 
          "both URI are relative"
      end

      if self.absolute? && oth.absolute?
        #raise BadURIError, 
        #  "both URI are absolute"
        # hmm... should return oth for usability?
        return oth, oth
      end

      if self.absolute?
        return self.dup, oth
      else
        return oth, oth
      end
    end
    private :merge0

    def route_from_path(src, dst)
      case dst
      when src
        # RFC2396, Section 4.2
        return ''
      when %r{(?:\A|/)\.\.?(?:/|\z)}
        # dst has abnormal absolute path,
        # like "/./", "/../", "/x/../", ...
        return dst.dup
      end

      src_path = src.scan(%r{(?:\A|[^/]+)/})
      dst_path = dst.scan(%r{(?:\A|[^/]+)/?})

      # discard same parts
      while !dst_path.empty? && dst_path.first == src_path.first
        src_path.shift
        dst_path.shift
      end

      tmp = dst_path.join

      # calculate
      if src_path.empty?
        if tmp.empty?
          return './'
        elsif dst_path.first.include?(':') # (see RFC2396 Section 5)
          return './' + tmp
        else
          return tmp
        end
      end

      return '../' * src_path.size + tmp
    end
    private :route_from_path

    def route_from0(oth)
      case oth
      when Generic
      when String
        oth = URI.parse(oth)
      else
        raise ArgumentError,
          "bad argument(expected URI object or URI string)"
      end

      if self.relative?
        raise BadURIError, 
          "relative URI: #{self}"
      end
      if oth.relative?
        raise BadURIError, 
          "relative URI: #{oth}"
      end

      if self.scheme != oth.scheme
        return self, self.dup
      end
      rel = URI::Generic.new(nil, # it is relative URI
                             self.userinfo, self.host, self.port, 
                             self.registry, self.path, self.opaque,
                             self.query, self.fragment)

      if rel.userinfo != oth.userinfo ||
          rel.host.to_s.downcase != oth.host.to_s.downcase ||
          rel.port != oth.port
	if self.userinfo.nil? && self.host.nil?
	  return self, self.dup
	end
        rel.set_port(nil) if rel.port == oth.default_port
        return rel, rel
      end
      rel.set_userinfo(nil)
      rel.set_host(nil)
      rel.set_port(nil)

      if rel.path && rel.path == oth.path
        rel.set_path('')
        rel.set_query(nil) if rel.query == oth.query
        return rel, rel
      elsif rel.opaque && rel.opaque == oth.opaque
        rel.set_opaque('')
        rel.set_query(nil) if rel.query == oth.query
        return rel, rel
      end

      # you can modify `rel', but can not `oth'.
      return oth, rel
    end
    private :route_from0
    #
    # == Args
    #
    # +oth+::
    #    URI or String
    #
    # == Description
    #
    # Calculates relative path from oth to self
    #
    # == Usage
    #
    #   require 'uri'
    #
    #   uri = URI.parse('http://my.example.com/main.rbx?page=1')
    #   p uri.route_from('http://my.example.com')
    #   #=> #<URI::Generic:0x20218858 URL:/main.rbx?page=1>
    #
    def route_from(oth)
      # you can modify `rel', but can not `oth'.
      begin
        oth, rel = route_from0(oth)
      rescue
        raise $!.class, $!.message
      end
      if oth == rel
        return rel
      end

      rel.set_path(route_from_path(oth.path, self.path))
      if rel.path == './' && self.query
        # "./?foo" -> "?foo"
        rel.set_path('')
      end

      return rel
    end

    alias - route_from

    #
    # == Args
    #
    # +oth+::
    #    URI or String
    #
    # == Description
    #
    # Calculates relative path to oth from self
    #
    # == Usage
    #
    #   require 'uri'
    #
    #   uri = URI.parse('http://my.example.com')
    #   p uri.route_to('http://my.example.com/main.rbx?page=1')
    #   #=> #<URI::Generic:0x2020c2f6 URL:/main.rbx?page=1>
    #    
    def route_to(oth)
      case oth
      when Generic
      when String
        oth = URI.parse(oth)
      else
        raise ArgumentError,
          "bad argument(expected URI object or URI string)"
      end

      oth.route_from(self)
    end

    #
    # Returns normalized URI
    # 
    def normalize
      uri = dup
      uri.normalize!
      uri
    end

    #
    # Destructive version of #normalize
    #
    def normalize!
      if path && path == ''
        set_path('/')
      end
      if host && host != host.downcase
        set_host(self.host.downcase)
      end        
    end

    def path_query
      str = @path
      if @query
        str += '?' + @query
      end
      str
    end
    private :path_query

    #
    # Constructs String from URI
    # 
    def to_s
      str = ''
      if @scheme
        str << @scheme
        str << ':'
      end

      if @opaque
        str << @opaque

      else
        if @registry
          str << @registry
        else
          if @host
            str << '//'
          end
          if self.userinfo
            str << self.userinfo
            str << '@'
          end
          if @host
            str << @host
          end
          if @port && @port != self.default_port
            str << ':'
            str << @port.to_s
          end
        end

        str << path_query
      end

      if @fragment
        str << '#'
        str << @fragment
      end

      str
    end

    #
    # Compares to URI's
    #
    def ==(oth)
      if self.class == oth.class
        self.normalize.component_ary == oth.normalize.component_ary
      else
        false
      end
    end

    def hash
      self.component_ary.hash
    end

    def eql?(oth)
      self.class == oth.class &&
      self.component_ary.eql?(oth.component_ary)
    end

=begin

--- URI::Generic#===(oth)

=end
#    def ===(oth)
#      raise NotImplementedError
#    end

=begin
=end
    def component_ary
      component.collect do |x|
        self.send(x)
      end
    end
    protected :component_ary

    # == Args
    #
    # +components+::
    #    Multiple Symbol arguments defined in URI::HTTP
    #
    # == Description
    #
    # Selects specified components from URI
    #
    # == Usage
    #
    #   require 'uri'
    #
    #   uri = URI.parse('http://myuser:mypass@my.example.com/test.rbx')
    #   p uri.select(:userinfo, :host, :path)
    #   # => ["myuser:mypass", "my.example.com", "/test.rbx"]
    #
    def select(*components)
      components.collect do |c|
        if component.include?(c)
          self.send(c)
        else
          raise ArgumentError, 
            "expected of components of #{self.class} (#{self.class.component.join(', ')})"
        end
      end
    end

    @@to_s = Kernel.instance_method(:to_s)
    def inspect
      @@to_s.bind(self).call.sub!(/>\z/) {" URL:#{self}>"}
    end

    def coerce(oth)
      case oth
      when String
        oth = URI.parse(oth)
      else
        super
      end

      return oth, self
    end
  end
end
PK     Z\/[D  D    uri/common.rbnu [        # = uri/common.rb
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# Revision:: $Id: common.rb 14178 2007-12-10 09:31:55Z matz $
# License:: 
#   You can redistribute it and/or modify it under the same term as Ruby.
#

module URI
  module REGEXP
    #
    # Patterns used to parse URI's
    #
    module PATTERN
      # :stopdoc:

      # RFC 2396 (URI Generic Syntax)
      # RFC 2732 (IPv6 Literal Addresses in URL's)
      # RFC 2373 (IPv6 Addressing Architecture)

      # alpha         = lowalpha | upalpha
      ALPHA = "a-zA-Z"
      # alphanum      = alpha | digit
      ALNUM = "#{ALPHA}\\d"

      # hex           = digit | "A" | "B" | "C" | "D" | "E" | "F" |
      #                         "a" | "b" | "c" | "d" | "e" | "f"
      HEX     = "a-fA-F\\d"
      # escaped       = "%" hex hex
      ESCAPED = "%[#{HEX}]{2}"
      # mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" |
      #                 "(" | ")"
      # unreserved    = alphanum | mark
      UNRESERVED = "-_.!~*'()#{ALNUM}"
      # reserved      = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
      #                 "$" | ","
      # reserved      = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | 
      #                 "$" | "," | "[" | "]" (RFC 2732)
      RESERVED = ";/?:@&=+$,\\[\\]"

      # uric          = reserved | unreserved | escaped
      URIC = "(?:[#{UNRESERVED}#{RESERVED}]|#{ESCAPED})"
      # uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
      #                 "&" | "=" | "+" | "$" | ","
      URIC_NO_SLASH = "(?:[#{UNRESERVED};?:@&=+$,]|#{ESCAPED})"
      # query         = *uric
      QUERY = "#{URIC}*"
      # fragment      = *uric
      FRAGMENT = "#{URIC}*"

      # domainlabel   = alphanum | alphanum *( alphanum | "-" ) alphanum
      DOMLABEL = "(?:[#{ALNUM}](?:[-#{ALNUM}]*[#{ALNUM}])?)"
      # toplabel      = alpha | alpha *( alphanum | "-" ) alphanum
      TOPLABEL = "(?:[#{ALPHA}](?:[-#{ALNUM}]*[#{ALNUM}])?)"
      # hostname      = *( domainlabel "." ) toplabel [ "." ]
      HOSTNAME = "(?:#{DOMLABEL}\\.)*#{TOPLABEL}\\.?"

      # RFC 2373, APPENDIX B:
      # IPv6address = hexpart [ ":" IPv4address ]
      # IPv4address   = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
      # hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ]
      # hexseq  = hex4 *( ":" hex4)
      # hex4    = 1*4HEXDIG
      #
      # XXX: This definition has a flaw. "::" + IPv4address must be
      # allowed too.  Here is a replacement.
      #
      # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
      IPV4ADDR = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"
      # hex4     = 1*4HEXDIG
      HEX4 = "[#{HEX}]{1,4}"
      # lastpart = hex4 | IPv4address
      LASTPART = "(?:#{HEX4}|#{IPV4ADDR})"
      # hexseq1  = *( hex4 ":" ) hex4
      HEXSEQ1 = "(?:#{HEX4}:)*#{HEX4}"
      # hexseq2  = *( hex4 ":" ) lastpart
      HEXSEQ2 = "(?:#{HEX4}:)*#{LASTPART}"
      # IPv6address = hexseq2 | [ hexseq1 ] "::" [ hexseq2 ]
      IPV6ADDR = "(?:#{HEXSEQ2}|(?:#{HEXSEQ1})?::(?:#{HEXSEQ2})?)"

      # IPv6prefix  = ( hexseq1 | [ hexseq1 ] "::" [ hexseq1 ] ) "/" 1*2DIGIT
      # unused

      # ipv6reference = "[" IPv6address "]" (RFC 2732)
      IPV6REF = "\\[#{IPV6ADDR}\\]"

      # host          = hostname | IPv4address
      # host          = hostname | IPv4address | IPv6reference (RFC 2732)
      HOST = "(?:#{HOSTNAME}|#{IPV4ADDR}|#{IPV6REF})"
      # port          = *digit
      PORT = '\d*'
      # hostport      = host [ ":" port ]
      HOSTPORT = "#{HOST}(?::#{PORT})?"

      # userinfo      = *( unreserved | escaped |
      #                    ";" | ":" | "&" | "=" | "+" | "$" | "," )
      USERINFO = "(?:[#{UNRESERVED};:&=+$,]|#{ESCAPED})*"

      # pchar         = unreserved | escaped |
      #                 ":" | "@" | "&" | "=" | "+" | "$" | ","
      PCHAR = "(?:[#{UNRESERVED}:@&=+$,]|#{ESCAPED})"
      # param         = *pchar
      PARAM = "#{PCHAR}*"
      # segment       = *pchar *( ";" param )
      SEGMENT = "#{PCHAR}*(?:;#{PARAM})*"
      # path_segments = segment *( "/" segment )
      PATH_SEGMENTS = "#{SEGMENT}(?:/#{SEGMENT})*"

      # server        = [ [ userinfo "@" ] hostport ]
      SERVER = "(?:#{USERINFO}@)?#{HOSTPORT}"
      # reg_name      = 1*( unreserved | escaped | "$" | "," |
      #                     ";" | ":" | "@" | "&" | "=" | "+" )
      REG_NAME = "(?:[#{UNRESERVED}$,;:@&=+]|#{ESCAPED})+"
      # authority     = server | reg_name
      AUTHORITY = "(?:#{SERVER}|#{REG_NAME})"

      # rel_segment   = 1*( unreserved | escaped |
      #                     ";" | "@" | "&" | "=" | "+" | "$" | "," )
      REL_SEGMENT = "(?:[#{UNRESERVED};@&=+$,]|#{ESCAPED})+"

      # scheme        = alpha *( alpha | digit | "+" | "-" | "." )
      SCHEME = "[#{ALPHA}][-+.#{ALPHA}\\d]*"

      # abs_path      = "/"  path_segments
      ABS_PATH = "/#{PATH_SEGMENTS}"
      # rel_path      = rel_segment [ abs_path ]
      REL_PATH = "#{REL_SEGMENT}(?:#{ABS_PATH})?"
      # net_path      = "//" authority [ abs_path ]
      NET_PATH   = "//#{AUTHORITY}(?:#{ABS_PATH})?"

      # hier_part     = ( net_path | abs_path ) [ "?" query ]
      HIER_PART   = "(?:#{NET_PATH}|#{ABS_PATH})(?:\\?(?:#{QUERY}))?"
      # opaque_part   = uric_no_slash *uric
      OPAQUE_PART = "#{URIC_NO_SLASH}#{URIC}*"

      # absoluteURI   = scheme ":" ( hier_part | opaque_part )
      ABS_URI   = "#{SCHEME}:(?:#{HIER_PART}|#{OPAQUE_PART})"
      # relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ]
      REL_URI = "(?:#{NET_PATH}|#{ABS_PATH}|#{REL_PATH})(?:\\?#{QUERY})?"

      # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
      URI_REF = "(?:#{ABS_URI}|#{REL_URI})?(?:##{FRAGMENT})?"

      # XXX:
      X_ABS_URI = "
        (#{PATTERN::SCHEME}):                     (?# 1: scheme)
        (?:
           (#{PATTERN::OPAQUE_PART})              (?# 2: opaque)
        |
           (?:(?:
             //(?:
                 (?:(?:(#{PATTERN::USERINFO})@)?  (?# 3: userinfo)
                   (?:(#{PATTERN::HOST})(?::(\\d*))?))?(?# 4: host, 5: port)
               |
                 (#{PATTERN::REG_NAME})           (?# 6: registry)
               )
             |
             (?!//))                              (?# XXX: '//' is the mark for hostport)
             (#{PATTERN::ABS_PATH})?              (?# 7: path)
           )(?:\\?(#{PATTERN::QUERY}))?           (?# 8: query)
        )
        (?:\\#(#{PATTERN::FRAGMENT}))?            (?# 9: fragment)
      "
      X_REL_URI = "
        (?:
          (?:
            //
            (?:
              (?:(#{PATTERN::USERINFO})@)?       (?# 1: userinfo)
                (#{PATTERN::HOST})?(?::(\\d*))?  (?# 2: host, 3: port)
            |
              (#{PATTERN::REG_NAME})             (?# 4: registry)
            )
          )
        |
          (#{PATTERN::REL_SEGMENT})              (?# 5: rel_segment)
        )?
        (#{PATTERN::ABS_PATH})?                  (?# 6: abs_path)
        (?:\\?(#{PATTERN::QUERY}))?              (?# 7: query)
        (?:\\#(#{PATTERN::FRAGMENT}))?           (?# 8: fragment)
      "
      # :startdoc:
    end # PATTERN

    # :stopdoc:

    # for URI::split
    ABS_URI = Regexp.new('^' + PATTERN::X_ABS_URI + '$', #'
                         Regexp::EXTENDED, 'N').freeze
    REL_URI = Regexp.new('^' + PATTERN::X_REL_URI + '$', #'
                         Regexp::EXTENDED, 'N').freeze

    # for URI::extract
    URI_REF     = Regexp.new(PATTERN::URI_REF, false, 'N').freeze
    ABS_URI_REF = Regexp.new(PATTERN::X_ABS_URI, Regexp::EXTENDED, 'N').freeze
    REL_URI_REF = Regexp.new(PATTERN::X_REL_URI, Regexp::EXTENDED, 'N').freeze

    # for URI::escape/unescape
    ESCAPED = Regexp.new(PATTERN::ESCAPED, false, 'N').freeze
    UNSAFE  = Regexp.new("[^#{PATTERN::UNRESERVED}#{PATTERN::RESERVED}]",
                         false, 'N').freeze

    # for Generic#initialize
    SCHEME   = Regexp.new("^#{PATTERN::SCHEME}$", false, 'N').freeze #"
    USERINFO = Regexp.new("^#{PATTERN::USERINFO}$", false, 'N').freeze #"
    HOST     = Regexp.new("^#{PATTERN::HOST}$", false, 'N').freeze #"
    PORT     = Regexp.new("^#{PATTERN::PORT}$", false, 'N').freeze #"
    OPAQUE   = Regexp.new("^#{PATTERN::OPAQUE_PART}$", false, 'N').freeze #"
    REGISTRY = Regexp.new("^#{PATTERN::REG_NAME}$", false, 'N').freeze #"
    ABS_PATH = Regexp.new("^#{PATTERN::ABS_PATH}$", false, 'N').freeze #"
    REL_PATH = Regexp.new("^#{PATTERN::REL_PATH}$", false, 'N').freeze #"
    QUERY    = Regexp.new("^#{PATTERN::QUERY}$", false, 'N').freeze #"
    FRAGMENT = Regexp.new("^#{PATTERN::FRAGMENT}$", false, 'N').freeze #"
    # :startdoc:
  end # REGEXP

  module Util # :nodoc:
    def make_components_hash(klass, array_hash)
      tmp = {}
      if array_hash.kind_of?(Array) &&
          array_hash.size == klass.component.size - 1
        klass.component[1..-1].each_index do |i|
          begin
            tmp[klass.component[i + 1]] = array_hash[i].clone
          rescue TypeError
            tmp[klass.component[i + 1]] = array_hash[i]
          end
        end

      elsif array_hash.kind_of?(Hash)
        array_hash.each do |key, value|
          begin
            tmp[key] = value.clone
          rescue TypeError
            tmp[key] = value
          end
        end
      else
        raise ArgumentError, 
          "expected Array of or Hash of components of #{klass.to_s} (#{klass.component[1..-1].join(', ')})"
      end
      tmp[:scheme] = klass.to_s.sub(/\A.*::/, '').downcase

      return tmp
    end
    module_function :make_components_hash
  end

  module Escape
    include REGEXP

    #
    # == Synopsis
    #
    #   URI.escape(str [, unsafe])
    #
    # == Args
    #
    # +str+::
    #   String to replaces in.
    # +unsafe+::
    #   Regexp that matches all symbols that must be replaced with codes.
    #   By default uses <tt>REGEXP::UNSAFE</tt>.
    #   When this argument is a String, it represents a character set.
    #
    # == Description
    #
    # Escapes the string, replacing all unsafe characters with codes.
    #
    # == Usage
    #
    #   require 'uri'
    #
    #   enc_uri = URI.escape("http://example.com/?a=\11\15")
    #   p enc_uri
    #   # => "http://example.com/?a=%09%0D"
    #
    #   p URI.unescape(enc_uri)
    #   # => "http://example.com/?a=\t\r"
    #
    #   p URI.escape("@?@!", "!?")
    #   # => "@%3F@%21"
    #
    def escape(str, unsafe = UNSAFE)
      unless unsafe.kind_of?(Regexp)
        # perhaps unsafe is String object
        unsafe = Regexp.new("[#{Regexp.quote(unsafe)}]", false, 'N')
      end
      str.gsub(unsafe) do |us|
        tmp = ''
        us.each_byte do |uc|
          tmp << sprintf('%%%02X', uc)
        end
        tmp
      end
    end
    alias encode escape
    #
    # == Synopsis
    #
    #   URI.unescape(str)
    #
    # == Args
    #
    # +str+::
    #   Unescapes the string.
    #
    # == Usage
    #
    #   require 'uri'
    #
    #   enc_uri = URI.escape("http://example.com/?a=\11\15")
    #   p enc_uri
    #   # => "http://example.com/?a=%09%0D"
    #
    #   p URI.unescape(enc_uri)
    #   # => "http://example.com/?a=\t\r"
    #
    def unescape(str)
      str.gsub(ESCAPED) do
        $&[1,2].hex.chr
      end
    end
    alias decode unescape
  end

  include REGEXP
  extend Escape

  @@schemes = {}
  
  #
  # Base class for all URI exceptions.
  #
  class Error < StandardError; end
  #
  # Not a URI.
  #
  class InvalidURIError < Error; end
  #
  # Not a URI component.
  #
  class InvalidComponentError < Error; end
  #
  # URI is valid, bad usage is not.
  #
  class BadURIError < Error; end

  #
  # == Synopsis
  #
  #   URI::split(uri)
  #
  # == Args
  #
  # +uri+::
  #   String with URI.
  #
  # == Description
  #
  # Splits the string on following parts and returns array with result:
  #
  #   * Scheme
  #   * Userinfo
  #   * Host
  #   * Port
  #   * Registry
  #   * Path
  #   * Opaque
  #   * Query
  #   * Fragment
  # 
  # == Usage
  #
  #   require 'uri'
  #
  #   p URI.split("http://www.ruby-lang.org/")
  #   # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil]
  #
  def self.split(uri)
    case uri
    when ''
      # null uri

    when ABS_URI
      scheme, opaque, userinfo, host, port, 
        registry, path, query, fragment = $~[1..-1]

      # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]

      # absoluteURI   = scheme ":" ( hier_part | opaque_part )
      # hier_part     = ( net_path | abs_path ) [ "?" query ]
      # opaque_part   = uric_no_slash *uric

      # abs_path      = "/"  path_segments
      # net_path      = "//" authority [ abs_path ]

      # authority     = server | reg_name
      # server        = [ [ userinfo "@" ] hostport ]

      if !scheme
        raise InvalidURIError, 
          "bad URI(absolute but no scheme): #{uri}"
      end
      if !opaque && (!path && (!host && !registry))
        raise InvalidURIError,
          "bad URI(absolute but no path): #{uri}" 
      end

    when REL_URI
      scheme = nil
      opaque = nil

      userinfo, host, port, registry, 
        rel_segment, abs_path, query, fragment = $~[1..-1]
      if rel_segment && abs_path
        path = rel_segment + abs_path
      elsif rel_segment
        path = rel_segment
      elsif abs_path
        path = abs_path
      end

      # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]

      # relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ]

      # net_path      = "//" authority [ abs_path ]
      # abs_path      = "/"  path_segments
      # rel_path      = rel_segment [ abs_path ]

      # authority     = server | reg_name
      # server        = [ [ userinfo "@" ] hostport ]

    else
      raise InvalidURIError, "bad URI(is not URI?): #{uri}"
    end

    path = '' if !path && !opaque # (see RFC2396 Section 5.2)
    ret = [
      scheme, 
      userinfo, host, port,         # X
      registry,                        # X
      path,                         # Y
      opaque,                        # Y
      query,
      fragment
    ]
    return ret
  end

  #
  # == Synopsis
  #
  #   URI::parse(uri_str)
  #
  # == Args
  #
  # +uri_str+::
  #   String with URI.
  #
  # == Description
  #
  # Creates one of the URI's subclasses instance from the string.
  #  
  # == Raises
  #
  # URI::InvalidURIError
  #   Raised if URI given is not a correct one.
  #
  # == Usage
  #
  #   require 'uri'
  #
  #   uri = URI.parse("http://www.ruby-lang.org/")
  #   p uri
  #   # => #<URI::HTTP:0x202281be URL:http://www.ruby-lang.org/>
  #   p uri.scheme 
  #   # => "http" 
  #   p uri.host 
  #   # => "www.ruby-lang.org" 
  # 
  def self.parse(uri)
    scheme, userinfo, host, port, 
      registry, path, opaque, query, fragment = self.split(uri)

    if scheme && @@schemes.include?(scheme.upcase)
      @@schemes[scheme.upcase].new(scheme, userinfo, host, port, 
                                   registry, path, opaque, query, 
                                   fragment)
    else
      Generic.new(scheme, userinfo, host, port, 
                  registry, path, opaque, query, 
                  fragment)
    end
  end

  #
  # == Synopsis
  #
  #   URI::join(str[, str, ...])
  #
  # == Args
  #
  # +str+::
  #   String(s) to work with
  #
  # == Description
  #
  # Joins URIs.
  #
  # == Usage
  #
  #   require 'uri'
  #
  #   p URI.join("http://localhost/","main.rbx")
  #   # => #<URI::HTTP:0x2022ac02 URL:http://localhost/main.rbx>
  #
  def self.join(*str)
    u = self.parse(str[0])
    str[1 .. -1].each do |x|
      u = u.merge(x)
    end
    u
  end

  #
  # == Synopsis
  #
  #   URI::extract(str[, schemes][,&blk])
  #
  # == Args
  #
  # +str+:: 
  #   String to extract URIs from.
  # +schemes+::
  #   Limit URI matching to a specific schemes.
  #
  # == Description
  #
  # Extracts URIs from a string. If block given, iterates through all matched URIs.
  # Returns nil if block given or array with matches.
  #
  # == Usage
  #
  #   require "uri"
  #
  #   URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
  #   # => ["http://foo.example.com/bla", "mailto:test@example.com"]
  #
  def self.extract(str, schemes = nil, &block)
    if block_given?
      str.scan(regexp(schemes)) { yield $& }
      nil
    else
      result = []
      str.scan(regexp(schemes)) { result.push $& }
      result
    end
  end

  #
  # == Synopsis
  #
  #   URI::regexp([match_schemes])
  #
  # == Args
  #
  # +match_schemes+:: 
  #   Array of schemes. If given, resulting regexp matches to URIs
  #   whose scheme is one of the match_schemes.
  # 
  # == Description
  # Returns a Regexp object which matches to URI-like strings.
  # The Regexp object returned by this method includes arbitrary
  # number of capture group (parentheses).  Never rely on it's number.
  # 
  # == Usage
  #
  #   require 'uri'
  #
  #   # extract first URI from html_string
  #   html_string.slice(URI.regexp)
  # 
  #   # remove ftp URIs
  #   html_string.sub(URI.regexp(['ftp'])
  # 
  #   # You should not rely on the number of parentheses
  #   html_string.scan(URI.regexp) do |*matches|
  #     p $&
  #   end
  #
  def self.regexp(schemes = nil)
    unless schemes
      ABS_URI_REF
    else
      /(?=#{Regexp.union(*schemes)}:)#{PATTERN::X_ABS_URI}/xn
    end
  end

end

module Kernel
  # alias for URI.parse.
  #
  # This method is introduced at 1.8.2.
  def URI(uri_str) # :doc:
    URI.parse(uri_str)
  end
  module_function :URI
end
PK     Z\UT    
  uri/ftp.rbnu [        #
# = uri/ftp.rb
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# License:: You can redistribute it and/or modify it under the same term as Ruby.
# Revision:: $Id: ftp.rb 16085 2008-04-19 11:56:22Z knu $
#

require 'uri/generic'

module URI

  #
  # FTP URI syntax is defined by RFC1738 section 3.2.
  #
  class FTP < Generic
    DEFAULT_PORT = 21

    COMPONENT = [
      :scheme, 
      :userinfo, :host, :port,
      :path, :typecode
    ].freeze
    #
    # Typecode is "a", "i" or "d". 
    #
    # * "a" indicates a text file (the FTP command was ASCII)
    # * "i" indicates a binary file (FTP command IMAGE)
    # * "d" indicates the contents of a directory should be displayed
    #
    TYPECODE = ['a', 'i', 'd'].freeze
    TYPECODE_PREFIX = ';type='.freeze

    def self.new2(user, password, host, port, path, 
                  typecode = nil, arg_check = true)
      typecode = nil if typecode.size == 0
      if typecode && !TYPECODE.include?(typecode)
        raise ArgumentError,
          "bad typecode is specified: #{typecode}"
      end

      # do escape

      self.new('ftp',
               [user, password], 
               host, port, nil, 
               typecode ? path + TYPECODE_PREFIX + typecode : path, 
               nil, nil, nil, arg_check)
    end

    #
    # == Description
    #
    # Creates a new URI::FTP object from components, with syntax checking.  
    #
    # The components accepted are +userinfo+, +host+, +port+, +path+ and 
    # +typecode+.
    #
    # The components should be provided either as an Array, or as a Hash 
    # with keys formed by preceding the component names with a colon. 
    #
    # If an Array is used, the components must be passed in the order
    # [userinfo, host, port, path, typecode]
    #
    # If the path supplied is absolute, it will be escaped in order to
    # make it absolute in the URI. Examples:
    #
    #     require 'uri'
    #
    #     uri = URI::FTP.build(['user:password', 'ftp.example.com', nil, 
    #       '/path/file.> zip', 'i'])
    #     puts uri.to_s  ->  ftp://user:password@ftp.example.com/%2Fpath/file.zip;type=a
    #
    #     uri2 = URI::FTP.build({:host => 'ftp.example.com', 
    #       :path => 'ruby/src'})
    #     puts uri2.to_s  ->  ftp://ftp.example.com/ruby/src
    #
    def self.build(args)

      # Fix the incoming path to be generic URL syntax
      # FTP path  ->  URL path
      # foo/bar       /foo/bar
      # /foo/bar      /%2Ffoo/bar
      #
      if args.kind_of?(Array)
        args[3] = '/' + args[3].sub(/^\//, '%2F')
      else
        args[:path] = '/' + args[:path].sub(/^\//, '%2F')
      end

      tmp = Util::make_components_hash(self, args)

      if tmp[:typecode]
        if tmp[:typecode].size == 1
          tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode] 
        end
        tmp[:path] << tmp[:typecode]
      end

      return super(tmp)
    end

    #
    # == Description
    #
    # Creates a new URI::FTP object from generic URL components with no
    # syntax checking.
    #
    # Unlike build(), this method does not escape the path component as
    # required by RFC1738; instead it is treated as per RFC2396.
    #
    # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+, 
    # +opaque+, +query+ and +fragment+, in that order.
    #
    def initialize(*arg)
      super(*arg)
      @typecode = nil
      tmp = @path.index(TYPECODE_PREFIX)
      if tmp
        typecode = @path[tmp + TYPECODE_PREFIX.size..-1]
        self.set_path(@path[0..tmp - 1])
        
        if arg[-1]
          self.typecode = typecode
        else
          self.set_typecode(typecode)
        end
      end
    end
    attr_reader :typecode

    def check_typecode(v)
      if TYPECODE.include?(v)
        return true
      else
        raise InvalidComponentError,
          "bad typecode(expected #{TYPECODE.join(', ')}): #{v}"
      end
    end
    private :check_typecode

    def set_typecode(v)
      @typecode = v
    end
    protected :set_typecode

    def typecode=(typecode)
      check_typecode(typecode)
      set_typecode(typecode)
      typecode
    end

    def merge(oth) # :nodoc:
      tmp = super(oth)
      if self != tmp
        tmp.set_typecode(oth.typecode)
      end

      return tmp
    end

    # Returns the path from an FTP URI.
    #
    # RFC 1738 specifically states that the path for an FTP URI does not
    # include the / which separates the URI path from the URI host. Example:
    #
    #     ftp://ftp.example.com/pub/ruby 
    #
    # The above URI indicates that the client should connect to 
    # ftp.example.com then cd pub/ruby from the initial login directory.
    #
    # If you want to cd to an absolute directory, you must include an
    # escaped / (%2F) in the path. Example:
    #
    #     ftp://ftp.example.com/%2Fpub/ruby
    #
    # This method will then return "/pub/ruby"
    #
    def path
      return @path.sub(/^\//,'').sub(/^%2F/i,'/')
    end

    def to_s
      save_path = nil
      if @typecode
        save_path = @path
        @path = @path + TYPECODE_PREFIX + @typecode
      end
      str = super
      if @typecode
        @path = save_path
      end

      return str
    end
  end
  @@schemes['FTP'] = FTP
end
PK     Z\5#       uri/mailto.rbnu [        #
# = uri/mailto.rb
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# License:: You can redistribute it and/or modify it under the same term as Ruby.
# Revision:: $Id: mailto.rb 11747 2007-02-15 02:41:45Z knu $
#

require 'uri/generic'

module URI

  #
  # RFC2368, The mailto URL scheme
  #
  class MailTo < Generic
    include REGEXP

    DEFAULT_PORT = nil

    COMPONENT = [ :scheme, :to, :headers ].freeze

    # :stopdoc:
    #  "hname" and "hvalue" are encodings of an RFC 822 header name and
    #  value, respectively. As with "to", all URL reserved characters must
    #  be encoded.
    #
    #  "#mailbox" is as specified in RFC 822 [RFC822]. This means that it
    #  consists of zero or more comma-separated mail addresses, possibly
    #  including "phrase" and "comment" components. Note that all URL
    #  reserved characters in "to" must be encoded: in particular,
    #  parentheses, commas, and the percent sign ("%"), which commonly occur
    #  in the "mailbox" syntax.
    #
    #  Within mailto URLs, the characters "?", "=", "&" are reserved.

    # hname      =  *urlc
    # hvalue     =  *urlc
    # header     =  hname "=" hvalue
    HEADER_PATTERN = "(?:[^?=&]*=[^?=&]*)".freeze
    HEADER_REGEXP  = Regexp.new(HEADER_PATTERN, 'N').freeze
    # headers    =  "?" header *( "&" header )
    # to         =  #mailbox
    # mailtoURL  =  "mailto:" [ to ] [ headers ]
    MAILBOX_PATTERN = "(?:#{PATTERN::ESCAPED}|[^(),%?=&])".freeze
    MAILTO_REGEXP = Regexp.new(" # :nodoc:
      \\A
      (#{MAILBOX_PATTERN}*?)                          (?# 1: to)
      (?:
        \\?
        (#{HEADER_PATTERN}(?:\\&#{HEADER_PATTERN})*)  (?# 2: headers)
      )?
      (?:
        \\#
        (#{PATTERN::FRAGMENT})                        (?# 3: fragment)
      )?
      \\z
    ", Regexp::EXTENDED, 'N').freeze
    # :startdoc:

    #
    # == Description
    #
    # Creates a new URI::MailTo object from components, with syntax checking.
    #
    # Components can be provided as an Array or Hash. If an Array is used,
    # the components must be supplied as [to, headers].
    #
    # If a Hash is used, the keys are the component names preceded by colons.
    #
    # The headers can be supplied as a pre-encoded string, such as 
    # "subject=subscribe&cc=address", or as an Array of Arrays like
    # [['subject', 'subscribe'], ['cc', 'address']]
    #
    # Examples:
    # 
    #    require 'uri'
    #    
    #    m1 = URI::MailTo.build(['joe@example.com', 'subject=Ruby'])
    #    puts m1.to_s  ->  mailto:joe@example.com?subject=Ruby
    #    
    #    m2 = URI::MailTo.build(['john@example.com', [['Subject', 'Ruby'], ['Cc', 'jack@example.com']]])
    #    puts m2.to_s  ->  mailto:john@example.com?Subject=Ruby&Cc=jack@example.com
    #    
    #    m3 = URI::MailTo.build({:to => 'listman@example.com', :headers => [['subject', 'subscribe']]})
    #    puts m3.to_s  ->  mailto:listman@example.com?subject=subscribe
    #
    def self.build(args)
      tmp = Util::make_components_hash(self, args)

      if tmp[:to]
        tmp[:opaque] = tmp[:to]
      else
        tmp[:opaque] = ''
      end

      if tmp[:headers]
        tmp[:opaque] << '?'

        if tmp[:headers].kind_of?(Array)
          tmp[:opaque] << tmp[:headers].collect { |x|
            if x.kind_of?(Array)
              x[0] + '=' + x[1..-1].to_s
            else
              x.to_s
            end
          }.join('&')

        elsif tmp[:headers].kind_of?(Hash)
          tmp[:opaque] << tmp[:headers].collect { |h,v|
            h + '=' + v
          }.join('&')

        else
          tmp[:opaque] << tmp[:headers].to_s
        end
      end

      return super(tmp)
    end

    #
    # == Description
    #
    # Creates a new URI::MailTo object from generic URL components with
    # no syntax checking.
    #
    # This method is usually called from URI::parse, which checks
    # the validity of each component.
    #
    def initialize(*arg)
      super(*arg)

      @to = nil
      @headers = []

      if MAILTO_REGEXP =~ @opaque
         if arg[-1]
          self.to = $1
          self.headers = $2
        else
          set_to($1)
          set_headers($2)
        end

      else
        raise InvalidComponentError,
          "unrecognised opaque part for mailtoURL: #{@opaque}"
      end
    end

    # The primary e-mail address of the URL, as a String
    attr_reader :to

    # E-mail headers set by the URL, as an Array of Arrays
    attr_reader :headers

    def check_to(v)
      return true unless v
      return true if v.size == 0

      if OPAQUE !~ v || /\A#{MAILBOX_PATTERN}*\z/o !~ v
        raise InvalidComponentError,
          "bad component(expected opaque component): #{v}"
      end

      return true
    end
    private :check_to

    def set_to(v)
      @to = v
    end
    protected :set_to

    def to=(v)
      check_to(v)
      set_to(v)
      v
    end

    def check_headers(v)
      return true unless v
      return true if v.size == 0

      if OPAQUE !~ v || 
          /\A(#{HEADER_PATTERN}(?:\&#{HEADER_PATTERN})*)\z/o !~ v
        raise InvalidComponentError,
          "bad component(expected opaque component): #{v}"
      end

      return true
    end
    private :check_headers

    def set_headers(v)
      @headers = []
      if v
        v.scan(HEADER_REGEXP) do |x|
          @headers << x.split(/=/o, 2)
        end
      end
    end
    protected :set_headers

    def headers=(v)
      check_headers(v)
      set_headers(v)
      v
    end

    def to_s
      @scheme + ':' + 
        if @to 
          @to
        else
          ''
        end + 
        if @headers.size > 0
          '?' + @headers.collect{|x| x.join('=')}.join('&')
        else
          ''
        end +
        if @fragment
          '#' + @fragment
        else
          ''
        end
    end
    
    # Returns the RFC822 e-mail text equivalent of the URL, as a String.
    #
    # Example:
    #
    #   require 'uri'
    #
    #   uri = URI.parse("mailto:ruby-list@ruby-lang.org?Subject=subscribe&cc=myaddr")
    #   uri.to_mailtext
    #   # => "To: ruby-list@ruby-lang.org\nSubject: subscribe\nCc: myaddr\n\n\n"
    #
    def to_mailtext
      to = URI::unescape(@to)
      head = ''
      body = ''
      @headers.each do |x|
        case x[0]
        when 'body'
          body = URI::unescape(x[1])
        when 'to'
          to << ', ' + URI::unescape(x[1])
        else
          head << URI::unescape(x[0]).capitalize + ': ' +
            URI::unescape(x[1])  + "\n"
        end
      end

      return "To: #{to}
#{head}
#{body}
"
    end
    alias to_rfc822text to_mailtext
  end

  @@schemes['MAILTO'] = MailTo
end
PK     Z\8`X  X    sync.rbnu [        #
#   sync.rb - 2 phase lock with counter
#   	$Release Version: 1.0$
#   	$Revision: 22457 $
#   	$Date: 2009-02-20 01:41:12 +0900 (Fri, 20 Feb 2009) $
#   	by Keiju ISHITSUKA(keiju@ishitsuka.com)
#
# --
#  Sync_m, Synchronizer_m
#  Usage:
#   obj.extend(Sync_m)
#   or
#   class Foo
#	include Sync_m
#	:
#   end
#
#   Sync_m#sync_mode
#   Sync_m#sync_locked?, locked?
#   Sync_m#sync_shared?, shared?
#   Sync_m#sync_exclusive?, sync_exclusive?
#   Sync_m#sync_try_lock, try_lock
#   Sync_m#sync_lock, lock
#   Sync_m#sync_unlock, unlock
#
#   Sync, Synchronicer:
#	include Sync_m
#   Usage:
#   sync = Sync.new
#
#   Sync#mode
#   Sync#locked?
#   Sync#shared?
#   Sync#exclusive?
#   Sync#try_lock(mode) -- mode = :EX, :SH, :UN
#   Sync#lock(mode)     -- mode = :EX, :SH, :UN
#   Sync#unlock
#   Sync#synchronize(mode) {...}
#   
#

unless defined? Thread
  fail "Thread not available for this ruby interpreter"
end

module Sync_m
  RCS_ID='-$Header$-'
  
  # lock mode
  UN = :UN
  SH = :SH
  EX = :EX
  
  # exceptions
  class Err < StandardError
    def Err.Fail(*opt)
      Thread.critical = false
      fail self, sprintf(self::Message, *opt)
    end
    
    class UnknownLocker < Err
      Message = "Thread(%s) not locked."
      def UnknownLocker.Fail(th)
	super(th.inspect)
      end
    end
    
    class LockModeFailer < Err
      Message = "Unknown lock mode(%s)"
      def LockModeFailer.Fail(mode)
	if mode.id2name
	  mode = id2name
	end
	super(mode)
      end
    end
  end
  
  def Sync_m.define_aliases(cl)
    cl.module_eval %q{
      alias locked? sync_locked?
      alias shared? sync_shared?
      alias exclusive? sync_exclusive?
      alias lock sync_lock
      alias unlock sync_unlock
      alias try_lock sync_try_lock
      alias synchronize sync_synchronize
    }
  end
  
  def Sync_m.append_features(cl)
    super
    unless cl.instance_of?(Module)
      # do nothing for Modules
      # make aliases and include the proper module.
      define_aliases(cl)
    end
  end
  
  def Sync_m.extend_object(obj)
    super
    obj.sync_extended
  end

  def sync_extended
    unless (defined? locked? and
	    defined? shared? and
	    defined? exclusive? and
	    defined? lock and
	    defined? unlock and
	    defined? try_lock and
	    defined? synchronize)
      Sync_m.define_aliases(class<<self;self;end)
    end
    sync_initialize
  end

  # accessing
  def sync_locked?
    sync_mode != UN
  end
  
  def sync_shared?
    sync_mode == SH
  end
  
  def sync_exclusive?
    sync_mode == EX
  end
  
  # locking methods.
  def sync_try_lock(mode = EX)
    return unlock if mode == UN
    
    Thread.critical = true
    ret = sync_try_lock_sub(mode)
    Thread.critical = false
    ret
  end
  
  def sync_lock(m = EX)
    return unlock if m == UN

    until (Thread.critical = true; sync_try_lock_sub(m))
      if sync_sh_locker[Thread.current]
	sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
	sync_sh_locker.delete(Thread.current)
      else
	sync_waiting.push Thread.current
      end
      Thread.stop
    end
    Thread.critical = false
    self
  end
  
  def sync_unlock(m = EX)
    Thread.critical = true
    if sync_mode == UN
      Thread.critical = false
      Err::UnknownLocker.Fail(Thread.current)
    end
    
    m = sync_mode if m == EX and sync_mode == SH
    
    runnable = false
    case m
    when UN
      Thread.critical = false
      Err::UnknownLocker.Fail(Thread.current)
      
    when EX
      if sync_ex_locker == Thread.current
	if (self.sync_ex_count = sync_ex_count - 1) == 0
	  self.sync_ex_locker = nil
	  if sync_sh_locker.include?(Thread.current)
	    self.sync_mode = SH
	  else
	    self.sync_mode = UN
	  end
	  runnable = true
	end
      else
	Err::UnknownLocker.Fail(Thread.current)
      end
      
    when SH
      if (count = sync_sh_locker[Thread.current]).nil?
	Err::UnknownLocker.Fail(Thread.current)
      else
	if (sync_sh_locker[Thread.current] = count - 1) == 0 
	  sync_sh_locker.delete(Thread.current)
	  if sync_sh_locker.empty? and sync_ex_count == 0
	    self.sync_mode = UN
	    runnable = true
	  end
	end
      end
    end
    
    if runnable
      if sync_upgrade_waiting.size > 0
	for k, v in sync_upgrade_waiting
	  sync_sh_locker[k] = v
	end
	wait = sync_upgrade_waiting
	self.sync_upgrade_waiting = []
	Thread.critical = false
	
	for w, v in wait
	  w.run
	end
      else
	wait = sync_waiting
	self.sync_waiting = []
	Thread.critical = false
	for w in wait
	  w.run
	end
      end
    end
    
    Thread.critical = false
    self
  end
  
  def sync_synchronize(mode = EX)
    begin
      sync_lock(mode)
      yield
    ensure
      sync_unlock
    end
  end

  attr :sync_mode, true
    
  attr :sync_waiting, true
  attr :sync_upgrade_waiting, true
  attr :sync_sh_locker, true
  attr :sync_ex_locker, true
  attr :sync_ex_count, true
    
  private

  def sync_initialize
    @sync_mode = UN
    @sync_waiting = []
    @sync_upgrade_waiting = []
    @sync_sh_locker = Hash.new
    @sync_ex_locker = nil
    @sync_ex_count = 0
  end

  def initialize(*args)
    sync_initialize
    super
  end
    
  def sync_try_lock_sub(m)
    case m
    when SH
      case sync_mode
      when UN
	self.sync_mode = m
	sync_sh_locker[Thread.current] = 1
	ret = true
      when SH
	count = 0 unless count = sync_sh_locker[Thread.current]
	sync_sh_locker[Thread.current] = count + 1
	ret = true
      when EX
	# in EX mode, lock will upgrade to EX lock
	if sync_ex_locker == Thread.current
	  self.sync_ex_count = sync_ex_count + 1
	  ret = true
	else
	  ret = false
	end
      end
    when EX
      if sync_mode == UN or
	sync_mode == SH && sync_sh_locker.size == 1 && sync_sh_locker.include?(Thread.current) 
	self.sync_mode = m
	self.sync_ex_locker = Thread.current
	self.sync_ex_count = 1
	ret = true
      elsif sync_mode == EX && sync_ex_locker == Thread.current
	self.sync_ex_count = sync_ex_count + 1
	ret = true
      else
	ret = false
      end
    else
      Thread.critical = false
      Err::LockModeFailer.Fail mode
    end
    return ret
  end
end
Synchronizer_m = Sync_m

class Sync
  #Sync_m.extend_class self
  include Sync_m
    
  def initialize
    super
  end
    
end
Synchronizer = Sync
PK     Z\;E  E    optparse/date.rbnu [        require 'optparse'
require 'date'

OptionParser.accept(DateTime) do |s,|
  begin
    DateTime.parse(s) if s
  rescue ArgumentError
    raise OptionParser::InvalidArgument, s
  end
end
OptionParser.accept(Date) do |s,|
  begin
    Date.parse(s) if s
  rescue ArgumentError
    raise OptionParser::InvalidArgument, s
  end
end
PK     Z\Zvvy   y     optparse/shellwords.rbnu [        # -*- ruby -*-

require 'shellwords'
require 'optparse'

OptionParser.accept(Shellwords) {|s,| Shellwords.shellwords(s)}
PK     Z\[hzd   d     optparse/uri.rbnu [        # -*- ruby -*-

require 'optparse'
require 'uri'

OptionParser.accept(URI) {|s,| URI.parse(s) if s}
PK     Z\?߅      optparse/version.rbnu [        # OptionParser internal utility

class << OptionParser
  def show_version(*pkg)
    progname = ARGV.options.program_name
    result = false
    show = proc do |klass, cname, version|
      str = "#{progname}"
      unless klass == ::Object and cname == :VERSION
        version = version.join(".") if Array === version
        str << ": #{klass}" unless klass == Object
        str << " version #{version}"
      end
      [:Release, :RELEASE].find do |rel|
        if klass.const_defined?(rel)
          str << " (#{klass.const_get(rel)})"
        end
      end
      puts str
      result = true
    end
    if pkg.size == 1 and pkg[0] == "all"
      self.search_const(::Object, /\AV(?:ERSION|ersion)\z/) do |klass, cname, version|
        unless cname[1] == ?e and klass.const_defined?(:Version)
          show.call(klass, cname.intern, version)
        end
      end
    else
      pkg.each do |pkg|
        begin
          pkg = pkg.split(/::|\//).inject(::Object) {|m, c| m.const_get(c)}
          v = case
              when pkg.const_defined?(:Version)
                pkg.const_get(n = :Version)
              when pkg.const_defined?(:VERSION)
                pkg.const_get(n = :VERSION)
              else
                n = nil
                "unknown"
              end
          show.call(pkg, n, v)
        rescue NameError
        end
      end
    end
    result
  end

  def each_const(path, klass = ::Object)
    path.split(/::|\//).inject(klass) do |klass, name|
      raise NameError, path unless Module === klass
      klass.constants.grep(/#{name}/i) do |c|
        klass.const_defined?(c) or next
        c = klass.const_get(c)
      end
    end
  end

  def search_const(klass, name)
    klasses = [klass]
    while klass = klasses.shift
      klass.constants.each do |cname|
        klass.const_defined?(cname) or next
        const = klass.const_get(cname)
        yield klass, cname, const if name === cname
        klasses << const if Module === const and const != ::Object
      end
    end
  end
end
PK     Z\7&        optparse/time.rbnu [        require 'optparse'
require 'time'

OptionParser.accept(Time) do |s,|
  begin
    (Time.httpdate(s) rescue Time.parse(s)) if s
  rescue
    raise OptionParser::InvalidArgument, s
  end
end
PK     Z\{7N  N    importenv.rbnu [        # importenv.rb -- imports environment variables as global variables, Perlish ;(
#
# Usage:
#
#  require 'importenv'
#  p $USER
#  $USER = "matz"
#  p ENV["USER"]

warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: importenv is deprecated after Ruby 1.8.1 (no replacement)"

for k,v in ENV
  next unless /^[a-zA-Z][_a-zA-Z0-9]*/ =~ k
  eval <<EOS
  $#{k} = v
  trace_var "$#{k}", proc{|v|
    ENV[%q!#{k}!] = v
    $#{k} = v
    if v == nil
      untrace_var "$#{k}"
    end
  }
EOS
end

if __FILE__ == $0
  p $TERM
  $TERM = nil
  p $TERM
  p ENV["TERM"]
  $TERM = "foo"
  p ENV["TERM"]
end
PK     Z\"a
  
  	  abbrev.rbnu [        #!/usr/bin/env ruby
=begin
#
# Copyright (c) 2001,2003 Akinori MUSHA <knu@iDaemons.org>
#
# All rights reserved.  You can redistribute and/or modify it under
# the same terms as Ruby.
#
# $Idaemons: /home/cvs/rb/abbrev.rb,v 1.2 2001/05/30 09:37:45 knu Exp $
# $RoughId: abbrev.rb,v 1.4 2003/10/14 19:45:42 knu Exp $
# $Id: abbrev.rb 11708 2007-02-12 23:01:19Z shyouhei $
=end

# Calculate the set of unique abbreviations for a given set of strings.
#
#   require 'abbrev'
#   require 'pp'
#
#   pp Abbrev::abbrev(['ruby', 'rules']).sort
#
# <i>Generates:</i>
#
#   [["rub", "ruby"],
#    ["ruby", "ruby"],
#    ["rul", "rules"],
#    ["rule", "rules"],
#    ["rules", "rules"]]
#
# Also adds an +abbrev+ method to class +Array+.

module Abbrev

  # Given a set of strings, calculate the set of unambiguous
  # abbreviations for those strings, and return a hash where the keys
  # are all the possible abbreviations and the values are the full
  # strings. Thus, given input of "car" and "cone", the keys pointing
  # to "car" would be "ca" and "car", while those pointing to "cone"
  # would be "co", "con", and "cone".
  #
  # The optional +pattern+ parameter is a pattern or a string. Only
  # those input strings matching the pattern, or begging the string,
  # are considered for inclusion in the output hash

  def abbrev(words, pattern = nil)
    table = {}
    seen = Hash.new(0)

    if pattern.is_a?(String)
      pattern = /^#{Regexp.quote(pattern)}/	# regard as a prefix
    end

    words.each do |word|
      next if (abbrev = word).empty?
      while (len = abbrev.rindex(/[\w\W]\z/)) > 0
	abbrev = word[0,len]

	next if pattern && pattern !~ abbrev

	case seen[abbrev] += 1
	when 1
	  table[abbrev] = word
	when 2
	  table.delete(abbrev)
	else
	  break
	end
      end
    end

    words.each do |word|
      next if pattern && pattern !~ word

      table[word] = word
    end

    table
  end

  module_function :abbrev
end

class Array
  # Calculates the set of unambiguous abbreviations for the strings in
  # +self+. If passed a pattern or a string, only the strings matching
  # the pattern or starting with the string are considered.
  #
  #   %w{ car cone }.abbrev   #=> { "ca" => "car", "car" => "car",
  #                                 "co" => "cone", "con" => cone",
  #                                 "cone" => "cone" }
  def abbrev(pattern = nil)
    Abbrev::abbrev(self, pattern)
  end
end

if $0 == __FILE__
  while line = gets
    hash = line.split.abbrev

    hash.sort.each do |k, v|
      puts "#{k} => #{v}"
    end
  end
end
PK     Z\U      sha1.rbnu [        # just for compatibility; requiring "sha1" is obsoleted
#
# $RoughId: sha1.rb,v 1.4 2001/07/13 15:38:27 knu Exp $
# $Id: sha1.rb 12007 2007-03-06 10:09:51Z knu $

require 'digest/sha1'

class SHA1 < Digest::SHA1
  class << self
    alias orig_new new
    def new(str = nil)
      if str
        orig_new.update(str)
      else
        orig_new
      end
    end

    def sha1(*args)
      new(*args)
    end
  end
end
PK     Z\W      soap/netHttpClient.rbnu [        # SOAP4R - net/http wrapper
# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'net/http'


module SOAP


class NetHttpClient

  SSLEnabled = begin
      require 'net/https'
      true
    rescue LoadError
      false
    end

  attr_reader :proxy
  attr_accessor :no_proxy
  attr_accessor :debug_dev
  attr_accessor :ssl_config		# ignored for now.
  attr_accessor :protocol_version	# ignored for now.
  attr_accessor :connect_timeout
  attr_accessor :send_timeout           # ignored for now.
  attr_accessor :receive_timeout

  def initialize(proxy = nil, agent = nil)
    @proxy = proxy ? URI.parse(proxy) : nil
    @agent = agent
    @debug_dev = nil
    @session_manager = SessionManager.new
    @no_proxy = @ssl_config = @protocol_version = nil
    @connect_timeout = @send_timeout = @receive_timeout = nil
  end

  def test_loopback_response
    raise NotImplementedError.new("not supported for now")
  end
  
  def proxy=(proxy)
    if proxy.nil?
      @proxy = nil
    else
      if proxy.is_a?(URI)
        @proxy = proxy
      else
        @proxy = URI.parse(proxy)
      end
      if @proxy.scheme == nil or @proxy.scheme.downcase != 'http' or
	  @proxy.host == nil or @proxy.port == nil
	raise ArgumentError.new("unsupported proxy `#{proxy}'")
      end
    end
    reset_all
    @proxy
  end

  def set_basic_auth(uri, user_id, passwd)
    # net/http does not handle url.
    @basic_auth = [user_id, passwd]
    raise NotImplementedError.new("basic_auth is not supported under soap4r + net/http.")
  end

  def set_cookie_store(filename)
    raise NotImplementedError.new
  end

  def save_cookie_store(filename)
    raise NotImplementedError.new
  end

  def reset(url)
    # no persistent connection.  ignored.
  end

  def reset_all
    # no persistent connection.  ignored.
  end

  def post(url, req_body, header = {})
    unless url.is_a?(URI)
      url = URI.parse(url)
    end
    extra = header.dup
    extra['User-Agent'] = @agent if @agent
    res = start(url) { |http|
      http.post(url.request_uri, req_body, extra)
    }
    Response.new(res)
  end

  def get_content(url, header = {})
    unless url.is_a?(URI)
      url = URI.parse(url)
    end
    extra = header.dup
    extra['User-Agent'] = @agent if @agent
    res = start(url) { |http|
	http.get(url.request_uri, extra)
      }
    res.body
  end

private

  def start(url)
    http = create_connection(url)
    response = nil
    http.start { |worker|
      response = yield(worker)
      worker.finish
    }
    @debug_dev << response.body if @debug_dev
    response
  end

  def create_connection(url)
    proxy_host = proxy_port = nil
    unless no_proxy?(url)
      proxy_host = @proxy.host
      proxy_port = @proxy.port
    end
    http = Net::HTTP::Proxy(proxy_host, proxy_port).new(url.host, url.port)
    if http.respond_to?(:set_debug_output)
      http.set_debug_output(@debug_dev)
    end
    http.open_timeout = @connect_timeout if @connect_timeout
    http.read_timeout = @receive_timeout if @receive_timeout
    case url
    when URI::HTTPS
      if SSLEnabled
	http.use_ssl = true
      else
	raise RuntimeError.new("Cannot connect to #{url} (OpenSSL is not installed.)")
      end
    when URI::HTTP
      # OK
    else
      raise RuntimeError.new("Cannot connect to #{url} (Not HTTP.)")
    end
    http
  end

  NO_PROXY_HOSTS = ['localhost']

  def no_proxy?(uri)
    if !@proxy or NO_PROXY_HOSTS.include?(uri.host)
      return true
    end
    if @no_proxy
      @no_proxy.scan(/([^:,]*)(?::(\d+))?/) do |host, port|
  	if /(\A|\.)#{Regexp.quote(host)}\z/i =~ uri.host &&
	    (!port || uri.port == port.to_i)
	  return true
	end
      end
    else
      false
    end
  end

  class SessionManager
    attr_accessor :connect_timeout
    attr_accessor :send_timeout
    attr_accessor :receive_timeout
  end

  class Response
    attr_reader :content
    attr_reader :status
    attr_reader :reason
    attr_reader :contenttype

    def initialize(res)
      @status = res.code.to_i
      @reason = res.message
      @contenttype = res['content-type']
      @content = res.body
    end
  end
end


end
PK     Z\u      soap/generator.rbnu [        # SOAP4R - SOAP XML Instance Generator library.
# Copyright (C) 2001, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/ns'
require 'soap/soap'
require 'soap/baseData'
require 'soap/encodingstyle/handler'


module SOAP


###
## CAUTION: MT-unsafe
#
class SOAPGenerator
  include SOAP

  class FormatEncodeError < Error; end

public

  attr_accessor :charset
  attr_accessor :default_encodingstyle
  attr_accessor :generate_explicit_type
  attr_accessor :use_numeric_character_reference

  def initialize(opt = {})
    @reftarget = nil
    @handlers = {}
    @charset = opt[:charset] || XSD::Charset.xml_encoding_label
    @default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace
    @generate_explicit_type =
      opt.key?(:generate_explicit_type) ? opt[:generate_explicit_type] : true
    @elementformdefault = opt[:elementformdefault]
    @attributeformdefault = opt[:attributeformdefault]
    @use_numeric_character_reference = opt[:use_numeric_character_reference]
    @indentstr = opt[:no_indent] ? '' : '  '
    @buf = @indent = @curr = nil
  end

  def generate(obj, io = nil)
    @buf = io || ''
    @indent = ''

    prologue
    @handlers.each do |uri, handler|
      handler.encode_prologue
    end

    ns = XSD::NS.new
    @buf << xmldecl
    encode_data(ns, obj, nil)

    @handlers.each do |uri, handler|
      handler.encode_epilogue
    end
    epilogue

    @buf
  end

  def encode_data(ns, obj, parent)
    if obj.is_a?(SOAPEnvelopeElement)
      encode_element(ns, obj, parent)
      return
    end
    if @reftarget && !obj.precedents.empty?
      add_reftarget(obj.elename.name, obj)
      ref = SOAPReference.new(obj)
      ref.elename = ref.elename.dup_name(obj.elename.name)
      obj.precedents.clear	# Avoid cyclic delay.
      obj.encodingstyle = parent.encodingstyle
      # SOAPReference is encoded here.
      obj = ref
    end
    encodingstyle = obj.encodingstyle
    # Children's encodingstyle is derived from its parent.
    encodingstyle ||= parent.encodingstyle if parent
    obj.encodingstyle = encodingstyle
    handler = find_handler(encodingstyle || @default_encodingstyle)
    unless handler
      raise FormatEncodeError.new("Unknown encodingStyle: #{ encodingstyle }.")
    end
    if !obj.elename.name
      raise FormatEncodeError.new("Element name not defined: #{ obj }.")
    end
    handler.encode_data(self, ns, obj, parent)
    handler.encode_data_end(self, ns, obj, parent)
  end

  def add_reftarget(name, node)
    unless @reftarget
      raise FormatEncodeError.new("Reftarget is not defined.")
    end
    @reftarget.add(name, node)
  end

  def encode_child(ns, child, parent)
    indent_backup, @indent = @indent, @indent + @indentstr
    encode_data(ns.clone_ns, child, parent)
    @indent = indent_backup
  end

  def encode_element(ns, obj, parent)
    attrs = {}
    if obj.is_a?(SOAPBody)
      @reftarget = obj
      obj.encode(self, ns, attrs) do |child|
	indent_backup, @indent = @indent, @indent + @indentstr
        encode_data(ns.clone_ns, child, obj)
	@indent = indent_backup
      end
      @reftarget = nil
    else
      if obj.is_a?(SOAPEnvelope)
        # xsi:nil="true" can appear even if dumping without explicit type.
        SOAPGenerator.assign_ns(attrs, ns,
	  XSD::InstanceNamespace, XSINamespaceTag)
        if @generate_explicit_type
          SOAPGenerator.assign_ns(attrs, ns, XSD::Namespace, XSDNamespaceTag)
        end
      end
      obj.encode(self, ns, attrs) do |child|
	indent_backup, @indent = @indent, @indent + @indentstr
        encode_data(ns.clone_ns, child, obj)
	@indent = indent_backup
      end
    end
  end

  def encode_name(ns, data, attrs)
    if element_local?(data)
      data.elename.name
    else
      if element_qualified?(data)
        SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace, '')
      else
        SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace)
      end
      ns.name(data.elename)
    end
  end

  def encode_name_end(ns, data)
    if element_local?(data)
      data.elename.name
    else
      ns.name(data.elename)
    end
  end

  def encode_tag(elename, attrs = nil)
    if !attrs or attrs.empty?
      @buf << "\n#{ @indent }<#{ elename }>"
    elsif attrs.size == 1
      key, value = attrs.shift
      @buf << %Q[\n#{ @indent }<#{ elename } #{ key }="#{ value }">]
    else
      @buf << "\n#{ @indent }<#{ elename } " <<
        attrs.collect { |key, value|
          %Q[#{ key }="#{ value }"]
        }.join("\n#{ @indent }#{ @indentstr * 2 }") <<
	'>'
    end
  end

  def encode_tag_end(elename, cr = nil)
    if cr
      @buf << "\n#{ @indent }</#{ elename }>"
    else
      @buf << "</#{ elename }>"
    end
  end

  def encode_rawstring(str)
    @buf << str
  end

  EncodeMap = {
    '&' => '&amp;',
    '<' => '&lt;',
    '>' => '&gt;',
    '"' => '&quot;',
    '\'' => '&apos;',
    "\r" => '&#xd;'
  }
  EncodeCharRegexp = Regexp.new("[#{EncodeMap.keys.join}]")
  def encode_string(str)
    if @use_numeric_character_reference and !XSD::Charset.is_us_ascii(str)
      str.gsub!(EncodeCharRegexp) { |c| EncodeMap[c] }
      @buf << str.unpack("U*").collect { |c|
        if c == 0x9 or c == 0xa or c == 0xd or (c >= 0x20 and c <= 0x7f)
          c.chr
        else
          sprintf("&#x%x;", c)
        end
      }.join
    else
      @buf << str.gsub(EncodeCharRegexp) { |c| EncodeMap[c] }
    end
  end

  def element_local?(element)
    element.elename.namespace.nil?
  end

  def element_qualified?(element)
    if element.respond_to?(:qualified)
      if element.qualified.nil?
        @elementformdefault
      else
        element.qualified
      end
    else
      @elementformdefault
    end
  end

  def self.assign_ns(attrs, ns, namespace, tag = nil)
    if namespace.nil?
      raise FormatEncodeError.new("empty namespace")
    end
    unless ns.assigned?(namespace)
      tag = ns.assign(namespace, tag)
      if tag == ''
        attr = 'xmlns'
      else
        attr = "xmlns:#{tag}"
      end
      attrs[attr] = namespace
    end
  end

private

  def prologue
  end

  def epilogue
  end

  def find_handler(encodingstyle)
    unless @handlers.key?(encodingstyle)
      handler = SOAP::EncodingStyle::Handler.handler(encodingstyle).new(@charset)
      handler.generate_explicit_type = @generate_explicit_type
      handler.encode_prologue
      @handlers[encodingstyle] = handler
    end
    @handlers[encodingstyle]
  end

  def xmldecl
    if @charset
      %Q[<?xml version="1.0" encoding="#{ @charset }" ?>]
    else
      %Q[<?xml version="1.0" ?>]
    end
  end
end


end
PK     Z\Ꞙ      soap/httpconfigloader.rbnu [        # SOAP4R - HTTP config loader.
# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/property'


module SOAP


module HTTPConfigLoader
module_function

  def set_options(client, options)
    client.proxy = options["proxy"]
    options.add_hook("proxy") do |key, value|
      client.proxy = value
    end
    client.no_proxy = options["no_proxy"]
    options.add_hook("no_proxy") do |key, value|
      client.no_proxy = value
    end
    if client.respond_to?(:protocol_version=)
      client.protocol_version = options["protocol_version"]
      options.add_hook("protocol_version") do |key, value|
        client.protocol_version = value
      end
    end
    ssl_config = options["ssl_config"] ||= ::SOAP::Property.new
    set_ssl_config(client, ssl_config)
    ssl_config.add_hook(true) do |key, value|
      set_ssl_config(client, ssl_config)
    end
    basic_auth = options["basic_auth"] ||= ::SOAP::Property.new
    set_basic_auth(client, basic_auth)
    basic_auth.add_hook do |key, value|
      set_basic_auth(client, basic_auth)
    end
    options.add_hook("connect_timeout") do |key, value|
      client.connect_timeout = value
    end
    options.add_hook("send_timeout") do |key, value|
      client.send_timeout = value
    end
    options.add_hook("receive_timeout") do |key, value|
      client.receive_timeout = value
    end
  end

  def set_basic_auth(client, basic_auth)
    basic_auth.values.each do |url, userid, passwd|
      client.set_basic_auth(url, userid, passwd)
    end
  end

  def set_ssl_config(client, ssl_config)
    ssl_config.each do |key, value|
      cfg = client.ssl_config
      if cfg.nil?
        raise NotImplementedError.new("SSL not supported")
      end
      case key
      when 'client_cert'
        cfg.client_cert = cert_from_file(value)
      when 'client_key'
        cfg.client_key = key_from_file(value)
      when 'client_ca'
        cfg.client_ca = value
      when 'ca_path'
        cfg.set_trust_ca(value)
      when 'ca_file'
        cfg.set_trust_ca(value)
      when 'crl'
        cfg.set_crl(value)
      when 'verify_mode'
        cfg.verify_mode = ssl_config_int(value)
      when 'verify_depth'
        cfg.verify_depth = ssl_config_int(value)
      when 'options'
        cfg.options = value
      when 'ciphers'
        cfg.ciphers = value
      when 'verify_callback'
        cfg.verify_callback = value
      when 'cert_store'
        cfg.cert_store = value
      else
        raise ArgumentError.new("unknown ssl_config property #{key}")
      end
    end
  end

  def ssl_config_int(value)
    if value.nil? or value.to_s.empty?
      nil
    else
      begin
        Integer(value)
      rescue ArgumentError
        ::SOAP::Property::Util.const_from_name(value.to_s)
      end
    end
  end

  def cert_from_file(filename)
    OpenSSL::X509::Certificate.new(File.open(filename) { |f| f.read })
  end

  def key_from_file(filename)
    OpenSSL::PKey::RSA.new(File.open(filename) { |f| f.read })
  end
end


end
PK     Z\!-  -    soap/header/handlerset.rbnu [        # SOAP4R - SOAP Header handler set
# Copyright (C) 2003, 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/namedelements'


module SOAP
module Header


class HandlerSet
  def initialize
    @store = XSD::NamedElements.new
  end

  def dup
    obj = HandlerSet.new
    obj.store = @store.dup
    obj
  end

  def add(handler)
    @store << handler
  end
  alias << add

  def delete(handler)
    @store.delete(handler)
  end

  def include?(handler)
    @store.include?(handler)
  end

  # returns: Array of SOAPHeaderItem
  def on_outbound
    @store.collect { |handler|
      handler.on_outbound_headeritem
    }.compact
  end

  # headers: SOAPHeaderItem enumerable object
  def on_inbound(headers)
    headers.each do |name, item|
      handler = @store.find { |handler|
        handler.elename == item.element.elename
      }
      if handler
        handler.on_inbound_headeritem(item)
      elsif item.mustunderstand
        raise UnhandledMustUnderstandHeaderError.new(item.element.elename.to_s)
      end
    end
  end

protected

  def store=(store)
    @store = store
  end
end


end
end
PK     Z\T      soap/header/handler.rbnu [        # SOAP4R - SOAP Header handler item
# Copyright (C) 2003, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/element'


module SOAP
module Header


class Handler
  attr_reader :elename
  attr_reader :mustunderstand
  attr_reader :encodingstyle

  def initialize(elename)
    @elename = elename
    @mustunderstand = false
    @encodingstyle = nil
  end

  # Should return a SOAP/OM, a SOAPHeaderItem or nil.
  def on_outbound
    nil
  end

  # Given header is a SOAPHeaderItem or nil.
  def on_inbound(header, mustunderstand = false)
    # do something.
  end

  def on_outbound_headeritem
    item = on_outbound
    if item.nil?
      nil
    elsif item.is_a?(::SOAP::SOAPHeaderItem)
      item.elename = @elename
      item
    else
      item.elename = @elename
      ::SOAP::SOAPHeaderItem.new(item, @mustunderstand, @encodingstyle)
    end
  end

  def on_inbound_headeritem(header)
    on_inbound(header.element, header.mustunderstand)
  end
end


end
end
PK     Z\Nܣ      soap/header/simplehandler.rbnu [        # SOAP4R - SOAP Simple header item handler
# Copyright (C) 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/header/handler'
require 'soap/baseData'


module SOAP
module Header


class SimpleHandler < SOAP::Header::Handler
  def initialize(elename)
    super(elename)
  end

  # Should return a Hash, String or nil.
  def on_simple_outbound
    nil
  end

  # Given header is a Hash, String or nil.
  def on_simple_inbound(header, mustunderstand)
  end

  def on_outbound
    h = on_simple_outbound
    h ? SOAPElement.from_obj(h, elename.namespace) : nil
  end

  def on_inbound(header, mustunderstand)
    h = header.respond_to?(:to_obj) ? header.to_obj : header.data
    on_simple_inbound(h, mustunderstand)
  end
end


end
end
PK     Z\$r}  }    soap/processor.rbnu [        # SOAP4R - marshal/unmarshal interface.
# Copyright (C) 2000, 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/datatypes'
require 'soap/soap'
require 'soap/element'
require 'soap/parser'
require 'soap/generator'
require 'soap/encodingstyle/soapHandler'
require 'soap/encodingstyle/literalHandler'
require 'soap/encodingstyle/aspDotNetHandler'


module SOAP


module Processor
  @@default_parser_option = {}

  class << self
  public

    def marshal(env, opt = {}, io = nil)
      generator = create_generator(opt)
      marshalled_str = generator.generate(env, io)
      unless env.external_content.empty?
	opt[:external_content] = env.external_content
      end
      marshalled_str
    end

    def unmarshal(stream, opt = {})
      parser = create_parser(opt)
      parser.parse(stream)
    end

    def default_parser_option=(rhs)
      @@default_parser_option = rhs
    end

    def default_parser_option
      @@default_parser_option
    end

  private

    def create_generator(opt)
      SOAPGenerator.new(opt)
    end

    def create_parser(opt)
      if opt.empty?
	opt = @@default_parser_option
      end
      ::SOAP::Parser.new(opt)
    end
  end
end


end
PK     Z\X'      soap/mimemessage.rbnu [        # SOAP4R - MIME Message implementation.
# Copyright (C) 2002  Jamie Herre.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/attachment'


module SOAP


# Classes for MIME message handling.  Should be put somewhere else!
# Tried using the 'tmail' module but found that I needed something
# lighter in weight.


class MIMEMessage
  class MIMEMessageError < StandardError; end

  MultipartContentType = 'multipart/\w+'

  class Header
    attr_accessor :str, :key, :root

    def initialize
      @attrs = {}
    end

    def [](key)
      @attrs[key]
    end

    def []=(key, value)
      @attrs[key] = value
    end

    def to_s
      @key + ": " + @str
    end
  end

  class Headers < Hash
    def self.parse(str)
      new.parse(str)
    end

    def parse(str)
      header_cache = nil
      str.each do |line|
	case line
	when /^\A[^\: \t]+:\s*.+$/
	  parse_line(header_cache) if header_cache
	  header_cache = line.sub(/\r?\n\z/, '')
	when /^\A\s+(.*)$/
	  # a continuous line at the beginning line crashes here.
	  header_cache << line
	else
	  raise RuntimeError.new("unexpected header: #{line.inspect}")
	end
      end
      parse_line(header_cache) if header_cache
      self
    end

    def parse_line(line)
      if /^\A([^\: \t]+):\s*(.+)\z/ =~ line
    	header = parse_rhs($2.strip)
	header.key = $1.strip
	self[header.key.downcase] = header
      else
	raise RuntimeError.new("unexpected header line: #{line.inspect}")
      end
    end

    def parse_rhs(str)
      a = str.split(/;+\s+/)
      header = Header.new
      header.str = str
      header.root = a.shift
      a.each do |pair|
	if pair =~ /(\w+)\s*=\s*"?([^"]+)"?/
	  header[$1.downcase] = $2
	else
	  raise RuntimeError.new("unexpected header component: #{pair.inspect}")
	end
      end
      header
    end

    def add(key, value)
      if key != nil and value != nil
	header = parse_rhs(value)
	header.key = key
	self[key.downcase] = header
      end
    end

    def to_s
      self.values.collect { |hdr|
	hdr.to_s
      }.join("\r\n")
    end
  end

  class Part
    attr_accessor :headers, :body

    def initialize
      @headers = Headers.new
      @headers.add("Content-Transfer-Encoding", "8bit")
      @body = nil
      @contentid = nil
    end

    def self.parse(str)
      new.parse(str)
    end

    def parse(str)
      headers, body = str.split(/\r\n\r\n/s)
      if headers != nil and body != nil
	@headers = Headers.parse(headers)
	@body = body.sub(/\r\n\z/, '')
      else
	raise RuntimeError.new("unexpected part: #{str.inspect}")
      end
      self
    end

    def contentid
      if @contentid == nil and @headers.key?('content-id')
	@contentid = @headers['content-id'].str
	@contentid = $1 if @contentid =~ /^<(.+)>$/
      end
      @contentid
    end

    alias content body

    def to_s
      @headers.to_s + "\r\n\r\n" + @body
    end
  end

  def initialize
    @parts = []
    @headers = Headers.new
    @root = nil
  end

  def self.parse(head, str)
    new.parse(head, str)
  end

  attr_reader :parts, :headers

  def close
    @headers.add(
      "Content-Type",
      "multipart/related; type=\"text/xml\"; boundary=\"#{boundary}\"; start=\"#{@parts[0].contentid}\""
    )
  end

  def parse(head, str)
    @headers = Headers.parse(head + "\r\n" + "From: jfh\r\n")
    boundary = @headers['content-type']['boundary']
    if boundary != nil
      parts = str.split(/--#{Regexp.quote(boundary)}\s*(?:\r\n|--\r\n)/)
      part = parts.shift	# preamble must be ignored.
      @parts = parts.collect { |part| Part.parse(part) }
    else
      @parts = [Part.parse(str)]
    end
    if @parts.length < 1
      raise MIMEMessageError.new("This message contains no valid parts!")
    end
    self
  end

  def root
    if @root == nil
      start = @headers['content-type']['start']
      @root = (start && @parts.find { |prt| prt.contentid == start }) ||
	@parts[0]
    end
    @root
  end

  def boundary
    if @boundary == nil
      @boundary = "----=Part_" + __id__.to_s + rand.to_s
    end
    @boundary
  end

  def add_part(content)
    part = Part.new
    part.headers.add("Content-Type",
      "text/xml; charset=" + XSD::Charset.xml_encoding_label)
    part.headers.add("Content-ID", Attachment.contentid(part))
    part.body = content
    @parts.unshift(part)
  end

  def add_attachment(attach)
    part = Part.new
    part.headers.add("Content-Type", attach.contenttype)
    part.headers.add("Content-ID", attach.mime_contentid)
    part.body = attach.content
    @parts.unshift(part)
  end

  def has_parts?
    (@parts.length > 0)
  end

  def headers_str
    @headers.to_s
  end

  def content_str
    str = ''
    @parts.each do |prt|
      str << "--" + boundary + "\r\n"
      str << prt.to_s + "\r\n"
    end
    str << '--' + boundary + "--\r\n"
    str
  end

  def to_s
    str = headers_str + "\r\n\r\n" + content_str
  end
end


end
PK     Z\2 CB  B    soap/baseData.rbnu [        # soap/baseData.rb: SOAP4R - Base type library
# Copyright (C) 2000, 2001, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/datatypes'
require 'soap/soap'


module SOAP


###
## Mix-in module for SOAP base type classes.
#
module SOAPModuleUtils
  include SOAP

public

  def decode(elename)
    d = self.new
    d.elename = elename
    d
  end
end


###
## for SOAP type(base and compound)
#
module SOAPType
  attr_accessor :encodingstyle
  attr_accessor :elename
  attr_accessor :id
  attr_reader :precedents
  attr_accessor :root
  attr_accessor :parent
  attr_accessor :position
  attr_reader :extraattr
  attr_accessor :definedtype

  def initialize(*arg)
    super
    @encodingstyle = nil
    @elename = XSD::QName::EMPTY
    @id = nil
    @precedents = []
    @root = false
    @parent = nil
    @position = nil
    @definedtype = nil
    @extraattr = {}
  end

  def inspect
    if self.is_a?(XSD::NSDBase)
      sprintf("#<%s:0x%x %s %s>", self.class.name, __id__, self.elename, self.type)
    else
      sprintf("#<%s:0x%x %s>", self.class.name, __id__, self.elename)
    end
  end

  def rootnode
    node = self
    while node = node.parent
      break if SOAPEnvelope === node
    end
    node
  end
end


###
## for SOAP base type
#
module SOAPBasetype
  include SOAPType
  include SOAP

  def initialize(*arg)
    super
  end
end


###
## for SOAP compound type
#
module SOAPCompoundtype
  include SOAPType
  include SOAP

  def initialize(*arg)
    super
  end
end


###
## Convenience datatypes.
#
class SOAPReference < XSD::NSDBase
  include SOAPBasetype
  extend SOAPModuleUtils

public

  attr_accessor :refid

  # Override the definition in SOAPBasetype.
  def initialize(obj = nil)
    super()
    @type = XSD::QName::EMPTY
    @refid = nil
    @obj = nil
    __setobj__(obj) if obj
  end

  def __getobj__
    @obj
  end

  def __setobj__(obj)
    @obj = obj
    @refid = @obj.id || SOAPReference.create_refid(@obj)
    @obj.id = @refid unless @obj.id
    @obj.precedents << self
    # Copies NSDBase information
    @obj.type = @type unless @obj.type
  end

  # Why don't I use delegate.rb?
  # -> delegate requires target object type at initialize time.
  # Why don't I use forwardable.rb?
  # -> forwardable requires a list of forwarding methods.
  #
  # ToDo: Maybe I should use forwardable.rb and give it a methods list like
  # delegate.rb...
  #
  def method_missing(msg_id, *params)
    if @obj
      @obj.send(msg_id, *params)
    else
      nil
    end
  end

  def refidstr
    '#' + @refid
  end

  def self.create_refid(obj)
    'id' + obj.__id__.to_s
  end

  def self.decode(elename, refidstr)
    if /\A#(.*)\z/ =~ refidstr
      refid = $1
    elsif /\Acid:(.*)\z/ =~ refidstr
      refid = $1
    else
      raise ArgumentError.new("illegal refid #{refidstr}")
    end
    d = super(elename)
    d.refid = refid
    d
  end
end


class SOAPExternalReference < XSD::NSDBase
  include SOAPBasetype
  extend SOAPModuleUtils

  def initialize
    super()
    @type = XSD::QName::EMPTY
  end

  def referred
    rootnode.external_content[external_contentid] = self
  end

  def refidstr
    'cid:' + external_contentid
  end

private

  def external_contentid
    raise NotImplementedError.new
  end
end


class SOAPNil < XSD::XSDNil
  include SOAPBasetype
  extend SOAPModuleUtils
end

# SOAPRawString is for sending raw string.  In contrast to SOAPString,
# SOAP4R does not do XML encoding and does not convert its CES.  The string it
# holds is embedded to XML instance directly as a 'xsd:string'.
class SOAPRawString < XSD::XSDString
  include SOAPBasetype
  extend SOAPModuleUtils
end


###
## Basic datatypes.
#
class SOAPAnySimpleType < XSD::XSDAnySimpleType
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPString < XSD::XSDString
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPBoolean < XSD::XSDBoolean
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPDecimal < XSD::XSDDecimal
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPFloat < XSD::XSDFloat
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPDouble < XSD::XSDDouble
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPDuration < XSD::XSDDuration
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPDateTime < XSD::XSDDateTime
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPTime < XSD::XSDTime
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPDate < XSD::XSDDate
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPGYearMonth < XSD::XSDGYearMonth
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPGYear < XSD::XSDGYear
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPGMonthDay < XSD::XSDGMonthDay
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPGDay < XSD::XSDGDay
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPGMonth < XSD::XSDGMonth
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPHexBinary < XSD::XSDHexBinary
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPBase64 < XSD::XSDBase64Binary
  include SOAPBasetype
  extend SOAPModuleUtils
  Type = QName.new(EncodingNamespace, Base64Literal)

public
  # Override the definition in SOAPBasetype.
  def initialize(value = nil)
    super(value)
    @type = Type
  end

  def as_xsd
    @type = XSD::XSDBase64Binary::Type
  end
end

class SOAPAnyURI < XSD::XSDAnyURI
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPQName < XSD::XSDQName
  include SOAPBasetype
  extend SOAPModuleUtils
end


class SOAPInteger < XSD::XSDInteger
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPNonPositiveInteger < XSD::XSDNonPositiveInteger
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPNegativeInteger < XSD::XSDNegativeInteger
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPLong < XSD::XSDLong
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPInt < XSD::XSDInt
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPShort < XSD::XSDShort
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPByte < XSD::XSDByte
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPNonNegativeInteger < XSD::XSDNonNegativeInteger
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPUnsignedLong < XSD::XSDUnsignedLong
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPUnsignedInt < XSD::XSDUnsignedInt
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPUnsignedShort < XSD::XSDUnsignedShort
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPUnsignedByte < XSD::XSDUnsignedByte
  include SOAPBasetype
  extend SOAPModuleUtils
end

class SOAPPositiveInteger < XSD::XSDPositiveInteger
  include SOAPBasetype
  extend SOAPModuleUtils
end


###
## Compound datatypes.
#
class SOAPStruct < XSD::NSDBase
  include SOAPCompoundtype
  include Enumerable

public

  def initialize(type = nil)
    super()
    @type = type || XSD::QName::EMPTY
    @array = []
    @data = []
  end

  def to_s()
    str = ''
    self.each do |key, data|
      str << "#{key}: #{data}\n"
    end
    str
  end

  def add(name, value)
    add_member(name, value)
  end

  def [](idx)
    if idx.is_a?(Range)
      @data[idx]
    elsif idx.is_a?(Integer)
      if (idx > @array.size)
        raise ArrayIndexOutOfBoundsError.new('In ' << @type.name)
      end
      @data[idx]
    else
      if @array.include?(idx)
	@data[@array.index(idx)]
      else
	nil
      end
    end
  end

  def []=(idx, data)
    if @array.include?(idx)
      data.parent = self if data.respond_to?(:parent=)
      @data[@array.index(idx)] = data
    else
      add(idx, data)
    end
  end

  def key?(name)
    @array.include?(name)
  end

  def members
    @array
  end

  def to_obj
    hash = {}
    proptype = {}
    each do |k, v|
      value = v.respond_to?(:to_obj) ? v.to_obj : v.to_s
      case proptype[k]
      when :single
        hash[k] = [hash[k], value]
        proptype[k] = :multi
      when :multi
        hash[k] << value
      else
        hash[k] = value
        proptype[k] = :single
      end
    end
    hash
  end

  def each
    idx = 0
    while idx < @array.length
      yield(@array[idx], @data[idx])
      idx += 1
    end
  end

  def replace
    members.each do |member|
      self[member] = yield(self[member])
    end
  end

  def self.decode(elename, type)
    s = SOAPStruct.new(type)
    s.elename = elename
    s
  end

private

  def add_member(name, value = nil)
    value = SOAPNil.new() if value.nil?
    @array.push(name)
    value.elename = value.elename.dup_name(name)
    @data.push(value)
    value.parent = self if value.respond_to?(:parent=)
    value
  end
end


# SOAPElement is not typed so it is not derived from NSDBase.
class SOAPElement
  include Enumerable

  attr_accessor :encodingstyle

  attr_accessor :elename
  attr_accessor :id
  attr_reader :precedents
  attr_accessor :root
  attr_accessor :parent
  attr_accessor :position
  attr_accessor :extraattr

  attr_accessor :qualified

  def initialize(elename, text = nil)
    if !elename.is_a?(XSD::QName)
      elename = XSD::QName.new(nil, elename)
    end
    @encodingstyle = LiteralNamespace
    @elename = elename
    @id = nil
    @precedents = []
    @root = false
    @parent = nil
    @position = nil
    @extraattr = {}

    @qualified = nil

    @array = []
    @data = []
    @text = text
  end

  def inspect
    sprintf("#<%s:0x%x %s>", self.class.name, __id__, self.elename)
  end

  # Text interface.
  attr_accessor :text
  alias data text

  # Element interfaces.
  def add(value)
    add_member(value.elename.name, value)
  end

  def [](idx)
    if @array.include?(idx)
      @data[@array.index(idx)]
    else
      nil
    end
  end

  def []=(idx, data)
    if @array.include?(idx)
      data.parent = self if data.respond_to?(:parent=)
      @data[@array.index(idx)] = data
    else
      add(data)
    end
  end

  def key?(name)
    @array.include?(name)
  end

  def members
    @array
  end

  def to_obj
    if members.empty?
      @text
    else
      hash = {}
      proptype = {}
      each do |k, v|
        value = v.respond_to?(:to_obj) ? v.to_obj : v.to_s
        case proptype[k]
        when :single
          hash[k] = [hash[k], value]
          proptype[k] = :multi
        when :multi
          hash[k] << value
        else
          hash[k] = value
          proptype[k] = :single
        end
      end
      hash
    end
  end

  def each
    idx = 0
    while idx < @array.length
      yield(@array[idx], @data[idx])
      idx += 1
    end
  end

  def self.decode(elename)
    o = SOAPElement.new(elename)
    o
  end

  def self.from_obj(obj, namespace = nil)
    o = SOAPElement.new(nil)
    case obj
    when nil
      o.text = nil
    when Hash
      obj.each do |elename, value|
        if value.is_a?(Array)
          value.each do |subvalue|
            child = from_obj(subvalue, namespace)
            child.elename = to_elename(elename, namespace)
            o.add(child)
          end
        else
          child = from_obj(value, namespace)
          child.elename = to_elename(elename, namespace)
          o.add(child)
        end
      end
    else
      o.text = obj.to_s
    end
    o
  end

  def self.to_elename(obj, namespace = nil)
    if obj.is_a?(XSD::QName)
      obj
    elsif /\A(.+):([^:]+)\z/ =~ obj.to_s
      XSD::QName.new($1, $2)
    else
      XSD::QName.new(namespace, obj.to_s)
    end
  end

private

  def add_member(name, value)
    add_accessor(name)
    @array.push(name)
    @data.push(value)
    value.parent = self if value.respond_to?(:parent=)
    value
  end

  if RUBY_VERSION > "1.7.0"
    def add_accessor(name)
      methodname = name
      if self.respond_to?(methodname)
        methodname = safe_accessor_name(methodname)
      end
      Mapping.define_singleton_method(self, methodname) do
        @data[@array.index(name)]
      end
      Mapping.define_singleton_method(self, methodname + '=') do |value|
        @data[@array.index(name)] = value
      end
    end
  else
    def add_accessor(name)
      methodname = safe_accessor_name(name)
      instance_eval <<-EOS
        def #{methodname}
          @data[@array.index(#{name.dump})]
        end

        def #{methodname}=(value)
          @data[@array.index(#{name.dump})] = value
        end
      EOS
    end
  end

  def safe_accessor_name(name)
    "var_" << name.gsub(/[^a-zA-Z0-9_]/, '')
  end
end


class SOAPArray < XSD::NSDBase
  include SOAPCompoundtype
  include Enumerable

public

  attr_accessor :sparse

  attr_reader :offset, :rank
  attr_accessor :size, :size_fixed
  attr_reader :arytype

  def initialize(type = nil, rank = 1, arytype = nil)
    super()
    @type = type || ValueArrayName
    @rank = rank
    @data = Array.new
    @sparse = false
    @offset = Array.new(rank, 0)
    @size = Array.new(rank, 0)
    @size_fixed = false
    @position = nil
    @arytype = arytype
  end

  def offset=(var)
    @offset = var
    @sparse = true
  end

  def add(value)
    self[*(@offset)] = value
  end

  def [](*idxary)
    if idxary.size != @rank
      raise ArgumentError.new("given #{idxary.size} params does not match rank: #{@rank}")
    end

    retrieve(idxary)
  end

  def []=(*idxary)
    value = idxary.slice!(-1)

    if idxary.size != @rank
      raise ArgumentError.new("given #{idxary.size} params(#{idxary})" +
        " does not match rank: #{@rank}")
    end

    idx = 0
    while idx < idxary.size
      if idxary[idx] + 1 > @size[idx]
	@size[idx] = idxary[idx] + 1
      end
      idx += 1
    end

    data = retrieve(idxary[0, idxary.size - 1])
    data[idxary.last] = value

    if value.is_a?(SOAPType)
      value.elename = ITEM_NAME
      # Sync type
      unless @type.name
	@type = XSD::QName.new(value.type.namespace,
	  SOAPArray.create_arytype(value.type.name, @rank))
      end
      value.type ||= @type
    end

    @offset = idxary
    value.parent = self if value.respond_to?(:parent=)
    offsetnext
  end

  def each
    @data.each do |data|
      yield(data)
    end
  end

  def to_a
    @data.dup
  end

  def replace
    @data = deep_map(@data) do |ele|
      yield(ele)
    end
  end

  def deep_map(ary, &block)
    ary.collect do |ele|
      if ele.is_a?(Array)
	deep_map(ele, &block)
      else
	new_obj = block.call(ele)
	new_obj.elename = ITEM_NAME
	new_obj
      end
    end
  end

  def include?(var)
    traverse_data(@data) do |v, *rank|
      if v.is_a?(SOAPBasetype) && v.data == var
	return true
      end
    end
    false
  end

  def traverse
    traverse_data(@data) do |v, *rank|
      unless @sparse
       yield(v)
      else
       yield(v, *rank) if v && !v.is_a?(SOAPNil)
      end
    end
  end

  def soap2array(ary)
    traverse_data(@data) do |v, *position|
      iteary = ary
      rank = 1
      while rank < position.size
	idx = position[rank - 1]
	if iteary[idx].nil?
	  iteary = iteary[idx] = Array.new
	else
	  iteary = iteary[idx]
	end
        rank += 1
      end
      if block_given?
	iteary[position.last] = yield(v)
      else
	iteary[position.last] = v
      end
    end
  end

  def position
    @position
  end

private

  ITEM_NAME = XSD::QName.new(nil, 'item')

  def retrieve(idxary)
    data = @data
    rank = 1
    while rank <= idxary.size
      idx = idxary[rank - 1]
      if data[idx].nil?
	data = data[idx] = Array.new
      else
	data = data[idx]
      end
      rank += 1
    end
    data
  end

  def traverse_data(data, rank = 1)
    idx = 0
    while idx < ranksize(rank)
      if rank < @rank
	traverse_data(data[idx], rank + 1) do |*v|
	  v[1, 0] = idx
       	  yield(*v)
	end
      else
	yield(data[idx], idx)
      end
      idx += 1
    end
  end

  def ranksize(rank)
    @size[rank - 1]
  end

  def offsetnext
    move = false
    idx = @offset.size - 1
    while !move && idx >= 0
      @offset[idx] += 1
      if @size_fixed
	if @offset[idx] < @size[idx]
	  move = true
	else
	  @offset[idx] = 0
	  idx -= 1
	end
      else
	move = true
      end
    end
  end

  # Module function

public

  def self.decode(elename, type, arytype)
    typestr, nofary = parse_type(arytype.name)
    rank = nofary.count(',') + 1
    plain_arytype = XSD::QName.new(arytype.namespace, typestr)
    o = SOAPArray.new(type, rank, plain_arytype)
    size = []
    nofary.split(',').each do |s|
      if s.empty?
	size.clear
	break
      else
	size << s.to_i
      end
    end
    unless size.empty?
      o.size = size
      o.size_fixed = true
    end
    o.elename = elename
    o
  end

private

  def self.create_arytype(typename, rank)
    "#{typename}[" << ',' * (rank - 1) << ']'
  end

  TypeParseRegexp = Regexp.new('^(.+)\[([\d,]*)\]$')

  def self.parse_type(string)
    TypeParseRegexp =~ string
    return $1, $2
  end
end


require 'soap/mapping/typeMap'


end
PK     Z\ j      soap/soap.rbnu [        # soap/soap.rb: SOAP4R - Base definitions.
# Copyright (C) 2000-2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/qname'
require 'xsd/charset'


module SOAP


VERSION = Version = '1.5.5'
PropertyName = 'soap/property'

EnvelopeNamespace = 'http://schemas.xmlsoap.org/soap/envelope/'
EncodingNamespace = 'http://schemas.xmlsoap.org/soap/encoding/'
LiteralNamespace = 'http://xml.apache.org/xml-soap/literalxml'

NextActor = 'http://schemas.xmlsoap.org/soap/actor/next'

EleEnvelope = 'Envelope'
EleHeader = 'Header'
EleBody = 'Body'
EleFault = 'Fault'
EleFaultString = 'faultstring'
EleFaultActor = 'faultactor'
EleFaultCode = 'faultcode'
EleFaultDetail = 'detail'

AttrMustUnderstand = 'mustUnderstand'
AttrEncodingStyle = 'encodingStyle'
AttrActor = 'actor'
AttrRoot = 'root'
AttrArrayType = 'arrayType'
AttrOffset = 'offset'
AttrPosition = 'position'
ValueArray = 'Array'

EleEnvelopeName = XSD::QName.new(EnvelopeNamespace, EleEnvelope).freeze
EleHeaderName = XSD::QName.new(EnvelopeNamespace, EleHeader).freeze
EleBodyName = XSD::QName.new(EnvelopeNamespace, EleBody).freeze
EleFaultName = XSD::QName.new(EnvelopeNamespace, EleFault).freeze
EleFaultStringName = XSD::QName.new(nil, EleFaultString).freeze
EleFaultActorName = XSD::QName.new(nil, EleFaultActor).freeze
EleFaultCodeName = XSD::QName.new(nil, EleFaultCode).freeze
EleFaultDetailName = XSD::QName.new(nil, EleFaultDetail).freeze
AttrMustUnderstandName = XSD::QName.new(EnvelopeNamespace, AttrMustUnderstand).freeze
AttrEncodingStyleName = XSD::QName.new(EnvelopeNamespace, AttrEncodingStyle).freeze
AttrRootName = XSD::QName.new(EncodingNamespace, AttrRoot).freeze
AttrArrayTypeName = XSD::QName.new(EncodingNamespace, AttrArrayType).freeze
AttrOffsetName = XSD::QName.new(EncodingNamespace, AttrOffset).freeze
AttrPositionName = XSD::QName.new(EncodingNamespace, AttrPosition).freeze
ValueArrayName = XSD::QName.new(EncodingNamespace, ValueArray).freeze

Base64Literal = 'base64'

SOAPNamespaceTag = 'env'
XSDNamespaceTag = 'xsd'
XSINamespaceTag = 'xsi'

MediaType = 'text/xml'

class Error < StandardError; end

class StreamError < Error; end
class HTTPStreamError < StreamError; end
class PostUnavailableError < HTTPStreamError; end
class MPostUnavailableError < HTTPStreamError; end

class ArrayIndexOutOfBoundsError < Error; end
class ArrayStoreError < Error; end

class RPCRoutingError < Error; end
class EmptyResponseError < Error; end
class ResponseFormatError < Error; end

class UnhandledMustUnderstandHeaderError < Error; end

class FaultError < Error
  attr_reader :faultcode
  attr_reader :faultstring
  attr_reader :faultactor
  attr_accessor :detail

  def initialize(fault)
    @faultcode = fault.faultcode
    @faultstring = fault.faultstring
    @faultactor = fault.faultactor
    @detail = fault.detail
    super(self.to_s)
  end

  def to_s
    str = nil
    if @faultstring and @faultstring.respond_to?('data')
      str = @faultstring.data
    end
    str || '(No faultstring)'
  end
end


module Env
  def self.getenv(name)
    ENV[name.downcase] || ENV[name.upcase]
  end

  use_proxy = getenv('soap_use_proxy') == 'on'
  HTTP_PROXY = use_proxy ? getenv('http_proxy') : nil
  NO_PROXY = use_proxy ? getenv('no_proxy') : nil
end


end


unless Object.respond_to?(:instance_variable_get)
  class Object
    def instance_variable_get(ivarname)
      instance_eval(ivarname)
    end

    def instance_variable_set(ivarname, value)
      instance_eval("#{ivarname} = value")
    end
  end
end


unless Kernel.respond_to?(:warn)
  module Kernel
    def warn(msg)
      STDERR.puts(msg + "\n") unless $VERBOSE.nil?
    end
  end
end
PK     Z\Ԫ[:      soap/marshal.rbnu [        # SOAP4R - Marshalling/Unmarshalling Ruby's object using SOAP Encoding.
# Copyright (C) 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require "soap/mapping"
require "soap/processor"


module SOAP


module Marshal
  # Trying xsd:dateTime data to be recovered as aTime.
  MarshalMappingRegistry = Mapping::Registry.new(
    :allow_original_mapping => true)
  MarshalMappingRegistry.add(
    Time,
    ::SOAP::SOAPDateTime,
    ::SOAP::Mapping::Registry::DateTimeFactory
  )

  class << self
  public
    def dump(obj, io = nil)
      marshal(obj, MarshalMappingRegistry, io)
    end

    def load(stream)
      unmarshal(stream, MarshalMappingRegistry)
    end

    def marshal(obj, mapping_registry = MarshalMappingRegistry, io = nil)
      elename = Mapping.name2elename(obj.class.to_s)
      soap_obj = Mapping.obj2soap(obj, mapping_registry)
      body = SOAPBody.new
      body.add(elename, soap_obj)
      env = SOAPEnvelope.new(nil, body)
      SOAP::Processor.marshal(env, {}, io)
    end

    def unmarshal(stream, mapping_registry = MarshalMappingRegistry)
      env = SOAP::Processor.unmarshal(stream)
      if env.nil?
	raise ArgumentError.new("Illegal SOAP marshal format.")
      end
      Mapping.soap2obj(env.body.root_node, mapping_registry)
    end
  end
end


end


SOAPMarshal = SOAP::Marshal
PK     Z\0c+F  F    soap/rpc/router.rbnu [        # SOAP4R - RPC Routing library
# Copyright (C) 2001, 2002, 2004, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/soap'
require 'soap/processor'
require 'soap/mapping'
require 'soap/mapping/wsdlliteralregistry'
require 'soap/rpc/rpc'
require 'soap/rpc/element'
require 'soap/streamHandler'
require 'soap/mimemessage'
require 'soap/header/handlerset'


module SOAP
module RPC


class Router
  include SOAP

  attr_reader :actor
  attr_accessor :mapping_registry
  attr_accessor :literal_mapping_registry
  attr_accessor :generate_explicit_type
  attr_accessor :external_ces

  def initialize(actor)
    @actor = actor
    @mapping_registry = nil
    @headerhandler = Header::HandlerSet.new
    @literal_mapping_registry = ::SOAP::Mapping::WSDLLiteralRegistry.new
    @generate_explicit_type = true
    @external_ces = nil
    @operation_by_soapaction = {}
    @operation_by_qname = {}
    @headerhandlerfactory = []
  end

  ###
  ## header handler interface
  #
  def add_request_headerhandler(factory)
    unless factory.respond_to?(:create)
      raise TypeError.new("factory must respond to 'create'")
    end
    @headerhandlerfactory << factory
  end

  def add_headerhandler(handler)
    @headerhandler.add(handler)
  end

  ###
  ## servant definition interface
  #
  def add_rpc_request_servant(factory, namespace)
    unless factory.respond_to?(:create)
      raise TypeError.new("factory must respond to 'create'")
    end
    obj = factory.create        # a dummy instance for introspection
    ::SOAP::RPC.defined_methods(obj).each do |name|
      begin
        qname = XSD::QName.new(namespace, name)
        param_def = ::SOAP::RPC::SOAPMethod.derive_rpc_param_def(obj, name)
        opt = create_styleuse_option(:rpc, :encoded)
        add_rpc_request_operation(factory, qname, nil, name, param_def, opt)
      rescue SOAP::RPC::MethodDefinitionError => e
        p e if $DEBUG
      end
    end
  end

  def add_rpc_servant(obj, namespace)
    ::SOAP::RPC.defined_methods(obj).each do |name|
      begin
        qname = XSD::QName.new(namespace, name)
        param_def = ::SOAP::RPC::SOAPMethod.derive_rpc_param_def(obj, name)
        opt = create_styleuse_option(:rpc, :encoded)
        add_rpc_operation(obj, qname, nil, name, param_def, opt)
      rescue SOAP::RPC::MethodDefinitionError => e
        p e if $DEBUG
      end
    end
  end
  alias add_servant add_rpc_servant

  ###
  ## operation definition interface
  #
  def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {})
    ensure_styleuse_option(opt, :rpc, :encoded)
    opt[:request_qname] = qname
    op = ApplicationScopeOperation.new(soapaction, receiver, name, param_def,
      opt)
    if opt[:request_style] != :rpc
      raise RPCRoutingError.new("illegal request_style given")
    end
    assign_operation(soapaction, qname, op)
  end
  alias add_method add_rpc_operation
  alias add_rpc_method add_rpc_operation

  def add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt = {})
    ensure_styleuse_option(opt, :rpc, :encoded)
    opt[:request_qname] = qname
    op = RequestScopeOperation.new(soapaction, factory, name, param_def, opt)
    if opt[:request_style] != :rpc
      raise RPCRoutingError.new("illegal request_style given")
    end
    assign_operation(soapaction, qname, op)
  end

  def add_document_operation(receiver, soapaction, name, param_def, opt = {})
    #
    # adopt workaround for doc/lit wrapper method
    # (you should consider to simply use rpc/lit service)
    #
    #unless soapaction
    #  raise RPCRoutingError.new("soapaction is a must for document method")
    #end
    ensure_styleuse_option(opt, :document, :literal)
    op = ApplicationScopeOperation.new(soapaction, receiver, name, param_def,
      opt)
    if opt[:request_style] != :document
      raise RPCRoutingError.new("illegal request_style given")
    end
    assign_operation(soapaction, first_input_part_qname(param_def), op)
  end
  alias add_document_method add_document_operation

  def add_document_request_operation(factory, soapaction, name, param_def, opt = {})
    #
    # adopt workaround for doc/lit wrapper method
    # (you should consider to simply use rpc/lit service)
    #
    #unless soapaction
    #  raise RPCRoutingError.new("soapaction is a must for document method")
    #end
    ensure_styleuse_option(opt, :document, :literal)
    op = RequestScopeOperation.new(soapaction, receiver, name, param_def, opt)
    if opt[:request_style] != :document
      raise RPCRoutingError.new("illegal request_style given")
    end
    assign_operation(soapaction, first_input_part_qname(param_def), op)
  end

  def route(conn_data)
    # we cannot set request_default_encodingsyle before parsing the content.
    env = unmarshal(conn_data)
    if env.nil?
      raise ArgumentError.new("illegal SOAP marshal format")
    end
    op = lookup_operation(conn_data.soapaction, env.body)
    headerhandler = @headerhandler.dup
    @headerhandlerfactory.each do |f|
      headerhandler.add(f.create)
    end
    receive_headers(headerhandler, env.header)
    soap_response = default_encodingstyle = nil
    begin
      soap_response =
        op.call(env.body, @mapping_registry, @literal_mapping_registry,
          create_mapping_opt)
      default_encodingstyle = op.response_default_encodingstyle
    rescue Exception
      soap_response = fault($!)
      default_encodingstyle = nil
    end
    conn_data.is_fault = true if soap_response.is_a?(SOAPFault)
    header = call_headers(headerhandler)
    body = SOAPBody.new(soap_response)
    env = SOAPEnvelope.new(header, body)
    marshal(conn_data, env, default_encodingstyle)
  end

  # Create fault response string.
  def create_fault_response(e)
    env = SOAPEnvelope.new(SOAPHeader.new, SOAPBody.new(fault(e)))
    opt = {}
    opt[:external_content] = nil
    response_string = Processor.marshal(env, opt)
    conn_data = StreamHandler::ConnectionData.new(response_string)
    conn_data.is_fault = true
    if ext = opt[:external_content]
      mimeize(conn_data, ext)
    end
    conn_data
  end

private

  def first_input_part_qname(param_def)
    param_def.each do |inout, paramname, typeinfo|
      if inout == SOAPMethod::IN
        klass, nsdef, namedef = typeinfo
        return XSD::QName.new(nsdef, namedef)
      end
    end
    nil
  end

  def create_styleuse_option(style, use)
    opt = {}
    opt[:request_style] = opt[:response_style] = style
    opt[:request_use] = opt[:response_use] = use
    opt
  end

  def ensure_styleuse_option(opt, style, use)
    opt[:request_style] ||= style
    opt[:response_style] ||= style
    opt[:request_use] ||= use
    opt[:response_use] ||= use
  end

  def assign_operation(soapaction, qname, op)
    assigned = false
    if soapaction and !soapaction.empty?
      @operation_by_soapaction[soapaction] = op
      assigned = true
    end
    if qname
      @operation_by_qname[qname] = op
      assigned = true
    end
    unless assigned
      raise RPCRoutingError.new("cannot assign operation")
    end
  end

  def lookup_operation(soapaction, body)
    if op = @operation_by_soapaction[soapaction]
      return op
    end
    qname = body.root_node.elename
    if op = @operation_by_qname[qname]
      return op
    end
    if soapaction
      raise RPCRoutingError.new(
        "operation: #{soapaction} #{qname} not supported")
    else
      raise RPCRoutingError.new("operation: #{qname} not supported")
    end
  end

  def call_headers(headerhandler)
    headers = headerhandler.on_outbound
    if headers.empty?
      nil
    else
      h = ::SOAP::SOAPHeader.new
      headers.each do |header|
        h.add(header.elename.name, header)
      end
      h
    end
  end

  def receive_headers(headerhandler, headers)
    headerhandler.on_inbound(headers) if headers
  end

  def unmarshal(conn_data)
    opt = {}
    contenttype = conn_data.receive_contenttype
    if /#{MIMEMessage::MultipartContentType}/i =~ contenttype
      opt[:external_content] = {}
      mime = MIMEMessage.parse("Content-Type: " + contenttype,
        conn_data.receive_string)
      mime.parts.each do |part|
	value = Attachment.new(part.content)
	value.contentid = part.contentid
	obj = SOAPAttachment.new(value)
	opt[:external_content][value.contentid] = obj if value.contentid
      end
      opt[:charset] =
	StreamHandler.parse_media_type(mime.root.headers['content-type'].str)
      env = Processor.unmarshal(mime.root.content, opt)
    else
      opt[:charset] = ::SOAP::StreamHandler.parse_media_type(contenttype)
      env = Processor.unmarshal(conn_data.receive_string, opt)
    end
    charset = opt[:charset]
    conn_data.send_contenttype = "text/xml; charset=\"#{charset}\""
    env
  end

  def marshal(conn_data, env, default_encodingstyle = nil)
    opt = {}
    opt[:external_content] = nil
    opt[:default_encodingstyle] = default_encodingstyle
    opt[:generate_explicit_type] = @generate_explicit_type
    response_string = Processor.marshal(env, opt)
    conn_data.send_string = response_string
    if ext = opt[:external_content]
      mimeize(conn_data, ext)
    end
    conn_data
  end

  def mimeize(conn_data, ext)
    mime = MIMEMessage.new
    ext.each do |k, v|
      mime.add_attachment(v.data)
    end
    mime.add_part(conn_data.send_string + "\r\n")
    mime.close
    conn_data.send_string = mime.content_str
    conn_data.send_contenttype = mime.headers['content-type'].str
    conn_data
  end

  # Create fault response.
  def fault(e)
    detail = Mapping::SOAPException.new(e)
    SOAPFault.new(
      SOAPString.new('Server'),
      SOAPString.new(e.to_s),
      SOAPString.new(@actor),
      Mapping.obj2soap(detail, @mapping_registry))
  end

  def create_mapping_opt
    { :external_ces => @external_ces }
  end

  class Operation
    attr_reader :name
    attr_reader :soapaction
    attr_reader :request_style
    attr_reader :response_style
    attr_reader :request_use
    attr_reader :response_use

    def initialize(soapaction, name, param_def, opt)
      @soapaction = soapaction
      @name = name
      @request_style = opt[:request_style]
      @response_style = opt[:response_style]
      @request_use = opt[:request_use]
      @response_use = opt[:response_use]
      check_style(@request_style)
      check_style(@response_style)
      check_use(@request_use)
      check_use(@response_use)
      if @response_style == :rpc
        request_qname = opt[:request_qname] or raise
        @rpc_method_factory =
          RPC::SOAPMethodRequest.new(request_qname, param_def, @soapaction)
        @rpc_response_qname = opt[:response_qname]
      else
        @doc_request_qnames = []
        @doc_request_qualified = []
        @doc_response_qnames = []
        @doc_response_qualified = []
        param_def.each do |inout, paramname, typeinfo, eleinfo|
          klass, nsdef, namedef = typeinfo
          qualified = eleinfo
          case inout
          when SOAPMethod::IN
            @doc_request_qnames << XSD::QName.new(nsdef, namedef)
            @doc_request_qualified << qualified
          when SOAPMethod::OUT
            @doc_response_qnames << XSD::QName.new(nsdef, namedef)
            @doc_response_qualified << qualified
          else
            raise ArgumentError.new(
              "illegal inout definition for document style: #{inout}")
          end
        end
      end
    end

    def request_default_encodingstyle
      (@request_use == :encoded) ? EncodingNamespace : LiteralNamespace
    end

    def response_default_encodingstyle
      (@response_use == :encoded) ? EncodingNamespace : LiteralNamespace
    end

    def call(body, mapping_registry, literal_mapping_registry, opt)
      if @request_style == :rpc
        values = request_rpc(body, mapping_registry, literal_mapping_registry,
          opt)
      else
        values = request_document(body, mapping_registry,
          literal_mapping_registry, opt)
      end
      result = receiver.method(@name.intern).call(*values)
      return result if result.is_a?(SOAPFault)
      if @response_style == :rpc
        response_rpc(result, mapping_registry, literal_mapping_registry, opt)
      else
        response_doc(result, mapping_registry, literal_mapping_registry, opt)
      end
    end

  private

    def receiver
      raise NotImplementedError.new('must be defined in derived class')
    end

    def request_rpc(body, mapping_registry, literal_mapping_registry, opt)
      request = body.request
      unless request.is_a?(SOAPStruct)
        raise RPCRoutingError.new("not an RPC style")
      end
      if @request_use == :encoded
        request_rpc_enc(request, mapping_registry, opt)
      else
        request_rpc_lit(request, literal_mapping_registry, opt)
      end
    end

    def request_document(body, mapping_registry, literal_mapping_registry, opt)
      # ToDo: compare names with @doc_request_qnames
      if @request_use == :encoded
        request_doc_enc(body, mapping_registry, opt)
      else
        request_doc_lit(body, literal_mapping_registry, opt)
      end
    end

    def request_rpc_enc(request, mapping_registry, opt)
      param = Mapping.soap2obj(request, mapping_registry, nil, opt)
      request.collect { |key, value|
        param[key]
      }
    end

    def request_rpc_lit(request, mapping_registry, opt)
      request.collect { |key, value|
        Mapping.soap2obj(value, mapping_registry, nil, opt)
      }
    end

    def request_doc_enc(body, mapping_registry, opt)
      body.collect { |key, value|
        Mapping.soap2obj(value, mapping_registry, nil, opt)
      }
    end

    def request_doc_lit(body, mapping_registry, opt)
      body.collect { |key, value|
        Mapping.soap2obj(value, mapping_registry, nil, opt)
      }
    end

    def response_rpc(result, mapping_registry, literal_mapping_registry, opt)
      if @response_use == :encoded
        response_rpc_enc(result, mapping_registry, opt)
      else
        response_rpc_lit(result, literal_mapping_registry, opt)
      end
    end
    
    def response_doc(result, mapping_registry, literal_mapping_registry, opt)
      if @doc_response_qnames.size == 1 and !result.is_a?(Array)
        result = [result]
      end
      if result.size != @doc_response_qnames.size
        raise "required #{@doc_response_qnames.size} responses " +
          "but #{result.size} given"
      end
      if @response_use == :encoded
        response_doc_enc(result, mapping_registry, opt)
      else
        response_doc_lit(result, literal_mapping_registry, opt)
      end
    end

    def response_rpc_enc(result, mapping_registry, opt)
      soap_response =
        @rpc_method_factory.create_method_response(@rpc_response_qname)
      if soap_response.have_outparam?
        unless result.is_a?(Array)
          raise RPCRoutingError.new("out parameter was not returned")
        end
        outparams = {}
        i = 1
        soap_response.output_params.each do |outparam|
          outparams[outparam] = Mapping.obj2soap(result[i], mapping_registry,
            nil, opt)
          i += 1
        end
        soap_response.set_outparam(outparams)
        soap_response.retval = Mapping.obj2soap(result[0], mapping_registry,
          nil, opt)
      else
        soap_response.retval = Mapping.obj2soap(result, mapping_registry, nil,
          opt)
      end
      soap_response
    end

    def response_rpc_lit(result, mapping_registry, opt)
      soap_response =
        @rpc_method_factory.create_method_response(@rpc_response_qname)
      if soap_response.have_outparam?
        unless result.is_a?(Array)
          raise RPCRoutingError.new("out parameter was not returned")
        end
        outparams = {}
        i = 1
        soap_response.output_params.each do |outparam|
          outparams[outparam] = Mapping.obj2soap(result[i], mapping_registry,
            XSD::QName.new(nil, outparam), opt)
          i += 1
        end
        soap_response.set_outparam(outparams)
        soap_response.retval = Mapping.obj2soap(result[0], mapping_registry,
          XSD::QName.new(nil, soap_response.elename), opt)
      else
        soap_response.retval = Mapping.obj2soap(result, mapping_registry,
          XSD::QName.new(nil, soap_response.elename), opt)
      end
      soap_response
    end

    def response_doc_enc(result, mapping_registry, opt)
      (0...result.size).collect { |idx|
        ele = Mapping.obj2soap(result[idx], mapping_registry, nil, opt)
        ele.elename = @doc_response_qnames[idx]
        ele
      }
    end

    def response_doc_lit(result, mapping_registry, opt)
      (0...result.size).collect { |idx|
        ele = Mapping.obj2soap(result[idx], mapping_registry,
          @doc_response_qnames[idx])
        ele.encodingstyle = LiteralNamespace
        if ele.respond_to?(:qualified)
          ele.qualified = @doc_response_qualified[idx]
        end
        ele
      }
    end

    def check_style(style)
      unless [:rpc, :document].include?(style)
        raise ArgumentError.new("unknown style: #{style}")
      end
    end

    def check_use(use)
      unless [:encoded, :literal].include?(use)
        raise ArgumentError.new("unknown use: #{use}")
      end
    end
  end

  class ApplicationScopeOperation < Operation
    def initialize(soapaction, receiver, name, param_def, opt)
      super(soapaction, name, param_def, opt)
      @receiver = receiver
    end

  private

    def receiver
      @receiver
    end
  end

  class RequestScopeOperation < Operation
    def initialize(soapaction, receiver_factory, name, param_def, opt)
      super(soapaction, name, param_def, opt)
      unless receiver_factory.respond_to?(:create)
        raise TypeError.new("factory must respond to 'create'")
      end
      @receiver_factory = receiver_factory
    end

  private

    def receiver
      @receiver_factory.create
    end
  end
end


end
end
PK     Z\l      soap/rpc/cgistub.rbnu [        # SOAP4R - CGI/mod_ruby stub library
# Copyright (C) 2001, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/streamHandler'
require 'webrick/httpresponse'
require 'webrick/httpstatus'
require 'logger'
require 'soap/rpc/soaplet'


module SOAP
module RPC


###
# SYNOPSIS
#   CGIStub.new
#
# DESCRIPTION
#   To be written...
#
class CGIStub < Logger::Application
  include SOAP
  include WEBrick

  class SOAPRequest
    attr_reader :body

    def [](var); end

    def meta_vars; end
  end

  class SOAPStdinRequest < SOAPRequest
    attr_reader :body

    def initialize(stream)
      size = ENV['CONTENT_LENGTH'].to_i || 0
      @body = stream.read(size)
    end

    def [](var)
      ENV[var.gsub(/-/, '_').upcase]
    end

    def meta_vars
      {
        'HTTP_SOAPACTION' => ENV['HTTP_SOAPAction']
      }
    end
  end

  class SOAPFCGIRequest < SOAPRequest
    attr_reader :body

    def initialize(request)
      @request = request
      @body = @request.in.read
    end

    def [](var)
      @request.env[var.gsub(/-/, '_').upcase]
    end

    def meta_vars
      {
        'HTTP_SOAPACTION' => @request.env['HTTP_SOAPAction']
      }
    end
  end

  def initialize(appname, default_namespace)
    super(appname)
    set_log(STDERR)
    self.level = ERROR
    @default_namespace = default_namespace
    @remote_host = ENV['REMOTE_HOST'] || ENV['REMOTE_ADDR'] || 'unknown'
    @router = ::SOAP::RPC::Router.new(self.class.name)
    @soaplet = ::SOAP::RPC::SOAPlet.new(@router)
    on_init
  end
  
  def on_init
    # do extra initialization in a derived class if needed.
  end

  def mapping_registry
    @router.mapping_registry
  end

  def mapping_registry=(value)
    @router.mapping_registry = value
  end

  def generate_explicit_type
    @router.generate_explicit_type
  end

  def generate_explicit_type=(generate_explicit_type)
    @router.generate_explicit_type = generate_explicit_type
  end

  # servant entry interface

  def add_rpc_servant(obj, namespace = @default_namespace)
    @router.add_rpc_servant(obj, namespace)
  end
  alias add_servant add_rpc_servant

  def add_headerhandler(obj)
    @router.add_headerhandler(obj)
  end
  alias add_rpc_headerhandler add_headerhandler

  # method entry interface

  def add_rpc_method(obj, name, *param)
    add_rpc_method_with_namespace_as(@default_namespace, obj, name, name, *param)
  end
  alias add_method add_rpc_method

  def add_rpc_method_as(obj, name, name_as, *param)
    add_rpc_method_with_namespace_as(@default_namespace, obj, name, name_as, *param)
  end
  alias add_method_as add_rpc_method_as

  def add_rpc_method_with_namespace(namespace, obj, name, *param)
    add_rpc_method_with_namespace_as(namespace, obj, name, name, *param)
  end
  alias add_method_with_namespace add_rpc_method_with_namespace

  def add_rpc_method_with_namespace_as(namespace, obj, name, name_as, *param)
    qname = XSD::QName.new(namespace, name_as)
    soapaction = nil
    param_def = SOAPMethod.derive_rpc_param_def(obj, name, *param)
    @router.add_rpc_operation(obj, qname, soapaction, name, param_def)
  end
  alias add_method_with_namespace_as add_rpc_method_with_namespace_as

  def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {})
    @router.add_rpc_operation(receiver, qname, soapaction, name, param_def, opt)
  end

  def add_document_operation(receiver, soapaction, name, param_def, opt = {})
    @router.add_document_operation(receiver, soapaction, name, param_def, opt)
  end

  def set_fcgi_request(request)
    @fcgi = request
  end

private

  HTTPVersion = WEBrick::HTTPVersion.new('1.0')       # dummy; ignored

  def run
    res = WEBrick::HTTPResponse.new({:HTTPVersion => HTTPVersion})
    begin
      @log.info { "received a request from '#{ @remote_host }'" }
      if @fcgi
        req = SOAPFCGIRequest.new(@fcgi)
      else
        req = SOAPStdinRequest.new($stdin)
      end
      @soaplet.do_POST(req, res)
    rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
      res.set_error(ex)
    rescue HTTPStatus::Error => ex
      res.set_error(ex)
    rescue HTTPStatus::Status => ex
      res.status = ex.code
    rescue StandardError, NameError => ex # for Ruby 1.6
      res.set_error(ex, true)
    ensure
      if defined?(MOD_RUBY)
        r = Apache.request
        r.status = res.status
        r.content_type = res.content_type
        r.send_http_header
        buf = res.body
      else
        buf = ''
        res.send_response(buf)
        buf.sub!(/^[^\r]+\r\n/, '')       # Trim status line.
      end
      @log.debug { "SOAP CGI Response:\n#{ buf }" }
      if @fcgi
        @fcgi.out.print buf
        @fcgi.finish
        @fcgi = nil
      else
        print buf
      end
    end
    0
  end
end


end
end
PK     Z\x      soap/rpc/httpserver.rbnu [        # SOAP4R - WEBrick HTTP Server
# Copyright (C) 2003, 2004 by NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'logger'
require 'soap/rpc/soaplet'
require 'soap/streamHandler'
require 'webrick'


module SOAP
module RPC


class HTTPServer < Logger::Application
  attr_reader :server
  attr_accessor :default_namespace

  def initialize(config)
    super(config[:SOAPHTTPServerApplicationName] || self.class.name)
    @default_namespace = config[:SOAPDefaultNamespace]
    @webrick_config = config.dup
    self.level = Logger::Severity::ERROR # keep silent by default
    @webrick_config[:Logger] ||= @log
    @log = @webrick_config[:Logger]     # sync logger of App and HTTPServer
    @router = ::SOAP::RPC::Router.new(self.class.name)
    @soaplet = ::SOAP::RPC::SOAPlet.new(@router)
    on_init
    @server = WEBrick::HTTPServer.new(@webrick_config)
    @server.mount('/', @soaplet)
  end

  def on_init
    # do extra initialization in a derived class if needed.
  end

  def status
    @server.status if @server
  end

  def shutdown
    @server.shutdown if @server
  end

  def mapping_registry
    @router.mapping_registry
  end

  def mapping_registry=(mapping_registry)
    @router.mapping_registry = mapping_registry
  end

  def generate_explicit_type
    @router.generate_explicit_type
  end

  def generate_explicit_type=(generate_explicit_type)
    @router.generate_explicit_type = generate_explicit_type
  end

  # servant entry interface

  def add_rpc_request_servant(factory, namespace = @default_namespace)
    @router.add_rpc_request_servant(factory, namespace)
  end

  def add_rpc_servant(obj, namespace = @default_namespace)
    @router.add_rpc_servant(obj, namespace)
  end
  
  def add_request_headerhandler(factory)
    @router.add_request_headerhandler(factory)
  end

  def add_headerhandler(obj)
    @router.add_headerhandler(obj)
  end
  alias add_rpc_headerhandler add_headerhandler

  # method entry interface

  def add_rpc_method(obj, name, *param)
    add_rpc_method_as(obj, name, name, *param)
  end
  alias add_method add_rpc_method

  def add_rpc_method_as(obj, name, name_as, *param)
    qname = XSD::QName.new(@default_namespace, name_as)
    soapaction = nil
    param_def = SOAPMethod.derive_rpc_param_def(obj, name, *param)
    @router.add_rpc_operation(obj, qname, soapaction, name, param_def)
  end
  alias add_method_as add_rpc_method_as

  def add_document_method(obj, soapaction, name, req_qnames, res_qnames)
    param_def = SOAPMethod.create_doc_param_def(req_qnames, res_qnames)
    @router.add_document_operation(obj, soapaction, name, param_def)
  end

  def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {})
    @router.add_rpc_operation(receiver, qname, soapaction, name, param_def, opt)
  end

  def add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt = {})
    @router.add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt)
  end

  def add_document_operation(receiver, soapaction, name, param_def, opt = {})
    @router.add_document_operation(receiver, soapaction, name, param_def, opt)
  end

  def add_document_request_operation(factory, soapaction, name, param_def, opt = {})
    @router.add_document_request_operation(factory, soapaction, name, param_def, opt)
  end

private

  def run
    @server.start
  end
end


end
end
PK     Z\R&  &    soap/rpc/rpc.rbnu [        # SOAP4R - RPC utility.
# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


module SOAP


module RPC
  ServerException = Mapping::MappedException

  def self.defined_methods(obj)
    if obj.is_a?(Module)
      obj.methods - Module.methods
    else
      obj.methods - Object.instance_methods(true)
    end
  end
end


end
PK     Z\W*:  :    soap/rpc/proxy.rbnu [        # SOAP4R - RPC Proxy library.
# Copyright (C) 2000, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/soap'
require 'soap/processor'
require 'soap/mapping'
require 'soap/rpc/rpc'
require 'soap/rpc/element'
require 'soap/streamHandler'
require 'soap/mimemessage'


module SOAP
module RPC


class Proxy
  include SOAP

public

  attr_accessor :soapaction
  attr_accessor :mandatorycharset
  attr_accessor :allow_unqualified_element
  attr_accessor :default_encodingstyle
  attr_accessor :generate_explicit_type
  attr_reader :headerhandler
  attr_reader :streamhandler

  attr_accessor :mapping_registry
  attr_accessor :literal_mapping_registry

  attr_reader :operation

  def initialize(endpoint_url, soapaction, options)
    @endpoint_url = endpoint_url
    @soapaction = soapaction
    @options = options
    @streamhandler = HTTPStreamHandler.new(
      @options["protocol.http"] ||= ::SOAP::Property.new)
    @operation = {}
    @mandatorycharset = nil
    @allow_unqualified_element = true
    @default_encodingstyle = nil
    @generate_explicit_type = true
    @headerhandler = Header::HandlerSet.new
    @mapping_registry = nil
    @literal_mapping_registry = ::SOAP::Mapping::WSDLLiteralRegistry.new
  end

  def inspect
    "#<#{self.class}:#{@endpoint_url}>"
  end

  def endpoint_url
    @endpoint_url
  end

  def endpoint_url=(endpoint_url)
    @endpoint_url = endpoint_url
    reset_stream
  end

  def reset_stream
    @streamhandler.reset(@endpoint_url)
  end

  def set_wiredump_file_base(wiredump_file_base)
    @streamhandler.wiredump_file_base = wiredump_file_base
  end

  def test_loopback_response
    @streamhandler.test_loopback_response
  end

  def add_rpc_operation(qname, soapaction, name, param_def, opt = {})
    opt[:request_qname] = qname
    opt[:request_style] ||= :rpc
    opt[:response_style] ||= :rpc
    opt[:request_use] ||= :encoded
    opt[:response_use] ||= :encoded
    @operation[name] = Operation.new(soapaction, param_def, opt)
  end

  def add_document_operation(soapaction, name, param_def, opt = {})
    opt[:request_style] ||= :document
    opt[:response_style] ||= :document
    opt[:request_use] ||= :literal
    opt[:response_use] ||= :literal
    # default values of these values are unqualified in XML Schema.
    # set true for backward compatibility.
    unless opt.key?(:elementformdefault)
      opt[:elementformdefault] = true
    end
    unless opt.key?(:attributeformdefault)
      opt[:attributeformdefault] = true
    end
    @operation[name] = Operation.new(soapaction, param_def, opt)
  end

  # add_method is for shortcut of typical rpc/encoded method definition.
  alias add_method add_rpc_operation
  alias add_rpc_method add_rpc_operation
  alias add_document_method add_document_operation

  def invoke(req_header, req_body, opt = nil)
    opt ||= create_encoding_opt
    route(req_header, req_body, opt, opt)
  end

  def call(name, *params)
    unless op_info = @operation[name]
      raise MethodDefinitionError, "method: #{name} not defined"
    end
    mapping_opt = create_mapping_opt
    req_header = create_request_header
    req_body = SOAPBody.new(
      op_info.request_body(params, @mapping_registry,
        @literal_mapping_registry, mapping_opt)
    )
    reqopt = create_encoding_opt(
      :soapaction => op_info.soapaction || @soapaction,
      :envelopenamespace => @options["soap.envelope.requestnamespace"],
      :default_encodingstyle =>
        @default_encodingstyle || op_info.request_default_encodingstyle,
      :elementformdefault => op_info.elementformdefault,
      :attributeformdefault => op_info.attributeformdefault
    )
    resopt = create_encoding_opt(
      :envelopenamespace => @options["soap.envelope.responsenamespace"],
      :default_encodingstyle =>
        @default_encodingstyle || op_info.response_default_encodingstyle,
      :elementformdefault => op_info.elementformdefault,
      :attributeformdefault => op_info.attributeformdefault
    )
    env = route(req_header, req_body, reqopt, resopt)
    raise EmptyResponseError unless env
    receive_headers(env.header)
    begin
      check_fault(env.body)
    rescue ::SOAP::FaultError => e
      op_info.raise_fault(e, @mapping_registry, @literal_mapping_registry)
    end
    op_info.response_obj(env.body, @mapping_registry,
      @literal_mapping_registry, mapping_opt)
  end

  def route(req_header, req_body, reqopt, resopt)
    req_env = ::SOAP::SOAPEnvelope.new(req_header, req_body)
    unless reqopt[:envelopenamespace].nil?
      set_envelopenamespace(req_env, reqopt[:envelopenamespace])
    end
    reqopt[:external_content] = nil
    conn_data = marshal(req_env, reqopt)
    if ext = reqopt[:external_content]
      mime = MIMEMessage.new
      ext.each do |k, v|
      	mime.add_attachment(v.data)
      end
      mime.add_part(conn_data.send_string + "\r\n")
      mime.close
      conn_data.send_string = mime.content_str
      conn_data.send_contenttype = mime.headers['content-type'].str
    end
    conn_data = @streamhandler.send(@endpoint_url, conn_data,
      reqopt[:soapaction])
    if conn_data.receive_string.empty?
      return nil
    end
    unmarshal(conn_data, resopt)
  end

  def check_fault(body)
    if body.fault
      raise SOAP::FaultError.new(body.fault)
    end
  end

private

  def set_envelopenamespace(env, namespace)
    env.elename = XSD::QName.new(namespace, env.elename.name)
    if env.header
      env.header.elename = XSD::QName.new(namespace, env.header.elename.name)
    end
    if env.body
      env.body.elename = XSD::QName.new(namespace, env.body.elename.name)
    end
  end

  def create_request_header
    headers = @headerhandler.on_outbound
    if headers.empty?
      nil
    else
      h = ::SOAP::SOAPHeader.new
      headers.each do |header|
        h.add(header.elename.name, header)
      end
      h
    end
  end

  def receive_headers(headers)
    @headerhandler.on_inbound(headers) if headers
  end

  def marshal(env, opt)
    send_string = Processor.marshal(env, opt)
    StreamHandler::ConnectionData.new(send_string)
  end

  def unmarshal(conn_data, opt)
    contenttype = conn_data.receive_contenttype
    if /#{MIMEMessage::MultipartContentType}/i =~ contenttype
      opt[:external_content] = {}
      mime = MIMEMessage.parse("Content-Type: " + contenttype,
	conn_data.receive_string)
      mime.parts.each do |part|
	value = Attachment.new(part.content)
	value.contentid = part.contentid
	obj = SOAPAttachment.new(value)
	opt[:external_content][value.contentid] = obj if value.contentid
      end
      opt[:charset] = @mandatorycharset ||
	StreamHandler.parse_media_type(mime.root.headers['content-type'].str)
      env = Processor.unmarshal(mime.root.content, opt)
    else
      opt[:charset] = @mandatorycharset ||
	::SOAP::StreamHandler.parse_media_type(contenttype)
      env = Processor.unmarshal(conn_data.receive_string, opt)
    end
    unless env.is_a?(::SOAP::SOAPEnvelope)
      raise ResponseFormatError.new(
        "response is not a SOAP envelope: #{conn_data.receive_string}")
    end
    env
  end

  def create_header(headers)
    header = SOAPHeader.new()
    headers.each do |content, mustunderstand, encodingstyle|
      header.add(SOAPHeaderItem.new(content, mustunderstand, encodingstyle))
    end
    header
  end

  def create_encoding_opt(hash = nil)
    opt = {}
    opt[:default_encodingstyle] = @default_encodingstyle
    opt[:allow_unqualified_element] = @allow_unqualified_element
    opt[:generate_explicit_type] = @generate_explicit_type
    opt[:no_indent] = @options["soap.envelope.no_indent"]
    opt[:use_numeric_character_reference] =
      @options["soap.envelope.use_numeric_character_reference"]
    opt.update(hash) if hash
    opt
  end

  def create_mapping_opt(hash = nil)
    opt = {
      :external_ces => @options["soap.mapping.external_ces"]
    }
    opt.update(hash) if hash
    opt
  end

  class Operation
    attr_reader :soapaction
    attr_reader :request_style
    attr_reader :response_style
    attr_reader :request_use
    attr_reader :response_use
    attr_reader :elementformdefault
    attr_reader :attributeformdefault

    def initialize(soapaction, param_def, opt)
      @soapaction = soapaction
      @request_style = opt[:request_style]
      @response_style = opt[:response_style]
      @request_use = opt[:request_use]
      @response_use = opt[:response_use]
      # set nil(unqualified) by default
      @elementformdefault = opt[:elementformdefault]
      @attributeformdefault = opt[:attributeformdefault]
      check_style(@request_style)
      check_style(@response_style)
      check_use(@request_use)
      check_use(@response_use)
      if @request_style == :rpc
        @rpc_request_qname = opt[:request_qname]
        if @rpc_request_qname.nil?
          raise MethodDefinitionError.new("rpc_request_qname must be given")
        end
        @rpc_method_factory =
          RPC::SOAPMethodRequest.new(@rpc_request_qname, param_def, @soapaction)
      else
        @doc_request_qnames = []
        @doc_request_qualified = []
        @doc_response_qnames = []
        @doc_response_qualified = []
        param_def.each do |inout, paramname, typeinfo, eleinfo|
          klass_not_used, nsdef, namedef = typeinfo
          qualified = eleinfo
          if namedef.nil?
            raise MethodDefinitionError.new("qname must be given")
          end
          case inout
          when SOAPMethod::IN
            @doc_request_qnames << XSD::QName.new(nsdef, namedef)
            @doc_request_qualified << qualified
          when SOAPMethod::OUT
            @doc_response_qnames << XSD::QName.new(nsdef, namedef)
            @doc_response_qualified << qualified
          else
            raise MethodDefinitionError.new(
              "illegal inout definition for document style: #{inout}")
          end
        end
      end
    end

    def request_default_encodingstyle
      (@request_use == :encoded) ? EncodingNamespace : LiteralNamespace
    end

    def response_default_encodingstyle
      (@response_use == :encoded) ? EncodingNamespace : LiteralNamespace
    end

    def request_body(values, mapping_registry, literal_mapping_registry, opt)
      if @request_style == :rpc
        request_rpc(values, mapping_registry, literal_mapping_registry, opt)
      else
        request_doc(values, mapping_registry, literal_mapping_registry, opt)
      end
    end

    def response_obj(body, mapping_registry, literal_mapping_registry, opt)
      if @response_style == :rpc
        response_rpc(body, mapping_registry, literal_mapping_registry, opt)
      else
        response_doc(body, mapping_registry, literal_mapping_registry, opt)
      end
    end

    def raise_fault(e, mapping_registry, literal_mapping_registry)
      if @response_style == :rpc
        Mapping.fault2exception(e, mapping_registry)
      else
        Mapping.fault2exception(e, literal_mapping_registry)
      end
    end

  private

    def check_style(style)
      unless [:rpc, :document].include?(style)
        raise MethodDefinitionError.new("unknown style: #{style}")
      end
    end

    def check_use(use)
      unless [:encoded, :literal].include?(use)
        raise MethodDefinitionError.new("unknown use: #{use}")
      end
    end

    def request_rpc(values, mapping_registry, literal_mapping_registry, opt)
      if @request_use == :encoded
        request_rpc_enc(values, mapping_registry, opt)
      else
        request_rpc_lit(values, literal_mapping_registry, opt)
      end
    end

    def request_doc(values, mapping_registry, literal_mapping_registry, opt)
      if @request_use == :encoded
        request_doc_enc(values, mapping_registry, opt)
      else
        request_doc_lit(values, literal_mapping_registry, opt)
      end
    end

    def request_rpc_enc(values, mapping_registry, opt)
      method = @rpc_method_factory.dup
      names = method.input_params
      obj = create_request_obj(names, values)
      soap = Mapping.obj2soap(obj, mapping_registry, @rpc_request_qname, opt)
      method.set_param(soap)
      method
    end

    def request_rpc_lit(values, mapping_registry, opt)
      method = @rpc_method_factory.dup
      params = {}
      idx = 0
      method.input_params.each do |name|
        params[name] = Mapping.obj2soap(values[idx], mapping_registry, 
          XSD::QName.new(nil, name), opt)
        idx += 1
      end
      method.set_param(params)
      method
    end

    def request_doc_enc(values, mapping_registry, opt)
      (0...values.size).collect { |idx|
        ele = Mapping.obj2soap(values[idx], mapping_registry, nil, opt)
        ele.elename = @doc_request_qnames[idx]
        ele
      }
    end

    def request_doc_lit(values, mapping_registry, opt)
      (0...values.size).collect { |idx|
        ele = Mapping.obj2soap(values[idx], mapping_registry,
          @doc_request_qnames[idx], opt)
        ele.encodingstyle = LiteralNamespace
        if ele.respond_to?(:qualified)
          ele.qualified = @doc_request_qualified[idx]
        end
        ele
      }
    end

    def response_rpc(body, mapping_registry, literal_mapping_registry, opt)
      if @response_use == :encoded
        response_rpc_enc(body, mapping_registry, opt)
      else
        response_rpc_lit(body, literal_mapping_registry, opt)
      end
    end

    def response_doc(body, mapping_registry, literal_mapping_registry, opt)
      if @response_use == :encoded
        return *response_doc_enc(body, mapping_registry, opt)
      else
        return *response_doc_lit(body, literal_mapping_registry, opt)
      end
    end

    def response_rpc_enc(body, mapping_registry, opt)
      ret = nil
      if body.response
        ret = Mapping.soap2obj(body.response, mapping_registry,
          @rpc_method_factory.retval_class_name, opt)
      end
      if body.outparams
        outparams = body.outparams.collect { |outparam|
          Mapping.soap2obj(outparam, mapping_registry, nil, opt)
        }
        [ret].concat(outparams)
      else
        ret
      end
    end

    def response_rpc_lit(body, mapping_registry, opt)
      body.root_node.collect { |key, value|
        Mapping.soap2obj(value, mapping_registry,
          @rpc_method_factory.retval_class_name, opt)
      }
    end

    def response_doc_enc(body, mapping_registry, opt)
      body.collect { |key, value|
        Mapping.soap2obj(value, mapping_registry, nil, opt)
      }
    end

    def response_doc_lit(body, mapping_registry, opt)
      body.collect { |key, value|
        Mapping.soap2obj(value, mapping_registry)
      }
    end

    def create_request_obj(names, params)
      o = Object.new
      idx = 0
      while idx < params.length
        o.instance_variable_set('@' + names[idx], params[idx])
        idx += 1
      end
      o
    end
  end
end


end
end
PK     Z\ p      soap/rpc/soaplet.rbnu [        # SOAP4R - SOAP handler servlet for WEBrick
# Copyright (C) 2001-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'webrick/httpservlet/abstract'
require 'webrick/httpstatus'
require 'soap/rpc/router'
require 'soap/streamHandler'
begin
  require 'stringio'
  require 'zlib'
rescue LoadError
  warn("Loading stringio or zlib failed.  No gzipped response supported.") if $DEBUG
end


warn("Overriding WEBrick::Log#debug") if $DEBUG
require 'webrick/log'
module WEBrick
  class Log < BasicLog
    alias __debug debug
    def debug(msg = nil)
      if block_given? and msg.nil?
        __debug(yield)
      else
        __debug(msg)
      end
    end
  end
end


module SOAP
module RPC


class SOAPlet < WEBrick::HTTPServlet::AbstractServlet
public
  attr_reader :options

  def initialize(router = nil)
    @router = router || ::SOAP::RPC::Router.new(self.class.name)
    @options = {}
    @config = {}
  end

  # for backward compatibility
  def app_scope_router
    @router
  end

  # for backward compatibility
  def add_servant(obj, namespace)
    @router.add_rpc_servant(obj, namespace)
  end

  def allow_content_encoding_gzip=(allow)
    @options[:allow_content_encoding_gzip] = allow
  end

  ###
  ## Servlet interfaces for WEBrick.
  #
  def get_instance(config, *options)
    @config = config
    self
  end

  def require_path_info?
    false
  end

  def do_GET(req, res)
    res.header['Allow'] = 'POST'
    raise WEBrick::HTTPStatus::MethodNotAllowed, "GET request not allowed"
  end

  def do_POST(req, res)
    logger.debug { "SOAP request: " + req.body } if logger
    begin
      conn_data = ::SOAP::StreamHandler::ConnectionData.new
      setup_req(conn_data, req)
      @router.external_ces = @options[:external_ces]
      conn_data = @router.route(conn_data)
      setup_res(conn_data, req, res)
    rescue Exception => e
      conn_data = @router.create_fault_response(e)
      res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR
      res.body = conn_data.send_string
      res['content-type'] = conn_data.send_contenttype || "text/xml"
    end
    if res.body.is_a?(IO)
      res.chunked = true
      logger.debug { "SOAP response: (chunked response not logged)" } if logger
    else
      logger.debug { "SOAP response: " + res.body } if logger
    end
  end

private

  def logger
    @config[:Logger]
  end

  def setup_req(conn_data, req)
    conn_data.receive_string = req.body
    conn_data.receive_contenttype = req['content-type']
    conn_data.soapaction = parse_soapaction(req.meta_vars['HTTP_SOAPACTION'])
  end

  def setup_res(conn_data, req, res)
    res['content-type'] = conn_data.send_contenttype
    if conn_data.is_fault
      res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR
    end
    if outstring = encode_gzip(req, conn_data.send_string)
      res['content-encoding'] = 'gzip'
      res['content-length'] = outstring.size
      res.body = outstring
    else
      res.body = conn_data.send_string
    end
  end

  def parse_soapaction(soapaction)
    if !soapaction.nil? and !soapaction.empty?
      if /^"(.+)"$/ =~ soapaction
        return $1
      end
    end
    nil
  end

  def encode_gzip(req, outstring)
    unless encode_gzip?(req)
      return nil
    end
    begin
      ostream = StringIO.new
      gz = Zlib::GzipWriter.new(ostream)
      gz.write(outstring)
      ostream.string
    ensure
      gz.close
    end
  end

  def encode_gzip?(req)
    @options[:allow_content_encoding_gzip] and defined?(::Zlib) and
      req['accept-encoding'] and
      req['accept-encoding'].split(/,\s*/).include?('gzip')
  end
end


end
end
PK     Z\$      soap/rpc/standaloneServer.rbnu [        # SOAP4R - WEBrick Server
# Copyright (C) 2003 by NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/rpc/httpserver'


module SOAP
module RPC


class StandaloneServer < HTTPServer
  def initialize(appname, default_namespace, host = "0.0.0.0", port = 8080)
    @appname = appname
    @default_namespace = default_namespace
    @host = host
    @port = port
    super(create_config)
  end

  alias add_servant add_rpc_servant
  alias add_headerhandler add_rpc_headerhandler

private

  def create_config
    {
      :BindAddress => @host,
      :Port => @port,
      :AccessLog => [],
      :SOAPDefaultNamespace => @default_namespace,
      :SOAPHTTPServerApplicationName => @appname,
    }
  end
end


end
end
PK     Z\mT׋      soap/rpc/element.rbnu [        # SOAP4R - RPC element definition.
# Copyright (C) 2000, 2001, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/baseData'


module SOAP

# Add method definitions for RPC to common definition in element.rb
class SOAPBody < SOAPStruct
  public

  def request
    root_node
  end

  def response
    root = root_node
    if !@is_fault
      if root.nil?
        nil
      elsif root.is_a?(SOAPBasetype)
        root
      else
        # Initial element is [retval].
        root[0]
      end
    else
      root
    end
  end

  def outparams
    root = root_node
    if !@is_fault and !root.nil? and !root.is_a?(SOAPBasetype)
      op = root[1..-1]
      op = nil if op && op.empty?
      op
    else
      nil
    end
  end

  def fault
    if @is_fault
      self['fault']
    else
      nil
    end
  end

  def fault=(fault)
    @is_fault = true
    add_member('fault', fault)
  end
end


module RPC


class RPCError < Error; end
class MethodDefinitionError < RPCError; end
class ParameterError < RPCError; end

class SOAPMethod < SOAPStruct
  RETVAL = 'retval'
  IN = 'in'
  OUT = 'out'
  INOUT = 'inout'

  attr_reader :param_def
  attr_reader :inparam
  attr_reader :outparam
  attr_reader :retval_name
  attr_reader :retval_class_name

  def initialize(qname, param_def = nil)
    super(nil)
    @elename = qname
    @encodingstyle = nil

    @param_def = param_def

    @signature = []
    @inparam_names = []
    @inoutparam_names = []
    @outparam_names = []

    @inparam = {}
    @outparam = {}
    @retval_name = nil
    @retval_class_name = nil

    init_param(@param_def) if @param_def
  end

  def have_outparam?
    @outparam_names.size > 0
  end

  def input_params
    collect_params(IN, INOUT)
  end

  def output_params
    collect_params(OUT, INOUT)
  end

  def set_param(params)
    params.each do |param, data|
      @inparam[param] = data
      data.elename.name = param
      data.parent = self
    end
  end

  def set_outparam(params)
    params.each do |param, data|
      @outparam[param] = data
      data.elename.name = param
    end
  end

  def SOAPMethod.param_count(param_def, *type)
    count = 0
    param_def.each do |io_type, name, param_type|
      if type.include?(io_type)
        count += 1
      end
    end
    count
  end

  def SOAPMethod.derive_rpc_param_def(obj, name, *param)
    if param.size == 1 and param[0].is_a?(Array)
      return param[0]
    end
    if param.empty?
      method = obj.method(name)
      param_names = (1..method.arity.abs).collect { |i| "p#{i}" }
    else
      param_names = param
    end
    create_rpc_param_def(param_names)
  end

  def SOAPMethod.create_rpc_param_def(param_names)
    param_def = []
    param_names.each do |param_name|
      param_def.push([IN, param_name, nil])
    end
    param_def.push([RETVAL, 'return', nil])
    param_def
  end

  def SOAPMethod.create_doc_param_def(req_qnames, res_qnames)
    req_qnames = [req_qnames] if req_qnames.is_a?(XSD::QName)
    res_qnames = [res_qnames] if res_qnames.is_a?(XSD::QName)
    param_def = []
    req_qnames.each do |qname|
      param_def << [IN, qname.name, [nil, qname.namespace, qname.name]]
    end
    res_qnames.each do |qname|
      param_def << [OUT, qname.name, [nil, qname.namespace, qname.name]]
    end
    param_def
  end

private

  def collect_params(*type)
    names = []
    @signature.each do |io_type, name, param_type|
      names << name if type.include?(io_type)
    end
    names
  end

  def init_param(param_def)
    param_def.each do |io_type, name, param_type|
      case io_type
      when IN
        @signature.push([IN, name, param_type])
        @inparam_names.push(name)
      when OUT
        @signature.push([OUT, name, param_type])
        @outparam_names.push(name)
      when INOUT
        @signature.push([INOUT, name, param_type])
        @inoutparam_names.push(name)
      when RETVAL
        if @retval_name
          raise MethodDefinitionError.new('duplicated retval')
        end
        @retval_name = name
        @retval_class_name = nil
        if param_type
          if param_type[0].is_a?(String)
            @retval_class_name = Mapping.class_from_name(param_type[0])
          else
            @retval_class_name = param_type[0]
          end
        end
      else
        raise MethodDefinitionError.new("unknown type: #{io_type}")
      end
    end
  end
end


class SOAPMethodRequest < SOAPMethod
  attr_accessor :soapaction

  def SOAPMethodRequest.create_request(qname, *params)
    param_def = []
    param_value = []
    i = 0
    params.each do |param|
      param_name = "p#{i}"
      i += 1
      param_def << [IN, param_name, nil]
      param_value << [param_name, param]
    end
    param_def << [RETVAL, 'return', nil]
    o = new(qname, param_def)
    o.set_param(param_value)
    o
  end

  def initialize(qname, param_def = nil, soapaction = nil)
    check_elename(qname)
    super(qname, param_def)
    @soapaction = soapaction
  end

  def each
    input_params.each do |name|
      unless @inparam[name]
        raise ParameterError.new("parameter: #{name} was not given")
      end
      yield(name, @inparam[name])
    end
  end

  def dup
    req = self.class.new(@elename.dup, @param_def, @soapaction)
    req.encodingstyle = @encodingstyle
    req
  end

  def create_method_response(response_name = nil)
    response_name ||=
      XSD::QName.new(@elename.namespace, @elename.name + 'Response')
    SOAPMethodResponse.new(response_name, @param_def)
  end

private

  def check_elename(qname)
    # NCName & ruby's method name
    unless /\A[\w_][\w\d_\-]*\z/ =~ qname.name
      raise MethodDefinitionError.new("element name '#{qname.name}' not allowed")
    end
  end
end


class SOAPMethodResponse < SOAPMethod

  def initialize(qname, param_def = nil)
    super(qname, param_def)
    @retval = nil
  end

  def retval=(retval)
    @retval = retval
    @retval.elename = @retval.elename.dup_name(@retval_name || 'return')
    retval.parent = self
    retval
  end

  def each
    if @retval_name and !@retval.is_a?(SOAPVoid)
      yield(@retval_name, @retval)
    end

    output_params.each do |name|
      unless @outparam[name]
        raise ParameterError.new("parameter: #{name} was not given")
      end
      yield(name, @outparam[name])
    end
  end
end


# To return(?) void explicitly.
#  def foo(input_var)
#    ...
#    return SOAP::RPC::SOAPVoid.new
#  end
class SOAPVoid < XSD::XSDAnySimpleType
  include SOAPBasetype
  extend SOAPModuleUtils
  Name = XSD::QName.new(Mapping::RubyCustomTypeNamespace, nil)

public
  def initialize()
    @elename = Name
    @id = nil
    @precedents = []
    @parent = nil
  end
end


end
end
PK     Z\|@K  K    soap/rpc/driver.rbnu [        # SOAP4R - SOAP RPC driver
# Copyright (C) 2000, 2001, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/soap'
require 'soap/mapping'
require 'soap/mapping/wsdlliteralregistry'
require 'soap/rpc/rpc'
require 'soap/rpc/proxy'
require 'soap/rpc/element'
require 'soap/streamHandler'
require 'soap/property'
require 'soap/header/handlerset'


module SOAP
module RPC


class Driver
  class << self
    if RUBY_VERSION >= "1.7.0"
      def __attr_proxy(symbol, assignable = false)
        name = symbol.to_s
        define_method(name) {
          @proxy.__send__(name)
        }
        if assignable
          aname = name + '='
          define_method(aname) { |rhs|
            @proxy.__send__(aname, rhs)
          }
        end
      end
    else
      def __attr_proxy(symbol, assignable = false)
        name = symbol.to_s
        module_eval <<-EOS
          def #{name}
            @proxy.#{name}
          end
        EOS
        if assignable
          module_eval <<-EOS
            def #{name}=(value)
              @proxy.#{name} = value
            end
          EOS
        end
      end
    end
  end

  __attr_proxy :endpoint_url, true
  __attr_proxy :mapping_registry, true
  __attr_proxy :default_encodingstyle, true
  __attr_proxy :generate_explicit_type, true
  __attr_proxy :allow_unqualified_element, true
  __attr_proxy :headerhandler
  __attr_proxy :streamhandler
  __attr_proxy :test_loopback_response
  __attr_proxy :reset_stream

  attr_reader :proxy
  attr_reader :options
  attr_accessor :soapaction

  def inspect
    "#<#{self.class}:#{@proxy.inspect}>"
  end

  def httpproxy
    options["protocol.http.proxy"]
  end

  def httpproxy=(httpproxy)
    options["protocol.http.proxy"] = httpproxy
  end

  def wiredump_dev
    options["protocol.http.wiredump_dev"]
  end

  def wiredump_dev=(wiredump_dev)
    options["protocol.http.wiredump_dev"] = wiredump_dev
  end

  def mandatorycharset
    options["protocol.mandatorycharset"]
  end

  def mandatorycharset=(mandatorycharset)
    options["protocol.mandatorycharset"] = mandatorycharset
  end

  def wiredump_file_base
    options["protocol.wiredump_file_base"]
  end

  def wiredump_file_base=(wiredump_file_base)
    options["protocol.wiredump_file_base"] = wiredump_file_base
  end

  def initialize(endpoint_url, namespace = nil, soapaction = nil)
    @namespace = namespace
    @soapaction = soapaction
    @options = setup_options
    @wiredump_file_base = nil
    @proxy = Proxy.new(endpoint_url, @soapaction, @options)
  end

  def loadproperty(propertyname)
    unless options.loadproperty(propertyname)
      raise LoadError.new("No such property to load -- #{propertyname}")
    end
  end

  def add_rpc_method(name, *params)
    add_rpc_method_with_soapaction_as(name, name, @soapaction, *params)
  end

  def add_rpc_method_as(name, name_as, *params)
    add_rpc_method_with_soapaction_as(name, name_as, @soapaction, *params)
  end

  def add_rpc_method_with_soapaction(name, soapaction, *params)
    add_rpc_method_with_soapaction_as(name, name, soapaction, *params)
  end

  def add_rpc_method_with_soapaction_as(name, name_as, soapaction, *params)
    param_def = SOAPMethod.create_rpc_param_def(params)
    qname = XSD::QName.new(@namespace, name_as)
    @proxy.add_rpc_method(qname, soapaction, name, param_def)
    add_rpc_method_interface(name, param_def)
  end

  # add_method is for shortcut of typical rpc/encoded method definition.
  alias add_method add_rpc_method
  alias add_method_as add_rpc_method_as
  alias add_method_with_soapaction add_rpc_method_with_soapaction
  alias add_method_with_soapaction_as add_rpc_method_with_soapaction_as

  def add_document_method(name, soapaction, req_qname, res_qname)
    param_def = SOAPMethod.create_doc_param_def(req_qname, res_qname)
    @proxy.add_document_method(soapaction, name, param_def)
    add_document_method_interface(name, param_def)
  end

  def add_rpc_operation(qname, soapaction, name, param_def, opt = {})
    @proxy.add_rpc_operation(qname, soapaction, name, param_def, opt)
    add_rpc_method_interface(name, param_def)
  end

  def add_document_operation(soapaction, name, param_def, opt = {})
    @proxy.add_document_operation(soapaction, name, param_def, opt)
    add_document_method_interface(name, param_def)
  end

  def invoke(headers, body)
    if headers and !headers.is_a?(SOAPHeader)
      headers = create_header(headers)
    end
    set_wiredump_file_base(body.elename.name)
    env = @proxy.invoke(headers, body)
    if env.nil?
      return nil, nil
    else
      return env.header, env.body
    end
  end

  def call(name, *params)
    set_wiredump_file_base(name)
    @proxy.call(name, *params)
  end

private

  def set_wiredump_file_base(name)
    if @wiredump_file_base
      @proxy.set_wiredump_file_base("#{@wiredump_file_base}_#{name}")
    end
  end

  def create_header(headers)
    header = SOAPHeader.new()
    headers.each do |content, mustunderstand, encodingstyle|
      header.add(SOAPHeaderItem.new(content, mustunderstand, encodingstyle))
    end
    header
  end

  def setup_options
    if opt = Property.loadproperty(::SOAP::PropertyName)
      opt = opt["client"]
    end
    opt ||= Property.new
    opt.add_hook("protocol.mandatorycharset") do |key, value|
      @proxy.mandatorycharset = value
    end
    opt.add_hook("protocol.wiredump_file_base") do |key, value|
      @wiredump_file_base = value
    end
    opt["protocol.http.charset"] ||= XSD::Charset.xml_encoding_label
    opt["protocol.http.proxy"] ||= Env::HTTP_PROXY
    opt["protocol.http.no_proxy"] ||= Env::NO_PROXY
    opt
  end

  def add_rpc_method_interface(name, param_def)
    param_count = RPC::SOAPMethod.param_count(param_def,
      RPC::SOAPMethod::IN, RPC::SOAPMethod::INOUT)
    add_method_interface(name, param_count)
  end

  def add_document_method_interface(name, param_def)
    param_count = RPC::SOAPMethod.param_count(param_def, RPC::SOAPMethod::IN)
    add_method_interface(name, param_count)
  end

  if RUBY_VERSION > "1.7.0"
    def add_method_interface(name, param_count)
      ::SOAP::Mapping.define_singleton_method(self, name) do |*arg|
        unless arg.size == param_count
          raise ArgumentError.new(
          "wrong number of arguments (#{arg.size} for #{param_count})")
        end
        call(name, *arg)
      end
      self.method(name)
    end
  else
    def add_method_interface(name, param_count)
      instance_eval <<-EOS
        def #{name}(*arg)
          unless arg.size == #{param_count}
            raise ArgumentError.new(
              "wrong number of arguments (\#{arg.size} for #{param_count})")
          end
          call(#{name.dump}, *arg)
        end
      EOS
      self.method(name)
    end
  end
end


end
end
PK     Z\ҍɜ    &  soap/encodingstyle/aspDotNetHandler.rbnu [        # SOAP4R - ASP.NET EncodingStyle handler library
# Copyright (C) 2001, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/encodingstyle/handler'


module SOAP
module EncodingStyle


class ASPDotNetHandler < Handler
  Namespace = 'http://tempuri.org/ASP.NET'
  add_handler

  def initialize(charset = nil)
    super(charset)
    @textbuf = ''
    @decode_typemap = nil
  end


  ###
  ## encode interface.
  #
  def encode_data(generator, ns, data, parent)
    attrs = {}
    # ASPDotNetHandler is intended to be used for accessing an ASP.NET doc/lit
    # service as an rpc/encoded service.  in the situation, local elements
    # should be qualified.  propagate parent's namespace to children.
    if data.elename.namespace.nil?
      data.elename.namespace = parent.elename.namespace
    end
    name = generator.encode_name(ns, data, attrs)
    case data
    when SOAPRawString
      generator.encode_tag(name, attrs)
      generator.encode_rawstring(data.to_s)
    when XSD::XSDString
      generator.encode_tag(name, attrs)
      generator.encode_string(@charset ?
        XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)
    when XSD::XSDAnySimpleType
      generator.encode_tag(name, attrs)
      generator.encode_string(data.to_s)
    when SOAPStruct
      generator.encode_tag(name, attrs)
      data.each do |key, value|
        generator.encode_child(ns, value, data)
      end
    when SOAPArray
      generator.encode_tag(name, attrs)
      data.traverse do |child, *rank|
	data.position = nil
        generator.encode_child(ns, child, data)
      end
    else
      raise EncodingStyleError.new(
        "unknown object:#{data} in this encodingStyle")
    end
  end

  def encode_data_end(generator, ns, data, parent)
    name = generator.encode_name_end(ns, data)
    cr = data.is_a?(SOAPCompoundtype)
    generator.encode_tag_end(name, cr)
  end


  ###
  ## decode interface.
  #
  class SOAPTemporalObject
    attr_accessor :parent

    def initialize
      @parent = nil
    end
  end

  class SOAPUnknown < SOAPTemporalObject
    def initialize(handler, elename)
      super()
      @handler = handler
      @elename = elename
    end

    def as_struct
      o = SOAPStruct.decode(@elename, XSD::AnyTypeName)
      o.parent = @parent
      o.type.name = @name
      @handler.decode_parent(@parent, o)
      o
    end

    def as_string
      o = SOAPString.decode(@elename)
      o.parent = @parent
      @handler.decode_parent(@parent, o)
      o
    end

    def as_nil
      o = SOAPNil.decode(@elename)
      o.parent = @parent
      @handler.decode_parent(@parent, o)
      o
    end
  end

  def decode_tag(ns, elename, attrs, parent)
    @textbuf = ''
    o = SOAPUnknown.new(self, elename)
    o.parent = parent
    o
  end

  def decode_tag_end(ns, node)
    o = node.node
    if o.is_a?(SOAPUnknown)
      newnode = o.as_string
#	if /\A\s*\z/ =~ @textbuf
#	  o.as_struct
#	else
#	  o.as_string
#	end
      node.replace_node(newnode)
      o = node.node
    end

    decode_textbuf(o)
    @textbuf = ''
  end

  def decode_text(ns, text)
    # @textbuf is set at decode_tag_end.
    @textbuf << text
  end

  def decode_prologue
  end

  def decode_epilogue
  end

  def decode_parent(parent, node)
    case parent.node
    when SOAPUnknown
      newparent = parent.node.as_struct
      node.parent = newparent
      parent.replace_node(newparent)
      decode_parent(parent, node)

    when SOAPStruct
      data = parent.node[node.elename.name]
      case data
      when nil
	parent.node.add(node.elename.name, node)
      when SOAPArray
	name, type_ns = node.elename.name, node.type.namespace
	data.add(node)
	node.elename, node.type.namespace = name, type_ns
      else
	parent.node[node.elename.name] = SOAPArray.new
	name, type_ns = data.elename.name, data.type.namespace
	parent.node[node.elename.name].add(data)
	data.elename.name, data.type.namespace = name, type_ns
	name, type_ns = node.elename.name, node.type.namespace
	parent.node[node.elename.name].add(node)
	node.elename.name, node.type.namespace = name, type_ns
      end

    when SOAPArray
      if node.position
	parent.node[*(decode_arypos(node.position))] = node
	parent.node.sparse = true
      else
	parent.node.add(node)
      end

    when SOAPBasetype
      raise EncodingStyleError.new("SOAP base type must not have a child")

    else
      # SOAPUnknown does not have parent.
      # raise EncodingStyleError.new("illegal parent: #{parent}")
    end
  end

private

  def decode_textbuf(node)
    if node.is_a?(XSD::XSDString)
      if @charset
	node.set(XSD::Charset.encoding_from_xml(@textbuf, @charset))
      else
	node.set(@textbuf)
      end
    else
      # Nothing to do...
    end
  end
end

ASPDotNetHandler.new


end
end
PK     Z\s3  3  $  soap/encodingstyle/literalHandler.rbnu [        # SOAP4R - XML Literal EncodingStyle handler library
# Copyright (C) 2001, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/encodingstyle/handler'


module SOAP
module EncodingStyle


class LiteralHandler < Handler
  Namespace = SOAP::LiteralNamespace
  add_handler

  def initialize(charset = nil)
    super(charset)
    @textbuf = ''
  end


  ###
  ## encode interface.
  #
  def encode_data(generator, ns, data, parent)
    attrs = {}
    name = generator.encode_name(ns, data, attrs)
    data.extraattr.each do |k, v|
      # ToDo: check generator.attributeformdefault here
      if k.is_a?(XSD::QName)
        if k.namespace
          SOAPGenerator.assign_ns(attrs, ns, k.namespace)
          k = ns.name(k)
        else
          k = k.name
        end
      end
      attrs[k] = v
    end
    case data
    when SOAPRawString
      generator.encode_tag(name, attrs)
      generator.encode_rawstring(data.to_s)
    when XSD::XSDString
      generator.encode_tag(name, attrs)
      str = data.to_s
      str = XSD::Charset.encoding_to_xml(str, @charset) if @charset
      generator.encode_string(str)
    when XSD::XSDAnySimpleType
      generator.encode_tag(name, attrs)
      generator.encode_string(data.to_s)
    when SOAPStruct
      generator.encode_tag(name, attrs)
      data.each do |key, value|
        generator.encode_child(ns, value, data)
      end
    when SOAPArray
      generator.encode_tag(name, attrs)
      data.traverse do |child, *rank|
	data.position = nil
        generator.encode_child(ns, child, data)
      end
    when SOAPElement
      # passes 2 times for simplifying namespace definition
      data.each do |key, value|
        if value.elename.namespace
          SOAPGenerator.assign_ns(attrs, ns, value.elename.namespace)
        end
      end
      generator.encode_tag(name, attrs)
      generator.encode_rawstring(data.text) if data.text
      data.each do |key, value|
        generator.encode_child(ns, value, data)
      end
    else
      raise EncodingStyleError.new(
        "unknown object:#{data} in this encodingStyle")
    end
  end

  def encode_data_end(generator, ns, data, parent)
    name = generator.encode_name_end(ns, data)
    cr = (data.is_a?(SOAPCompoundtype) or
      (data.is_a?(SOAPElement) and !data.text))
    generator.encode_tag_end(name, cr)
  end


  ###
  ## decode interface.
  #
  class SOAPTemporalObject
    attr_accessor :parent

    def initialize
      @parent = nil
    end
  end

  class SOAPUnknown < SOAPTemporalObject
    def initialize(handler, elename, extraattr)
      super()
      @handler = handler
      @elename = elename
      @extraattr = extraattr
    end

    def as_element
      o = SOAPElement.decode(@elename)
      o.parent = @parent
      o.extraattr.update(@extraattr)
      @handler.decode_parent(@parent, o)
      o
    end

    def as_string
      o = SOAPString.decode(@elename)
      o.parent = @parent
      o.extraattr.update(@extraattr)
      @handler.decode_parent(@parent, o)
      o
    end

    def as_nil
      o = SOAPNil.decode(@elename)
      o.parent = @parent
      o.extraattr.update(@extraattr)
      @handler.decode_parent(@parent, o)
      o
    end
  end

  def decode_tag(ns, elename, attrs, parent)
    @textbuf = ''
    o = SOAPUnknown.new(self, elename, decode_attrs(ns, attrs))
    o.parent = parent
    o
  end

  def decode_tag_end(ns, node)
    o = node.node
    if o.is_a?(SOAPUnknown)
      newnode = if /\A\s*\z/ =~ @textbuf
	  o.as_element
	else
	  o.as_string
	end
      node.replace_node(newnode)
      o = node.node
    end

    decode_textbuf(o)
    @textbuf = ''
  end

  def decode_text(ns, text)
    # @textbuf is set at decode_tag_end.
    @textbuf << text
  end

  def decode_attrs(ns, attrs)
    extraattr = {}
    attrs.each do |key, value|
      qname = ns.parse_local(key)
      extraattr[qname] = value
    end
    extraattr
  end

  def decode_prologue
  end

  def decode_epilogue
  end

  def decode_parent(parent, node)
    return unless parent.node
    case parent.node
    when SOAPUnknown
      newparent = parent.node.as_element
      node.parent = newparent
      parent.replace_node(newparent)
      decode_parent(parent, node)
    when SOAPElement
      parent.node.add(node)
      node.parent = parent.node
    when SOAPStruct
      parent.node.add(node.elename.name, node)
      node.parent = parent.node
    when SOAPArray
      if node.position
	parent.node[*(decode_arypos(node.position))] = node
	parent.node.sparse = true
      else
	parent.node.add(node)
      end
      node.parent = parent.node
    else
      raise EncodingStyleError.new("illegal parent: #{parent.node}")
    end
  end

private

  def decode_textbuf(node)
    if node.is_a?(XSD::XSDString)
      if @charset
	node.set(XSD::Charset.encoding_from_xml(@textbuf, @charset))
      else
	node.set(@textbuf)
      end
    else
      # Nothing to do...
    end
  end
end

LiteralHandler.new


end
end
PK     Z\dS9  S9  !  soap/encodingstyle/soapHandler.rbnu [        # SOAP4R - SOAP EncodingStyle handler library
# Copyright (C) 2001, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/encodingstyle/handler'


module SOAP
module EncodingStyle


class SOAPHandler < Handler
  Namespace = SOAP::EncodingNamespace
  add_handler

  def initialize(charset = nil)
    super(charset)
    @refpool = []
    @idpool = []
    @textbuf = ''
    @is_first_top_ele = true
  end


  ###
  ## encode interface.
  #
  def encode_data(generator, ns, data, parent)
    attrs = encode_attrs(generator, ns, data, parent)
    if parent && parent.is_a?(SOAPArray) && parent.position
      attrs[ns.name(AttrPositionName)] = "[#{parent.position.join(',')}]"
    end
    name = generator.encode_name(ns, data, attrs)
    case data
    when SOAPReference
      attrs['href'] = data.refidstr
      generator.encode_tag(name, attrs)
    when SOAPExternalReference
      data.referred
      attrs['href'] = data.refidstr
      generator.encode_tag(name, attrs)
    when SOAPRawString
      generator.encode_tag(name, attrs)
      generator.encode_rawstring(data.to_s)
    when XSD::XSDString
      generator.encode_tag(name, attrs)
      generator.encode_string(@charset ?
	XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)
    when XSD::XSDAnySimpleType
      generator.encode_tag(name, attrs)
      generator.encode_string(data.to_s)
    when SOAPStruct
      generator.encode_tag(name, attrs)
      data.each do |key, value|
        generator.encode_child(ns, value, data)
      end
    when SOAPArray
      generator.encode_tag(name, attrs)
      data.traverse do |child, *rank|
	data.position = data.sparse ? rank : nil
        generator.encode_child(ns, child, data)
      end
    else
      raise EncodingStyleError.new(
	"unknown object:#{data} in this encodingStyle")
    end
  end

  def encode_data_end(generator, ns, data, parent)
    name = generator.encode_name_end(ns, data)
    cr = data.is_a?(SOAPCompoundtype)
    generator.encode_tag_end(name, cr)
  end


  ###
  ## decode interface.
  #
  class SOAPTemporalObject
    attr_accessor :parent
    attr_accessor :position
    attr_accessor :id
    attr_accessor :root

    def initialize
      @parent = nil
      @position = nil
      @id = nil
      @root = nil
    end
  end

  class SOAPUnknown < SOAPTemporalObject
    attr_reader :type
    attr_accessor :definedtype
    attr_reader :extraattr

    def initialize(handler, elename, type, extraattr)
      super()
      @handler = handler
      @elename = elename
      @type = type
      @extraattr = extraattr
      @definedtype = nil
    end

    def as_struct
      o = SOAPStruct.decode(@elename, @type)
      o.id = @id
      o.root = @root
      o.parent = @parent
      o.position = @position
      o.extraattr.update(@extraattr)
      @handler.decode_parent(@parent, o)
      o
    end

    def as_string
      o = SOAPString.decode(@elename)
      o.id = @id
      o.root = @root
      o.parent = @parent
      o.position = @position
      o.extraattr.update(@extraattr)
      @handler.decode_parent(@parent, o)
      o
    end

    def as_nil
      o = SOAPNil.decode(@elename)
      o.id = @id
      o.root = @root
      o.parent = @parent
      o.position = @position
      o.extraattr.update(@extraattr)
      @handler.decode_parent(@parent, o)
      o
    end
  end

  def decode_tag(ns, elename, attrs, parent)
    @textbuf = ''
    is_nil, type, arytype, root, offset, position, href, id, extraattr =
      decode_attrs(ns, attrs)
    o = nil
    if is_nil
      o = SOAPNil.decode(elename)
    elsif href
      o = SOAPReference.decode(elename, href)
      @refpool << o
    elsif @decode_typemap
      o = decode_tag_by_wsdl(ns, elename, type, parent.node, arytype, extraattr)
    else
      o = decode_tag_by_type(ns, elename, type, parent.node, arytype, extraattr)
    end

    if o.is_a?(SOAPArray)
      if offset
	o.offset = decode_arypos(offset)
	o.sparse = true
      else
	o.sparse = false
      end
    end

    o.parent = parent
    o.id = id
    o.root = root
    o.position = position

    unless o.is_a?(SOAPTemporalObject)
      @idpool << o if o.id
      decode_parent(parent, o)
    end
    o
  end

  def decode_tag_end(ns, node)
    o = node.node
    if o.is_a?(SOAPUnknown)
      newnode = if /\A\s*\z/ =~ @textbuf
	o.as_struct
      else
	o.as_string
      end
      if newnode.id
	@idpool << newnode
      end
      node.replace_node(newnode)
      o = node.node
    end
    decode_textbuf(o)
    # unlink definedtype
    o.definedtype = nil
  end

  def decode_text(ns, text)
    @textbuf << text
  end

  def decode_prologue
    @refpool.clear
    @idpool.clear
    @is_first_top_ele = true
  end

  def decode_epilogue
    decode_resolve_id
  end

  def decode_parent(parent, node)
    return unless parent.node
    case parent.node
    when SOAPUnknown
      newparent = parent.node.as_struct
      node.parent = newparent
      if newparent.id
	@idpool << newparent
      end
      parent.replace_node(newparent)
      decode_parent(parent, node)
    when SOAPStruct
      parent.node.add(node.elename.name, node)
      node.parent = parent.node
    when SOAPArray
      if node.position
	parent.node[*(decode_arypos(node.position))] = node
	parent.node.sparse = true
      else
	parent.node.add(node)
      end
      node.parent = parent.node
    else
      raise EncodingStyleError.new("illegal parent: #{parent.node}")
    end
  end

private

  def content_ranksize(typename)
    typename.scan(/\[[\d,]*\]$/)[0]
  end

  def content_typename(typename)
    typename.sub(/\[,*\]$/, '')
  end

  def create_arytype(ns, data)
    XSD::QName.new(data.arytype.namespace,
      content_typename(data.arytype.name) + "[#{data.size.join(',')}]")
  end

  def encode_attrs(generator, ns, data, parent)
    attrs = {}
    return attrs if data.is_a?(SOAPReference)

    if !parent || parent.encodingstyle != EncodingNamespace
      if @generate_explicit_type
        SOAPGenerator.assign_ns(attrs, ns, EnvelopeNamespace)
        attrs[ns.name(AttrEncodingStyleName)] = EncodingNamespace
      end
      data.encodingstyle = EncodingNamespace
    end

    if data.is_a?(SOAPNil)
      attrs[ns.name(XSD::AttrNilName)] = XSD::NilValue
    elsif @generate_explicit_type
      if data.type.namespace
        SOAPGenerator.assign_ns(attrs, ns, data.type.namespace)
      end
      if data.is_a?(SOAPArray)
	if data.arytype.namespace
          SOAPGenerator.assign_ns(attrs, ns, data.arytype.namespace)
   	end
	SOAPGenerator.assign_ns(attrs, ns, EncodingNamespace)
	attrs[ns.name(AttrArrayTypeName)] = ns.name(create_arytype(ns, data))
	if data.type.name
	  attrs[ns.name(XSD::AttrTypeName)] = ns.name(data.type)
	end
      elsif parent && parent.is_a?(SOAPArray) && (parent.arytype == data.type)
	# No need to add.
      elsif !data.type.namespace
	# No need to add.
      else
	attrs[ns.name(XSD::AttrTypeName)] = ns.name(data.type)
      end
    end

    data.extraattr.each do |key, value|
      SOAPGenerator.assign_ns(attrs, ns, key.namespace)
      attrs[ns.name(key)] = encode_attr_value(generator, ns, key, value)
    end
    if data.id
      attrs['id'] = data.id
    end
    attrs
  end

  def encode_attr_value(generator, ns, qname, value)
    if value.is_a?(SOAPType)
      ref = SOAPReference.new(value)
      generator.add_reftarget(qname.name, value)
      ref.refidstr
    else
      value.to_s
    end
  end

  def decode_tag_by_wsdl(ns, elename, typestr, parent, arytypestr, extraattr)
    o = nil
    if parent.class == SOAPBody
      # root element: should branch by root attribute?
      if @is_first_top_ele
	# Unqualified name is allowed here.
	@is_first_top_ele = false
	type = @decode_typemap[elename] ||
	  @decode_typemap.find_name(elename.name)
	if type
	  o = SOAPStruct.new(elename)
	  o.definedtype = type
	  return o
	end
      end
      # multi-ref element.
      if typestr
	typename = ns.parse(typestr)
	typedef = @decode_typemap[typename]
	if typedef
          return decode_definedtype(elename, typename, typedef, arytypestr)
	end
      end
      return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,
	extraattr)
    end

    if parent.type == XSD::AnyTypeName
      return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,
	extraattr)
    end

    # parent.definedtype == nil means the parent is SOAPUnknown.  SOAPUnknown
    # is generated by decode_tag_by_type when its type is anyType.
    parenttype = parent.definedtype || @decode_typemap[parent.type]
    unless parenttype
      return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,
	extraattr)
    end

    definedtype_name = parenttype.child_type(elename)
    if definedtype_name and (klass = TypeMap[definedtype_name])
      return decode_basetype(klass, elename)
    elsif definedtype_name == XSD::AnyTypeName
      return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,
	extraattr)
    end

    if definedtype_name
      typedef = @decode_typemap[definedtype_name]
    else
      typedef = parenttype.child_defined_complextype(elename)
    end
    decode_definedtype(elename, definedtype_name, typedef, arytypestr)
  end

  def decode_definedtype(elename, typename, typedef, arytypestr)
    unless typedef
      raise EncodingStyleError.new("unknown type '#{typename}'")
    end
    if typedef.is_a?(::WSDL::XMLSchema::SimpleType)
      decode_defined_simpletype(elename, typename, typedef, arytypestr)
    else
      decode_defined_complextype(elename, typename, typedef, arytypestr)
    end
  end

  def decode_basetype(klass, elename)
    klass.decode(elename)
  end

  def decode_defined_simpletype(elename, typename, typedef, arytypestr)
    o = decode_basetype(TypeMap[typedef.base], elename)
    o.definedtype = typedef
    o
  end

  def decode_defined_complextype(elename, typename, typedef, arytypestr)
    case typedef.compoundtype
    when :TYPE_STRUCT, :TYPE_MAP
      o = SOAPStruct.decode(elename, typename)
      o.definedtype = typedef
      return o
    when :TYPE_ARRAY
      expected_arytype = typedef.find_arytype
      if arytypestr
	actual_arytype = XSD::QName.new(expected_arytype.namespace,
	  content_typename(expected_arytype.name) <<
	  content_ranksize(arytypestr))
	o = SOAPArray.decode(elename, typename, actual_arytype)
      else
	o = SOAPArray.new(typename, 1, expected_arytype)
	o.elename = elename
      end
      o.definedtype = typedef
      return o
    when :TYPE_EMPTY
      o = SOAPNil.decode(elename)
      o.definedtype = typedef
      return o
    else
      raise RuntimeError.new(
        "Unknown kind of complexType: #{typedef.compoundtype}")
    end
    nil
  end

  def decode_tag_by_type(ns, elename, typestr, parent, arytypestr, extraattr)
    if arytypestr
      type = typestr ? ns.parse(typestr) : ValueArrayName
      node = SOAPArray.decode(elename, type, ns.parse(arytypestr))
      node.extraattr.update(extraattr)
      return node
    end

    type = nil
    if typestr
      type = ns.parse(typestr)
    elsif parent.is_a?(SOAPArray)
      type = parent.arytype
    else
      # Since it's in dynamic(without any type) encoding process,
      # assumes entity as its type itself.
      #   <SOAP-ENC:Array ...> => type Array in SOAP-ENC.
      #   <Country xmlns="foo"> => type Country in foo.
      type = elename
    end

    if (klass = TypeMap[type])
      node = decode_basetype(klass, elename)
      node.extraattr.update(extraattr)
      return node
    end

    # Unknown type... Struct or String
    SOAPUnknown.new(self, elename, type, extraattr)
  end

  def decode_textbuf(node)
    case node
    when XSD::XSDHexBinary, XSD::XSDBase64Binary
      node.set_encoded(@textbuf)
    when XSD::XSDString
      if @charset
	@textbuf = XSD::Charset.encoding_from_xml(@textbuf, @charset)
      end
      if node.definedtype
        node.definedtype.check_lexical_format(@textbuf)
      end
      node.set(@textbuf)
    when SOAPNil
      # Nothing to do.
    when SOAPBasetype
      node.set(@textbuf)
    else
      # Nothing to do...
    end
    @textbuf = ''
  end

  NilLiteralMap = {
    'true' => true,
    '1' => true,
    'false' => false,
    '0' => false
  }
  RootLiteralMap = {
    '1' => 1,
    '0' => 0
  }
  def decode_attrs(ns, attrs)
    is_nil = false
    type = nil
    arytype = nil
    root = nil
    offset = nil
    position = nil
    href = nil
    id = nil
    extraattr = {}

    attrs.each do |key, value|
      qname = ns.parse(key)
      case qname.namespace
      when XSD::InstanceNamespace
        case qname.name
        when XSD::NilLiteral
          is_nil = NilLiteralMap[value] or
            raise EncodingStyleError.new("cannot accept attribute value: #{value} as the value of xsi:#{XSD::NilLiteral} (expected 'true', 'false', '1', or '0')")
          next
        when XSD::AttrType
          type = value
          next
        end
      when EncodingNamespace
        case qname.name
        when AttrArrayType
          arytype = value
          next
        when AttrRoot
          root = RootLiteralMap[value] or
            raise EncodingStyleError.new(
	      "illegal root attribute value: #{value}")
          next
        when AttrOffset
          offset = value
          next
        when AttrPosition
          position = value
          next
        end
      end
      if key == 'href'
        href = value
        next
      elsif key == 'id'
        id = value
        next
      end
      qname = ns.parse_local(key)
      extraattr[qname] = decode_attr_value(ns, qname, value)
    end

    return is_nil, type, arytype, root, offset, position, href, id, extraattr
  end

  def decode_attr_value(ns, qname, value)
    if /\A#/ =~ value
      o = SOAPReference.decode(nil, value)
      @refpool << o
      o
    else
      value
    end
  end

  def decode_arypos(position)
    /^\[(.+)\]$/ =~ position
    $1.split(',').collect { |s| s.to_i }
  end

  def decode_resolve_id
    count = @refpool.length	# To avoid infinite loop
    while !@refpool.empty? && count > 0
      @refpool = @refpool.find_all { |ref|
	o = @idpool.find { |item|
	  item.id == ref.refid
	}
	if o.is_a?(SOAPReference)
	  true	# link of link.
	elsif o
	  ref.__setobj__(o)
	  false
	elsif o = ref.rootnode.external_content[ref.refid]
	  ref.__setobj__(o)
      	  false
	else
	  raise EncodingStyleError.new("unresolved reference: #{ref.refid}")
	end
      }
      count -= 1
    end
  end
end

SOAPHandler.new


end
end
PK     Z\b,X?  ?    soap/encodingstyle/handler.rbnu [        # SOAP4R - EncodingStyle handler library
# Copyright (C) 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/soap'
require 'soap/baseData'
require 'soap/element'


module SOAP
module EncodingStyle


class Handler
  @@handlers = {}

  class EncodingStyleError < Error; end

  class << self
    def uri
      self::Namespace
    end

    def handler(uri)
      @@handlers[uri]
    end

    def each
      @@handlers.each do |key, value|
	yield(value)
      end
    end

  private

    def add_handler
      @@handlers[self.uri] = self
    end
  end

  attr_reader :charset
  attr_accessor :generate_explicit_type
  def decode_typemap=(definedtypes)
    @decode_typemap = definedtypes
  end

  def initialize(charset)
    @charset = charset
    @generate_explicit_type = true
    @decode_typemap = nil
  end

  ###
  ## encode interface.
  #
  # Returns a XML instance as a string.
  def encode_data(generator, ns, data, parent)
    raise NotImplementError
  end

  def encode_data_end(generator, ns, data, parent)
    raise NotImplementError
  end

  def encode_prologue
  end

  def encode_epilogue
  end

  ###
  ## decode interface.
  #
  # Returns SOAP/OM data.
  def decode_tag(ns, name, attrs, parent)
    raise NotImplementError.new('Method decode_tag must be defined in derived class.')
  end

  def decode_tag_end(ns, name)
    raise NotImplementError.new('Method decode_tag_end must be defined in derived class.')
  end

  def decode_text(ns, text)
    raise NotImplementError.new('Method decode_text must be defined in derived class.')
  end

  def decode_prologue
  end

  def decode_epilogue
  end
end


end
end
PK     Z\C`pp  p    soap/streamHandler.rbnu [        # SOAP4R - Stream handler.
# Copyright (C) 2000, 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/soap'
require 'soap/httpconfigloader'
begin
  require 'stringio'
  require 'zlib'
rescue LoadError
  warn("Loading stringio or zlib failed.  No gzipped response support.") if $DEBUG
end


module SOAP


class StreamHandler
  RUBY_VERSION_STRING = "ruby #{ RUBY_VERSION } (#{ RUBY_RELEASE_DATE }) [#{ RUBY_PLATFORM }]"

  class ConnectionData
    attr_accessor :send_string
    attr_accessor :send_contenttype
    attr_accessor :receive_string
    attr_accessor :receive_contenttype
    attr_accessor :is_fault
    attr_accessor :soapaction

    def initialize(send_string = nil)
      @send_string = send_string
      @send_contenttype = nil
      @receive_string = nil
      @receive_contenttype = nil
      @is_fault = false
      @soapaction = nil
    end
  end

  def self.parse_media_type(str)
    if /^#{ MediaType }(?:\s*;\s*charset=([^"]+|"[^"]+"))?$/i !~ str
      return nil
    end
    charset = $1
    charset.gsub!(/"/, '') if charset
    charset || 'us-ascii'
  end

  def self.create_media_type(charset)
    "#{ MediaType }; charset=#{ charset }"
  end
end


class HTTPStreamHandler < StreamHandler
  include SOAP

  begin
    require 'http-access2'
    if HTTPAccess2::VERSION < "2.0"
      raise LoadError.new("http-access/2.0 or later is required.")
    end
    Client = HTTPAccess2::Client
    RETRYABLE = true
  rescue LoadError
    warn("Loading http-access2 failed.  Net/http is used.") if $DEBUG
    require 'soap/netHttpClient'
    Client = SOAP::NetHttpClient
    RETRYABLE = false
  end


public
  
  attr_reader :client
  attr_accessor :wiredump_file_base
  
  MAX_RETRY_COUNT = 10       	# [times]

  def initialize(options)
    super()
    @client = Client.new(nil, "SOAP4R/#{ Version }")
    @wiredump_file_base = nil
    @charset = @wiredump_dev = nil
    @options = options
    set_options
    @client.debug_dev = @wiredump_dev
    @cookie_store = nil
    @accept_encoding_gzip = false
  end

  def test_loopback_response
    @client.test_loopback_response
  end

  def accept_encoding_gzip=(allow)
    @accept_encoding_gzip = allow
  end

  def inspect
    "#<#{self.class}>"
  end

  def send(endpoint_url, conn_data, soapaction = nil, charset = @charset)
    conn_data.soapaction ||= soapaction # for backward conpatibility
    send_post(endpoint_url, conn_data, charset)
  end

  def reset(endpoint_url = nil)
    if endpoint_url.nil?
      @client.reset_all
    else
      @client.reset(endpoint_url)
    end
    @client.save_cookie_store if @cookie_store
  end

private

  def set_options
    HTTPConfigLoader.set_options(@client, @options)
    @charset = @options["charset"] || XSD::Charset.xml_encoding_label
    @options.add_hook("charset") do |key, value|
      @charset = value
    end
    @wiredump_dev = @options["wiredump_dev"]
    @options.add_hook("wiredump_dev") do |key, value|
      @wiredump_dev = value
      @client.debug_dev = @wiredump_dev
    end
    set_cookie_store_file(@options["cookie_store_file"])
    @options.add_hook("cookie_store_file") do |key, value|
      set_cookie_store_file(value)
    end
    ssl_config = @options["ssl_config"]
    basic_auth = @options["basic_auth"]
    @options.lock(true)
    ssl_config.unlock
    basic_auth.unlock
  end

  def set_cookie_store_file(value)
    value = nil if value and value.empty?
    @cookie_store = value
    @client.set_cookie_store(@cookie_store) if @cookie_store
  end

  def send_post(endpoint_url, conn_data, charset)
    conn_data.send_contenttype ||= StreamHandler.create_media_type(charset)

    if @wiredump_file_base
      filename = @wiredump_file_base + '_request.xml'
      f = File.open(filename, "w")
      f << conn_data.send_string
      f.close
    end

    extra = {}
    extra['Content-Type'] = conn_data.send_contenttype
    extra['SOAPAction'] = "\"#{ conn_data.soapaction }\""
    extra['Accept-Encoding'] = 'gzip' if send_accept_encoding_gzip?
    send_string = conn_data.send_string
    @wiredump_dev << "Wire dump:\n\n" if @wiredump_dev
    begin
      retry_count = 0
      while true
        res = @client.post(endpoint_url, send_string, extra)
        if RETRYABLE and HTTP::Status.redirect?(res.status)
          retry_count += 1
          if retry_count >= MAX_RETRY_COUNT
            raise HTTPStreamError.new("redirect count exceeded")
          end
          endpoint_url = res.header["location"][0]
          puts "redirected to #{endpoint_url}" if $DEBUG
        else
          break
        end
      end
    rescue
      @client.reset(endpoint_url)
      raise
    end
    @wiredump_dev << "\n\n" if @wiredump_dev
    receive_string = res.content
    if @wiredump_file_base
      filename = @wiredump_file_base + '_response.xml'
      f = File.open(filename, "w")
      f << receive_string
      f.close
    end
    case res.status
    when 405
      raise PostUnavailableError.new("#{ res.status }: #{ res.reason }")
    when 200, 500
      # Nothing to do.
    else
      raise HTTPStreamError.new("#{ res.status }: #{ res.reason }")
    end
    if res.respond_to?(:header) and !res.header['content-encoding'].empty? and
        res.header['content-encoding'][0].downcase == 'gzip'
      receive_string = decode_gzip(receive_string)
    end
    conn_data.receive_string = receive_string
    conn_data.receive_contenttype = res.contenttype
    conn_data
  end

  def send_accept_encoding_gzip?
    @accept_encoding_gzip and defined?(::Zlib)
  end

  def decode_gzip(instring)
    unless send_accept_encoding_gzip?
      raise HTTPStreamError.new("Gzipped response content.")
    end
    begin
      gz = Zlib::GzipReader.new(StringIO.new(instring))
      gz.read
    ensure
      gz.close
    end
  end
end


end
PK     Z\/~α      soap/property.rbnu [        # soap/property.rb: SOAP4R - Property implementation.
# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


module SOAP


# Property stream format:
#
#   line separator is \r?\n.  1 line per a property.
#   line which begins with '#' is a comment line.  empty line is ignored, too.
#   key/value separator is ':' or '='.
#   '\' as escape character.  but line separator cannot be escaped.
#   \s at the head/tail of key/value are trimmed.
#
#   '[' + key + ']' indicates property section.  for example,
#
#     [aaa.bbb]
#     ccc = ddd
#     eee.fff = ggg
#     []
#     aaa.hhh = iii
#
#   is the same as;
#
#     aaa.bbb.ccc = ddd
#     aaa.bbb.eee.fff = ggg
#     aaa.hhh = iii
#
class Property
  FrozenError = (RUBY_VERSION >= "1.9.0") ? RuntimeError : TypeError

  include Enumerable

  module Util
    def const_from_name(fqname)
      fqname.split("::").inject(Kernel) { |klass, name| klass.const_get(name) }
    end
    module_function :const_from_name

    def require_from_name(fqname)
      require File.join(fqname.split("::").collect { |ele| ele.downcase })
    end
    module_function :require_from_name
  end

  def self.load(stream)
    new.load(stream)
  end

  def self.loadproperty(propname)
    new.loadproperty(propname)
  end

  def initialize
    @store = Hash.new
    @hook = Hash.new
    @self_hook = Array.new
    @locked = false
  end

  KEY_REGSRC = '([^=:\\\\]*(?:\\\\.[^=:\\\\]*)*)'
  DEF_REGSRC = '\\s*' + KEY_REGSRC + '\\s*[=:]\\s*(.*)'
  COMMENT_REGEXP = Regexp.new('^(?:#.*|)$')
  CATDEF_REGEXP = Regexp.new("^\\[\\s*#{KEY_REGSRC}\\s*\\]$")
  LINE_REGEXP = Regexp.new("^#{DEF_REGSRC}$")
  def load(stream)
    key_prefix = ""
    stream.each_with_index do |line, lineno|
      line.sub!(/\r?\n\z/, '')
      case line
      when COMMENT_REGEXP
	next
      when CATDEF_REGEXP
	key_prefix = $1.strip
      when LINE_REGEXP
	key, value = $1.strip, $2.strip
	key = "#{key_prefix}.#{key}" unless key_prefix.empty?
	key, value = loadstr(key), loadstr(value)
	self[key] = value
      else
	raise TypeError.new(
	  "property format error at line #{lineno + 1}: `#{line}'")
      end
    end
    self
  end

  # find property from $:.
  def loadproperty(propname)
    return loadpropertyfile(propname) if File.file?(propname)
    $:.each do |path|
      if File.file?(file = File.join(path, propname))
        return loadpropertyfile(file)
      end
    end
    nil
  end

  # name: a Symbol, String or an Array
  def [](name)
    referent(name_to_a(name))
  end

  # name: a Symbol, String or an Array
  # value: an Object
  def []=(name, value)
    name_pair = name_to_a(name).freeze
    hooks = assign(name_pair, value)
    hooks.each do |hook|
      hook.call(name_pair, value)
    end
    value
  end

  # value: an Object
  # key is generated by property
  def <<(value)
    self[generate_new_key] = value
  end

  # name: a Symbol, String or an Array; nil means hook to the root
  # cascade: true/false; for cascading hook of sub key
  # hook: block which will be called with 2 args, name and value
  def add_hook(name = nil, cascade = false, &hook)
    if name == nil or name == true or name == false
      cascade = name
      assign_self_hook(cascade, &hook)
    else
      assign_hook(name_to_a(name), cascade, &hook)
    end
  end

  def each
    @store.each do |key, value|
      yield(key, value)
    end
  end

  def empty?
    @store.empty?
  end

  def keys
    @store.keys
  end

  def values
    @store.values
  end

  def lock(cascade = false)
    if cascade
      each_key do |key|
	key.lock(cascade)
      end
    end
    @locked = true
    self
  end

  def unlock(cascade = false)
    @locked = false
    if cascade
      each_key do |key|
	key.unlock(cascade)
      end
    end
    self
  end

  def locked?
    @locked
  end

protected

  def deref_key(key)
    check_lock(key)
    ref = @store[key] ||= self.class.new
    unless propkey?(ref)
      raise ArgumentError.new("key `#{key}' already defined as a value")
    end
    ref
  end

  def local_referent(key)
    check_lock(key)
    if propkey?(@store[key]) and @store[key].locked?
      raise FrozenError.new("cannot split any key from locked property")
    end
    @store[key]
  end

  def local_assign(key, value)
    check_lock(key)
    if @locked
      if propkey?(value)
	raise FrozenError.new("cannot add any key to locked property")
      elsif propkey?(@store[key])
	raise FrozenError.new("cannot override any key in locked property")
      end
    end
    @store[key] = value
  end

  def local_hook(key, direct)
    hooks = []
    (@self_hook + (@hook[key] || NO_HOOK)).each do |hook, cascade|
      hooks << hook if direct or cascade
    end
    hooks
  end

  def local_assign_hook(key, cascade, &hook)
    check_lock(key)
    @store[key] ||= nil
    (@hook[key] ||= []) << [hook, cascade]
  end

private

  NO_HOOK = [].freeze

  def referent(ary)
    ary[0..-2].inject(self) { |ref, name|
      ref.deref_key(to_key(name))
    }.local_referent(to_key(ary.last))
  end

  def assign(ary, value)
    ref = self
    hook = NO_HOOK
    ary[0..-2].each do |name|
      key = to_key(name)
      hook += ref.local_hook(key, false)
      ref = ref.deref_key(key)
    end
    last_key = to_key(ary.last)
    ref.local_assign(last_key, value)
    hook + ref.local_hook(last_key, true)
  end

  def assign_hook(ary, cascade, &hook)
    ary[0..-2].inject(self) { |ref, name|
      ref.deref_key(to_key(name))
    }.local_assign_hook(to_key(ary.last), cascade, &hook)
  end

  def assign_self_hook(cascade, &hook)
    check_lock(nil)
    @self_hook << [hook, cascade]
  end

  def each_key
    self.each do |key, value|
      if propkey?(value)
	yield(value)
      end
    end
  end

  def check_lock(key)
    if @locked and (key.nil? or !@store.key?(key))
      raise FrozenError.new("cannot add any key to locked property")
    end
  end

  def propkey?(value)
    value.is_a?(::SOAP::Property)
  end

  def name_to_a(name)
    case name
    when Symbol
      [name]
    when String
      name.scan(/[^.\\]+(?:\\.[^.\\])*/)	# split with unescaped '.'
    when Array
      name
    else
      raise ArgumentError.new("Unknown name #{name}(#{name.class})")
    end
  end

  def to_key(name)
    name.to_s.downcase
  end

  def generate_new_key
    if @store.empty?
      "0"
    else
      (key_max + 1).to_s
    end
  end

  def key_max
    (@store.keys.max { |l, r| l.to_s.to_i <=> r.to_s.to_i }).to_s.to_i
  end

  def loadpropertyfile(file)
    puts "find property at #{file}" if $DEBUG
    File.open(file) do |f|
      load(f)
    end
  end

  def loadstr(str)
    str.gsub(/\\./) { |c| eval("\"#{c}\"") }
  end
end


end


# for ruby/1.6.
unless Enumerable.instance_methods.include?('inject')
  module Enumerable
    def inject(init)
      result = init
      each do |item|
	result = yield(result, item)
      end
      result
    end
  end
end
PK     Z\&mBW
@  
@    soap/mapping/registry.rbnu [        # SOAP4R - Mapping registry.
# Copyright (C) 2000, 2001, 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/baseData'
require 'soap/mapping/mapping'
require 'soap/mapping/typeMap'
require 'soap/mapping/factory'
require 'soap/mapping/rubytypeFactory'


module SOAP


module Marshallable
  # @@type_ns = Mapping::RubyCustomTypeNamespace
end


module Mapping

  
module MappedException; end


RubyTypeName = XSD::QName.new(RubyTypeInstanceNamespace, 'rubyType')
RubyExtendName = XSD::QName.new(RubyTypeInstanceNamespace, 'extends')
RubyIVarName = XSD::QName.new(RubyTypeInstanceNamespace, 'ivars')


# Inner class to pass an exception.
class SOAPException; include Marshallable
  attr_reader :excn_type_name, :cause
  def initialize(e)
    @excn_type_name = Mapping.name2elename(e.class.to_s)
    @cause = e
  end

  def to_e
    if @cause.is_a?(::Exception)
      @cause.extend(::SOAP::Mapping::MappedException)
      return @cause
    elsif @cause.respond_to?(:message) and @cause.respond_to?(:backtrace)
      e = RuntimeError.new(@cause.message)
      e.set_backtrace(@cause.backtrace)
      return e
    end
    klass = Mapping.class_from_name(Mapping.elename2name(@excn_type_name.to_s))
    if klass.nil? or not klass <= ::Exception
      return RuntimeError.new(@cause.inspect)
    end
    obj = klass.new(@cause.message)
    obj.extend(::SOAP::Mapping::MappedException)
    obj
  end
end


# For anyType object: SOAP::Mapping::Object not ::Object
class Object; include Marshallable
  def initialize
    @__xmlele_type = {}
    @__xmlele = []
    @__xmlattr = {}
  end

  def inspect
    sprintf("#<%s:0x%x%s>", self.class.name, __id__,
      @__xmlele.collect { |name, value| " #{name}=#{value.inspect}" }.join)
  end

  def __xmlattr
    @__xmlattr
  end

  def __xmlele
    @__xmlele
  end

  def [](qname)
    unless qname.is_a?(XSD::QName)
      qname = XSD::QName.new(nil, qname)
    end
    @__xmlele.each do |k, v|
      return v if k == qname
    end
    # fallback
    @__xmlele.each do |k, v|
      return v if k.name == qname.name
    end
    nil
  end

  def []=(qname, value)
    unless qname.is_a?(XSD::QName)
      qname = XSD::QName.new(nil, qname)
    end
    found = false
    @__xmlele.each do |pair|
      if pair[0] == qname
        found = true
        pair[1] = value
      end
    end
    unless found
      __define_attr_accessor(qname)
      @__xmlele << [qname, value]
    end
    @__xmlele_type[qname] = :single
  end

  def __add_xmlele_value(qname, value)
    found = false
    @__xmlele.map! do |k, v|
      if k == qname
        found = true
        [k, __set_xmlele_value(k, v, value)]
      else
        [k, v]
      end
    end
    unless found
      __define_attr_accessor(qname)
      @__xmlele << [qname, value]
      @__xmlele_type[qname] = :single
    end
    value
  end

private

  if RUBY_VERSION > "1.7.0"
    def __define_attr_accessor(qname)
      name = XSD::CodeGen::GenSupport.safemethodname(qname.name)
      Mapping.define_attr_accessor(self, name,
        proc { self[qname] },
        proc { |value| self[qname] = value })
    end
  else
    def __define_attr_accessor(qname)
      name = XSD::CodeGen::GenSupport.safemethodname(qname.name)
      instance_eval <<-EOS
        def #{name}
          self[#{qname.dump}]
        end

        def #{name}=(value)
          self[#{qname.dump}] = value
        end
      EOS
    end
  end

  def __set_xmlele_value(key, org, value)
    case @__xmlele_type[key]
    when :multi
      org << value
      org
    when :single
      @__xmlele_type[key] = :multi
      [org, value]
    else
      raise RuntimeError.new("unknown type")
    end
  end
end


class MappingError < Error; end


class Registry
  class Map
    def initialize(registry)
      @obj2soap = {}
      @soap2obj = {}
      @registry = registry
    end

    def obj2soap(obj)
      klass = obj.class
      if map = @obj2soap[klass]
        map.each do |soap_class, factory, info|
          ret = factory.obj2soap(soap_class, obj, info, @registry)
          return ret if ret
        end
      end
      ancestors = klass.ancestors
      ancestors.delete(klass)
      ancestors.delete(::Object)
      ancestors.delete(::Kernel)
      ancestors.each do |klass|
        if map = @obj2soap[klass]
          map.each do |soap_class, factory, info|
            if info[:derived_class]
              ret = factory.obj2soap(soap_class, obj, info, @registry)
              return ret if ret
            end
          end
        end
      end
      nil
    end

    def soap2obj(node, klass = nil)
      if map = @soap2obj[node.class]
        map.each do |obj_class, factory, info|
          next if klass and obj_class != klass
          conv, obj = factory.soap2obj(obj_class, node, info, @registry)
          return true, obj if conv
        end
      end
      return false, nil
    end

    # Give priority to former entry.
    def init(init_map = [])
      clear
      init_map.reverse_each do |obj_class, soap_class, factory, info|
        add(obj_class, soap_class, factory, info)
      end
    end

    # Give priority to latter entry.
    def add(obj_class, soap_class, factory, info)
      info ||= {}
      (@obj2soap[obj_class] ||= []).unshift([soap_class, factory, info])
      (@soap2obj[soap_class] ||= []).unshift([obj_class, factory, info])
    end

    def clear
      @obj2soap.clear
      @soap2obj.clear
    end

    def find_mapped_soap_class(target_obj_class)
      map = @obj2soap[target_obj_class]
      map.empty? ? nil : map[0][1]
    end

    def find_mapped_obj_class(target_soap_class)
      map = @soap2obj[target_soap_class]
      map.empty? ? nil : map[0][0]
    end
  end

  StringFactory = StringFactory_.new
  BasetypeFactory = BasetypeFactory_.new
  DateTimeFactory = DateTimeFactory_.new
  ArrayFactory = ArrayFactory_.new
  Base64Factory = Base64Factory_.new
  URIFactory = URIFactory_.new
  TypedArrayFactory = TypedArrayFactory_.new
  TypedStructFactory = TypedStructFactory_.new

  HashFactory = HashFactory_.new

  SOAPBaseMap = [
    [::NilClass,     ::SOAP::SOAPNil,        BasetypeFactory],
    [::TrueClass,    ::SOAP::SOAPBoolean,    BasetypeFactory],
    [::FalseClass,   ::SOAP::SOAPBoolean,    BasetypeFactory],
    [::String,       ::SOAP::SOAPString,     StringFactory],
    [::DateTime,     ::SOAP::SOAPDateTime,   DateTimeFactory],
    [::Date,         ::SOAP::SOAPDate,       DateTimeFactory],
    [::Time,         ::SOAP::SOAPDateTime,   DateTimeFactory],
    [::Time,         ::SOAP::SOAPTime,       DateTimeFactory],
    [::Float,        ::SOAP::SOAPDouble,     BasetypeFactory,
      {:derived_class => true}],
    [::Float,        ::SOAP::SOAPFloat,      BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPInt,        BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPLong,       BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPInteger,    BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPShort,      BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPByte,       BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPNonPositiveInteger, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPNegativeInteger, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPNonNegativeInteger, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPPositiveInteger, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPUnsignedLong, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPUnsignedInt, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPUnsignedShort, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPUnsignedByte, BasetypeFactory,
      {:derived_class => true}],
    [::URI::Generic, ::SOAP::SOAPAnyURI,     URIFactory,
      {:derived_class => true}],
    [::String,       ::SOAP::SOAPBase64,     Base64Factory],
    [::String,       ::SOAP::SOAPHexBinary,  Base64Factory],
    [::String,       ::SOAP::SOAPDecimal,    BasetypeFactory],
    [::String,       ::SOAP::SOAPDuration,   BasetypeFactory],
    [::String,       ::SOAP::SOAPGYearMonth, BasetypeFactory],
    [::String,       ::SOAP::SOAPGYear,      BasetypeFactory],
    [::String,       ::SOAP::SOAPGMonthDay,  BasetypeFactory],
    [::String,       ::SOAP::SOAPGDay,       BasetypeFactory],
    [::String,       ::SOAP::SOAPGMonth,     BasetypeFactory],
    [::String,       ::SOAP::SOAPQName,      BasetypeFactory],

    [::Hash,         ::SOAP::SOAPArray,      HashFactory],
    [::Hash,         ::SOAP::SOAPStruct,     HashFactory],

    [::Array,        ::SOAP::SOAPArray,      ArrayFactory,
      {:derived_class => true}],

    [::SOAP::Mapping::SOAPException,
		     ::SOAP::SOAPStruct,     TypedStructFactory,
      {:type => XSD::QName.new(RubyCustomTypeNamespace, "SOAPException")}],
 ]

  RubyOriginalMap = [
    [::NilClass,     ::SOAP::SOAPNil,        BasetypeFactory],
    [::TrueClass,    ::SOAP::SOAPBoolean,    BasetypeFactory],
    [::FalseClass,   ::SOAP::SOAPBoolean,    BasetypeFactory],
    [::String,       ::SOAP::SOAPString,     StringFactory],
    [::DateTime,     ::SOAP::SOAPDateTime,   DateTimeFactory],
    [::Date,         ::SOAP::SOAPDate,       DateTimeFactory],
    [::Time,         ::SOAP::SOAPDateTime,   DateTimeFactory],
    [::Time,         ::SOAP::SOAPTime,       DateTimeFactory],
    [::Float,        ::SOAP::SOAPDouble,     BasetypeFactory,
      {:derived_class => true}],
    [::Float,        ::SOAP::SOAPFloat,      BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPInt,        BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPLong,       BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPInteger,    BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPShort,      BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPByte,       BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPNonPositiveInteger, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPNegativeInteger, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPNonNegativeInteger, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPPositiveInteger, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPUnsignedLong, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPUnsignedInt, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPUnsignedShort, BasetypeFactory,
      {:derived_class => true}],
    [::Integer,      ::SOAP::SOAPUnsignedByte, BasetypeFactory,
      {:derived_class => true}],
    [::URI::Generic, ::SOAP::SOAPAnyURI,     URIFactory,
      {:derived_class => true}],
    [::String,       ::SOAP::SOAPBase64,     Base64Factory],
    [::String,       ::SOAP::SOAPHexBinary,  Base64Factory],
    [::String,       ::SOAP::SOAPDecimal,    BasetypeFactory],
    [::String,       ::SOAP::SOAPDuration,   BasetypeFactory],
    [::String,       ::SOAP::SOAPGYearMonth, BasetypeFactory],
    [::String,       ::SOAP::SOAPGYear,      BasetypeFactory],
    [::String,       ::SOAP::SOAPGMonthDay,  BasetypeFactory],
    [::String,       ::SOAP::SOAPGDay,       BasetypeFactory],
    [::String,       ::SOAP::SOAPGMonth,     BasetypeFactory],
    [::String,       ::SOAP::SOAPQName,      BasetypeFactory],

    [::Hash,         ::SOAP::SOAPArray,      HashFactory],
    [::Hash,         ::SOAP::SOAPStruct,     HashFactory],

    # Does not allow Array's subclass here.
    [::Array,        ::SOAP::SOAPArray,      ArrayFactory],

    [::SOAP::Mapping::SOAPException,
                     ::SOAP::SOAPStruct,     TypedStructFactory,
      {:type => XSD::QName.new(RubyCustomTypeNamespace, "SOAPException")}],
  ]

  attr_accessor :default_factory
  attr_accessor :excn_handler_obj2soap
  attr_accessor :excn_handler_soap2obj

  def initialize(config = {})
    @config = config
    @map = Map.new(self)
    if @config[:allow_original_mapping]
      @allow_original_mapping = true
      @map.init(RubyOriginalMap)
    else
      @allow_original_mapping = false
      @map.init(SOAPBaseMap)
    end
    @allow_untyped_struct = @config.key?(:allow_untyped_struct) ?
      @config[:allow_untyped_struct] : true
    @rubytype_factory = RubytypeFactory.new(
      :allow_untyped_struct => @allow_untyped_struct,
      :allow_original_mapping => @allow_original_mapping
    )
    @default_factory = @rubytype_factory
    @excn_handler_obj2soap = nil
    @excn_handler_soap2obj = nil
  end

  def add(obj_class, soap_class, factory, info = nil)
    @map.add(obj_class, soap_class, factory, info)
  end
  alias set add

  # general Registry ignores type_qname
  def obj2soap(obj, type_qname = nil)
    soap = _obj2soap(obj)
    if @allow_original_mapping
      addextend2soap(soap, obj)
    end
    soap
  end

  def soap2obj(node, klass = nil)
    obj = _soap2obj(node, klass)
    if @allow_original_mapping
      addextend2obj(obj, node.extraattr[RubyExtendName])
      addiv2obj(obj, node.extraattr[RubyIVarName])
    end
    obj
  end

  def find_mapped_soap_class(obj_class)
    @map.find_mapped_soap_class(obj_class)
  end

  def find_mapped_obj_class(soap_class)
    @map.find_mapped_obj_class(soap_class)
  end

private

  def _obj2soap(obj)
    ret = nil
    if obj.is_a?(SOAPStruct) or obj.is_a?(SOAPArray)
      obj.replace do |ele|
        Mapping._obj2soap(ele, self)
      end
      return obj
    elsif obj.is_a?(SOAPBasetype)
      return obj
    end
    begin 
      ret = @map.obj2soap(obj) ||
        @default_factory.obj2soap(nil, obj, nil, self)
      return ret if ret
    rescue MappingError
    end
    if @excn_handler_obj2soap
      ret = @excn_handler_obj2soap.call(obj) { |yield_obj|
        Mapping._obj2soap(yield_obj, self)
      }
      return ret if ret
    end
    raise MappingError.new("Cannot map #{ obj.class.name } to SOAP/OM.")
  end

  # Might return nil as a mapping result.
  def _soap2obj(node, klass = nil)
    if node.extraattr.key?(RubyTypeName)
      conv, obj = @rubytype_factory.soap2obj(nil, node, nil, self)
      return obj if conv
    else
      conv, obj = @map.soap2obj(node, klass)
      return obj if conv
      conv, obj = @default_factory.soap2obj(nil, node, nil, self)
      return obj if conv
    end
    if @excn_handler_soap2obj
      begin
        return @excn_handler_soap2obj.call(node) { |yield_node|
	    Mapping._soap2obj(yield_node, self)
	  }
      rescue Exception
      end
    end
    raise MappingError.new("Cannot map #{ node.type.name } to Ruby object.")
  end

  def addiv2obj(obj, attr)
    return unless attr
    vars = {}
    attr.__getobj__.each do |name, value|
      vars[name] = Mapping._soap2obj(value, self)
    end
    Mapping.set_attributes(obj, vars)
  end

  if RUBY_VERSION >= '1.8.0'
    def addextend2obj(obj, attr)
      return unless attr
      attr.split(/ /).reverse_each do |mstr|
	obj.extend(Mapping.module_from_name(mstr))
      end
    end
  else
    # (class < false; self; end).ancestors includes "TrueClass" under 1.6...
    def addextend2obj(obj, attr)
      return unless attr
      attr.split(/ /).reverse_each do |mstr|
	m = Mapping.module_from_name(mstr)
	obj.extend(m)
      end
    end
  end

  def addextend2soap(node, obj)
    return if obj.is_a?(Symbol) or obj.is_a?(Fixnum)
    list = (class << obj; self; end).ancestors - obj.class.ancestors
    unless list.empty?
      node.extraattr[RubyExtendName] = list.collect { |c|
	if c.name.empty?
  	  raise TypeError.new("singleton can't be dumped #{ obj }")
   	end
	c.name
      }.join(" ")
    end
  end

end


DefaultRegistry = Registry.new
RubyOriginalRegistry = Registry.new(:allow_original_mapping => true)


end
end
PK     Z\ʻ$oB<  B<    soap/mapping/rubytypeFactory.rbnu [        # SOAP4R - Ruby type mapping factory.
# Copyright (C) 2000-2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


module SOAP
module Mapping


class RubytypeFactory < Factory
  TYPE_STRING = XSD::QName.new(RubyTypeNamespace, 'String')
  TYPE_TIME = XSD::QName.new(RubyTypeNamespace, 'Time')
  TYPE_ARRAY = XSD::QName.new(RubyTypeNamespace, 'Array')
  TYPE_REGEXP = XSD::QName.new(RubyTypeNamespace, 'Regexp')
  TYPE_RANGE = XSD::QName.new(RubyTypeNamespace, 'Range')
  TYPE_CLASS = XSD::QName.new(RubyTypeNamespace, 'Class')
  TYPE_MODULE = XSD::QName.new(RubyTypeNamespace, 'Module')
  TYPE_SYMBOL = XSD::QName.new(RubyTypeNamespace, 'Symbol')
  TYPE_STRUCT = XSD::QName.new(RubyTypeNamespace, 'Struct')
  TYPE_HASH = XSD::QName.new(RubyTypeNamespace, 'Map')

  def initialize(config = {})
    @config = config
    @allow_untyped_struct = @config.key?(:allow_untyped_struct) ?
      @config[:allow_untyped_struct] : true
    @allow_original_mapping = @config.key?(:allow_original_mapping) ?
      @config[:allow_original_mapping] : false
    @string_factory = StringFactory_.new(true)
    @basetype_factory = BasetypeFactory_.new(true)
    @datetime_factory = DateTimeFactory_.new(true)
    @array_factory = ArrayFactory_.new(true)
    @hash_factory = HashFactory_.new(true)
  end

  def obj2soap(soap_class, obj, info, map)
    param = nil
    case obj
    when ::String
      unless @allow_original_mapping
        return nil
      end
      param = @string_factory.obj2soap(SOAPString, obj, info, map)
      if obj.class != String
        param.extraattr[RubyTypeName] = obj.class.name
      end
      addiv2soapattr(param, obj, map)
    when ::Time
      unless @allow_original_mapping
        return nil
      end
      param = @datetime_factory.obj2soap(SOAPDateTime, obj, info, map)
      if obj.class != Time
        param.extraattr[RubyTypeName] = obj.class.name
      end
      addiv2soapattr(param, obj, map)
    when ::Array
      unless @allow_original_mapping
        return nil
      end
      param = @array_factory.obj2soap(nil, obj, info, map)
      if obj.class != Array
        param.extraattr[RubyTypeName] = obj.class.name
      end
      addiv2soapattr(param, obj, map)
    when ::NilClass
      unless @allow_original_mapping
        return nil
      end
      param = @basetype_factory.obj2soap(SOAPNil, obj, info, map)
      addiv2soapattr(param, obj, map)
    when ::FalseClass, ::TrueClass
      unless @allow_original_mapping
        return nil
      end
      param = @basetype_factory.obj2soap(SOAPBoolean, obj, info, map)
      addiv2soapattr(param, obj, map)
    when ::Integer
      unless @allow_original_mapping
        return nil
      end
      param = @basetype_factory.obj2soap(SOAPInt, obj, info, map)
      param ||= @basetype_factory.obj2soap(SOAPInteger, obj, info, map)
      param ||= @basetype_factory.obj2soap(SOAPDecimal, obj, info, map)
      addiv2soapattr(param, obj, map)
    when ::Float
      unless @allow_original_mapping
        return nil
      end
      param = @basetype_factory.obj2soap(SOAPDouble, obj, info, map)
      if obj.class != Float
        param.extraattr[RubyTypeName] = obj.class.name
      end
      addiv2soapattr(param, obj, map)
    when ::Hash
      unless @allow_original_mapping
        return nil
      end
      if obj.respond_to?(:default_proc) && obj.default_proc
        raise TypeError.new("cannot dump hash with default proc")
      end
      param = SOAPStruct.new(TYPE_HASH)
      mark_marshalled_obj(obj, param)
      if obj.class != Hash
        param.extraattr[RubyTypeName] = obj.class.name
      end
      obj.each do |key, value|
        elem = SOAPStruct.new # Undefined type.
        elem.add("key", Mapping._obj2soap(key, map))
        elem.add("value", Mapping._obj2soap(value, map))
        param.add("item", elem)
      end
      param.add('default', Mapping._obj2soap(obj.default, map))
      addiv2soapattr(param, obj, map)
    when ::Regexp
      unless @allow_original_mapping
        return nil
      end
      param = SOAPStruct.new(TYPE_REGEXP)
      mark_marshalled_obj(obj, param)
      if obj.class != Regexp
        param.extraattr[RubyTypeName] = obj.class.name
      end
      param.add('source', SOAPBase64.new(obj.source))
      if obj.respond_to?('options')
        # Regexp#options is from Ruby/1.7
        options = obj.options
      else
        options = 0
        obj.inspect.sub(/^.*\//, '').each_byte do |c|
          options += case c
            when ?i
              1
            when ?x
              2
            when ?m
              4
            when ?n
              16
            when ?e
              32
            when ?s
              48
            when ?u
              64
            end
        end
      end
      param.add('options', SOAPInt.new(options))
      addiv2soapattr(param, obj, map)
    when ::Range
      unless @allow_original_mapping
        return nil
      end
      param = SOAPStruct.new(TYPE_RANGE)
      mark_marshalled_obj(obj, param)
      if obj.class != Range
        param.extraattr[RubyTypeName] = obj.class.name
      end
      param.add('begin', Mapping._obj2soap(obj.begin, map))
      param.add('end', Mapping._obj2soap(obj.end, map))
      param.add('exclude_end', SOAP::SOAPBoolean.new(obj.exclude_end?))
      addiv2soapattr(param, obj, map)
    when ::Class
      unless @allow_original_mapping
        return nil
      end
      if obj.to_s[0] == ?#
        raise TypeError.new("can't dump anonymous class #{obj}")
      end
      param = SOAPStruct.new(TYPE_CLASS)
      mark_marshalled_obj(obj, param)
      param.add('name', SOAPString.new(obj.name))
      addiv2soapattr(param, obj, map)
    when ::Module
      unless @allow_original_mapping
        return nil
      end
      if obj.to_s[0] == ?#
        raise TypeError.new("can't dump anonymous module #{obj}")
      end
      param = SOAPStruct.new(TYPE_MODULE)
      mark_marshalled_obj(obj, param)
      param.add('name', SOAPString.new(obj.name))
      addiv2soapattr(param, obj, map)
    when ::Symbol
      unless @allow_original_mapping
        return nil
      end
      param = SOAPStruct.new(TYPE_SYMBOL)
      mark_marshalled_obj(obj, param)
      param.add('id', SOAPString.new(obj.id2name))
      addiv2soapattr(param, obj, map)
    when ::Struct
      unless @allow_original_mapping
        # treat it as an user defined class. [ruby-talk:104980]
        #param = unknownobj2soap(soap_class, obj, info, map)
        param = SOAPStruct.new(XSD::AnyTypeName)
        mark_marshalled_obj(obj, param)
        obj.members.each do |member|
          param.add(Mapping.name2elename(member),
            Mapping._obj2soap(obj[member], map))
        end
      else
        param = SOAPStruct.new(TYPE_STRUCT)
        mark_marshalled_obj(obj, param)
        param.add('type', ele_type = SOAPString.new(obj.class.to_s))
        ele_member = SOAPStruct.new
        obj.members.each do |member|
          ele_member.add(Mapping.name2elename(member),
            Mapping._obj2soap(obj[member], map))
        end
        param.add('member', ele_member)
        addiv2soapattr(param, obj, map)
      end
    when ::IO, ::Binding, ::Continuation, ::Data, ::Dir, ::File::Stat,
        ::MatchData, Method, ::Proc, ::Thread, ::ThreadGroup
        # from 1.8: Process::Status, UnboundMethod
      return nil
    when ::SOAP::Mapping::Object
      param = SOAPStruct.new(XSD::AnyTypeName)
      mark_marshalled_obj(obj, param)
      obj.__xmlele.each do |key, value|
        param.add(key.name, Mapping._obj2soap(value, map))
      end
      obj.__xmlattr.each do |key, value|
        param.extraattr[key] = value
      end
    when ::Exception
      typestr = Mapping.name2elename(obj.class.to_s)
      param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, typestr))
      mark_marshalled_obj(obj, param)
      param.add('message', Mapping._obj2soap(obj.message, map))
      param.add('backtrace', Mapping._obj2soap(obj.backtrace, map))
      addiv2soapattr(param, obj, map)
    else
      param = unknownobj2soap(soap_class, obj, info, map)
    end
    param
  end

  def soap2obj(obj_class, node, info, map)
    rubytype = node.extraattr[RubyTypeName]
    if rubytype or node.type.namespace == RubyTypeNamespace
      rubytype2obj(node, info, map, rubytype)
    elsif node.type == XSD::AnyTypeName or node.type == XSD::AnySimpleTypeName
      anytype2obj(node, info, map)
    else
      unknowntype2obj(node, info, map)
    end
  end

private

  def addiv2soapattr(node, obj, map)
    return if obj.instance_variables.empty?
    ivars = SOAPStruct.new    # Undefined type.
    setiv2soap(ivars, obj, map)
    node.extraattr[RubyIVarName] = ivars
  end

  def unknownobj2soap(soap_class, obj, info, map)
    if obj.class.name.empty?
      raise TypeError.new("can't dump anonymous class #{obj}")
    end
    singleton_class = class << obj; self; end
    if !singleton_methods_true(obj).empty? or
	!singleton_class.instance_variables.empty?
      raise TypeError.new("singleton can't be dumped #{obj}")
    end
    if !(singleton_class.ancestors - obj.class.ancestors).empty?
      typestr = Mapping.name2elename(obj.class.to_s)
      type = XSD::QName.new(RubyTypeNamespace, typestr)
    else
      type = Mapping.class2element(obj.class)
    end
    param = SOAPStruct.new(type)
    mark_marshalled_obj(obj, param)
    setiv2soap(param, obj, map)
    param
  end

  if RUBY_VERSION >= '1.8.0'
    def singleton_methods_true(obj)
      obj.singleton_methods(true)
    end
  else
    def singleton_methods_true(obj)
      obj.singleton_methods
    end
  end

  def rubytype2obj(node, info, map, rubytype)
    klass = rubytype ? Mapping.class_from_name(rubytype) : nil
    obj = nil
    case node
    when SOAPString
      return @string_factory.soap2obj(klass || String, node, info, map)
    when SOAPDateTime
      #return @datetime_factory.soap2obj(klass || Time, node, info, map)
      klass ||= Time
      t = node.to_time
      arg = [t.year, t.month, t.mday, t.hour, t.min, t.sec, t.usec]
      obj = t.gmt? ? klass.gm(*arg) : klass.local(*arg)
      mark_unmarshalled_obj(node, obj)
      return true, obj
    when SOAPArray
      return @array_factory.soap2obj(klass || Array, node, info, map)
    when SOAPNil, SOAPBoolean, SOAPInt, SOAPInteger, SOAPDecimal, SOAPDouble
      return @basetype_factory.soap2obj(nil, node, info, map)
    when SOAPStruct
      return rubytypestruct2obj(node, info, map, rubytype)
    else
      raise
    end
  end

  def rubytypestruct2obj(node, info, map, rubytype)
    klass = rubytype ? Mapping.class_from_name(rubytype) : nil
    obj = nil
    case node.type
    when TYPE_HASH
      klass = rubytype ? Mapping.class_from_name(rubytype) : Hash
      obj = Mapping.create_empty_object(klass)
      mark_unmarshalled_obj(node, obj)
      node.each do |key, value|
        next unless key == 'item'
        obj[Mapping._soap2obj(value['key'], map)] =
          Mapping._soap2obj(value['value'], map)
      end
      if node.key?('default')
        obj.default = Mapping._soap2obj(node['default'], map)
      end
    when TYPE_REGEXP
      klass = rubytype ? Mapping.class_from_name(rubytype) : Regexp
      obj = Mapping.create_empty_object(klass)
      mark_unmarshalled_obj(node, obj)
      source = node['source'].string
      options = node['options'].data || 0
      Regexp.instance_method(:initialize).bind(obj).call(source, options)
    when TYPE_RANGE
      klass = rubytype ? Mapping.class_from_name(rubytype) : Range
      obj = Mapping.create_empty_object(klass)
      mark_unmarshalled_obj(node, obj)
      first = Mapping._soap2obj(node['begin'], map)
      last = Mapping._soap2obj(node['end'], map)
      exclude_end = node['exclude_end'].data
      Range.instance_method(:initialize).bind(obj).call(first, last, exclude_end)
    when TYPE_CLASS
      obj = Mapping.class_from_name(node['name'].data)
    when TYPE_MODULE
      obj = Mapping.class_from_name(node['name'].data)
    when TYPE_SYMBOL
      obj = node['id'].data.intern
    when TYPE_STRUCT
      typestr = Mapping.elename2name(node['type'].data)
      klass = Mapping.class_from_name(typestr)
      if klass.nil?
        return false
      end
      unless klass <= ::Struct
        return false
      end
      obj = Mapping.create_empty_object(klass)
      mark_unmarshalled_obj(node, obj)
      node['member'].each do |name, value|
        obj[Mapping.elename2name(name)] = Mapping._soap2obj(value, map)
      end
    else
      return unknowntype2obj(node, info, map)
    end
    return true, obj
  end

  def anytype2obj(node, info, map)
    case node
    when SOAPBasetype
      return true, node.data
    when SOAPStruct
      klass = ::SOAP::Mapping::Object
      obj = klass.new
      mark_unmarshalled_obj(node, obj)
      node.each do |name, value|
        obj.__add_xmlele_value(XSD::QName.new(nil, name),
          Mapping._soap2obj(value, map))
      end
      unless node.extraattr.empty?
        obj.instance_variable_set('@__xmlattr', node.extraattr)
      end
      return true, obj
    else
      return false
    end
  end

  def unknowntype2obj(node, info, map)
    case node
    when SOAPBasetype
      return true, node.data
    when SOAPArray
      return @array_factory.soap2obj(Array, node, info, map)
    when SOAPStruct
      obj = unknownstruct2obj(node, info, map)
      return true, obj if obj
      if !@allow_untyped_struct
        return false
      end
      return anytype2obj(node, info, map)
    else
      # Basetype which is not defined...
      return false
    end
  end

  def unknownstruct2obj(node, info, map)
    unless node.type.name
      return nil
    end
    typestr = Mapping.elename2name(node.type.name)
    klass = Mapping.class_from_name(typestr)
    if klass.nil? and @allow_untyped_struct
      klass = Mapping.class_from_name(typestr, true)    # lenient
    end
    if klass.nil?
      return nil
    end
    if klass <= ::Exception
      return exception2obj(klass, node, map)
    end
    klass_type = Mapping.class2qname(klass)
    return nil unless node.type.match(klass_type)
    obj = nil
    begin
      obj = Mapping.create_empty_object(klass)
    rescue
      # type name "data" tries Data.new which raises TypeError
      nil
    end
    mark_unmarshalled_obj(node, obj)
    setiv2obj(obj, node, map)
    obj
  end

  def exception2obj(klass, node, map)
    message = Mapping._soap2obj(node['message'], map)
    backtrace = Mapping._soap2obj(node['backtrace'], map)
    obj = Mapping.create_empty_object(klass)
    obj = obj.exception(message)
    mark_unmarshalled_obj(node, obj)
    obj.set_backtrace(backtrace)
    obj
  end

  # Only creates empty array.  Do String#replace it with real string.
  def array2obj(node, map, rubytype)
    klass = rubytype ? Mapping.class_from_name(rubytype) : Array
    obj = Mapping.create_empty_object(klass)
    mark_unmarshalled_obj(node, obj)
    obj
  end

  # Only creates empty string.  Do String#replace it with real string.
  def string2obj(node, map, rubytype)
    klass = rubytype ? Mapping.class_from_name(rubytype) : String
    obj = Mapping.create_empty_object(klass)
    mark_unmarshalled_obj(node, obj)
    obj
  end
end


end
end
PK     Z\P|-  |-  #  soap/mapping/wsdlliteralregistry.rbnu [        # SOAP4R - WSDL literal mapping registry.
# Copyright (C) 2004, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/baseData'
require 'soap/mapping/mapping'
require 'soap/mapping/typeMap'
require 'xsd/codegen/gensupport'
require 'xsd/namedelements'


module SOAP
module Mapping


class WSDLLiteralRegistry < Registry
  attr_reader :definedelements
  attr_reader :definedtypes
  attr_accessor :excn_handler_obj2soap
  attr_accessor :excn_handler_soap2obj

  def initialize(definedtypes = XSD::NamedElements::Empty,
      definedelements = XSD::NamedElements::Empty)
    @definedtypes = definedtypes
    @definedelements = definedelements
    @excn_handler_obj2soap = nil
    @excn_handler_soap2obj = nil
    @schema_element_cache = {}
    @schema_attribute_cache = {}
  end

  def obj2soap(obj, qname)
    soap_obj = nil
    if ele = @definedelements[qname]
      soap_obj = obj2elesoap(obj, ele)
    elsif type = @definedtypes[qname]
      soap_obj = obj2typesoap(obj, type, true)
    else
      soap_obj = any2soap(obj, qname)
    end
    return soap_obj if soap_obj
    if @excn_handler_obj2soap
      soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj|
        Mapping.obj2soap(yield_obj, nil, nil, MAPPING_OPT)
      }
      return soap_obj if soap_obj
    end
    raise MappingError.new("cannot map #{obj.class.name} as #{qname}")
  end

  # node should be a SOAPElement
  def soap2obj(node, obj_class = nil)
    # obj_class is given when rpc/literal service.  but ignored for now.
    begin
      return any2obj(node)
    rescue MappingError
    end
    if @excn_handler_soap2obj
      begin
        return @excn_handler_soap2obj.call(node) { |yield_node|
	    Mapping.soap2obj(yield_node, nil, nil, MAPPING_OPT)
	  }
      rescue Exception
      end
    end
    if node.respond_to?(:type)
      raise MappingError.new("cannot map #{node.type.name} to Ruby object")
    else
      raise MappingError.new("cannot map #{node.elename.name} to Ruby object")
    end
  end

private

  MAPPING_OPT = { :no_reference => true }

  def obj2elesoap(obj, ele)
    o = nil
    qualified = (ele.elementform == 'qualified')
    if ele.type
      if type = @definedtypes[ele.type]
        o = obj2typesoap(obj, type, qualified)
      elsif type = TypeMap[ele.type]
        o = base2soap(obj, type)
      else
        raise MappingError.new("cannot find type #{ele.type}")
      end
    elsif ele.local_complextype
      o = obj2typesoap(obj, ele.local_complextype, qualified)
      add_attributes2soap(obj, o)
    elsif ele.local_simpletype
      o = obj2typesoap(obj, ele.local_simpletype, qualified)
    else
      raise MappingError.new('illegal schema?')
    end
    o.elename = ele.name
    o
  end

  def obj2typesoap(obj, type, qualified)
    if type.is_a?(::WSDL::XMLSchema::SimpleType)
      simpleobj2soap(obj, type)
    else
      complexobj2soap(obj, type, qualified)
    end
  end

  def simpleobj2soap(obj, type)
    type.check_lexical_format(obj)
    return SOAPNil.new if obj.nil?      # ToDo: check nillable.
    o = base2soap(obj, TypeMap[type.base])
    o
  end

  def complexobj2soap(obj, type, qualified)
    o = SOAPElement.new(type.name)
    o.qualified = qualified
    type.each_element do |child_ele|
      child = Mapping.get_attribute(obj, child_ele.name.name)
      if child.nil?
        if child_ele.nillable
          # ToDo: test
          # add empty element
          child_soap = obj2elesoap(nil, child_ele)
          o.add(child_soap)
        elsif Integer(child_ele.minoccurs) == 0
          # nothing to do
        else
          raise MappingError.new("nil not allowed: #{child_ele.name.name}")
        end
      elsif child_ele.map_as_array?
        child.each do |item|
          child_soap = obj2elesoap(item, child_ele)
          o.add(child_soap)
        end
      else
        child_soap = obj2elesoap(child, child_ele)
        o.add(child_soap)
      end
    end
    o
  end

  def any2soap(obj, qname)
    if obj.is_a?(SOAPElement)
      obj
    elsif obj.class.class_variables.include?('@@schema_element')
      stubobj2soap(obj, qname)
    elsif obj.is_a?(SOAP::Mapping::Object)
      mappingobj2soap(obj, qname)
    elsif obj.is_a?(Hash)
      ele = SOAPElement.from_obj(obj)
      ele.elename = qname
      ele
    else
      # expected to be a basetype or an anyType.
      # SOAPStruct, etc. is used instead of SOAPElement.
      begin
        ele = Mapping.obj2soap(obj, nil, nil, MAPPING_OPT)
        ele.elename = qname
        ele
      rescue MappingError
        ele = SOAPElement.new(qname, obj.to_s)
      end
      if obj.respond_to?(:__xmlattr)
        obj.__xmlattr.each do |key, value|
          ele.extraattr[key] = value
        end
      end
      ele
    end
  end

  def stubobj2soap(obj, qname)
    ele = SOAPElement.new(qname)
    ele.qualified =
      (obj.class.class_variables.include?('@@schema_qualified') and
      obj.class.class_eval('@@schema_qualified'))
    add_elements2soap(obj, ele)
    add_attributes2soap(obj, ele)
    ele
  end

  def mappingobj2soap(obj, qname)
    ele = SOAPElement.new(qname)
    obj.__xmlele.each do |key, value|
      if value.is_a?(::Array)
        value.each do |item|
          ele.add(obj2soap(item, key))
        end
      else
        ele.add(obj2soap(value, key))
      end
    end
    obj.__xmlattr.each do |key, value|
      ele.extraattr[key] = value
    end
    ele
  end

  def add_elements2soap(obj, ele)
    elements, as_array = schema_element_definition(obj.class)
    if elements
      elements.each do |elename, type|
        if child = Mapping.get_attribute(obj, elename.name)
          if as_array.include?(elename.name)
            child.each do |item|
              ele.add(obj2soap(item, elename))
            end
          else
            ele.add(obj2soap(child, elename))
          end
        elsif obj.is_a?(::Array) and as_array.include?(elename.name)
          obj.each do |item|
            ele.add(obj2soap(item, elename))
          end
        end
      end
    end
  end
  
  def add_attributes2soap(obj, ele)
    attributes = schema_attribute_definition(obj.class)
    if attributes
      attributes.each do |qname, param|
        attr = obj.__send__('xmlattr_' +
          XSD::CodeGen::GenSupport.safevarname(qname.name))
        ele.extraattr[qname] = attr
      end
    end
  end

  def base2soap(obj, type)
    soap_obj = nil
    if type <= XSD::XSDString
      str = XSD::Charset.encoding_conv(obj.to_s,
        Thread.current[:SOAPExternalCES], XSD::Charset.encoding)
      soap_obj = type.new(str)
    else
      soap_obj = type.new(obj)
    end
    soap_obj
  end

  def anytype2obj(node)
    if node.is_a?(::SOAP::SOAPBasetype)
      return node.data
    end
    klass = ::SOAP::Mapping::Object
    obj = klass.new
    obj
  end

  def any2obj(node, obj_class = nil)
    unless obj_class
      typestr = XSD::CodeGen::GenSupport.safeconstname(node.elename.name)
      obj_class = Mapping.class_from_name(typestr)
    end
    if obj_class and obj_class.class_variables.include?('@@schema_element')
      soapele2stubobj(node, obj_class)
    elsif node.is_a?(SOAPElement) or node.is_a?(SOAPStruct)
        # SOAPArray for literal?
      soapele2plainobj(node)
    else
      obj = Mapping.soap2obj(node, nil, obj_class, MAPPING_OPT)
      add_attributes2plainobj(node, obj)
      obj
    end
  end

  def soapele2stubobj(node, obj_class)
    obj = Mapping.create_empty_object(obj_class)
    add_elements2stubobj(node, obj)
    add_attributes2stubobj(node, obj)
    obj
  end

  def soapele2plainobj(node)
    obj = anytype2obj(node)
    add_elements2plainobj(node, obj)
    add_attributes2plainobj(node, obj)
    obj
  end

  def add_elements2stubobj(node, obj)
    elements, as_array = schema_element_definition(obj.class)
    vars = {}
    node.each do |name, value|
      item = elements.find { |k, v| k.name == name }
      if item
        elename, class_name = item
        if klass = Mapping.class_from_name(class_name)
          # klass must be a SOAPBasetype or a class
          if klass.ancestors.include?(::SOAP::SOAPBasetype)
            if value.respond_to?(:data)
              child = klass.new(value.data).data
            else
              child = klass.new(nil).data
            end
          else
            child = any2obj(value, klass)
          end
        elsif klass = Mapping.module_from_name(class_name)
          # simpletype
          if value.respond_to?(:data)
            child = value.data
          else
            raise MappingError.new(
              "cannot map to a module value: #{class_name}")
          end
        else
          raise MappingError.new("unknown class/module: #{class_name}")
        end
      else      # untyped element is treated as anyType.
        child = any2obj(value)
      end
      if as_array.include?(elename.name)
        (vars[name] ||= []) << child
      else
        vars[name] = child
      end
    end
    Mapping.set_attributes(obj, vars)
  end

  def add_attributes2stubobj(node, obj)
    if attributes = schema_attribute_definition(obj.class)
      define_xmlattr(obj)
      attributes.each do |qname, class_name|
        attr = node.extraattr[qname]
        next if attr.nil? or attr.empty?
        klass = Mapping.class_from_name(class_name)
        if klass.ancestors.include?(::SOAP::SOAPBasetype)
          child = klass.new(attr).data
        else
          child = attr
        end
        obj.__xmlattr[qname] = child
        define_xmlattr_accessor(obj, qname)
      end
    end
  end

  def add_elements2plainobj(node, obj)
    node.each do |name, value|
      obj.__add_xmlele_value(value.elename, any2obj(value))
    end
  end

  def add_attributes2plainobj(node, obj)
    return if node.extraattr.empty?
    define_xmlattr(obj)
    node.extraattr.each do |qname, value|
      obj.__xmlattr[qname] = value
      define_xmlattr_accessor(obj, qname)
    end
  end

  if RUBY_VERSION > "1.7.0"
    def define_xmlattr_accessor(obj, qname)
      name = XSD::CodeGen::GenSupport.safemethodname(qname.name)
      Mapping.define_attr_accessor(obj, 'xmlattr_' + name,
        proc { @__xmlattr[qname] },
        proc { |value| @__xmlattr[qname] = value })
    end
  else
    def define_xmlattr_accessor(obj, qname)
      name = XSD::CodeGen::GenSupport.safemethodname(qname.name)
      obj.instance_eval <<-EOS
        def #{name}
          @__xmlattr[#{qname.dump}]
        end

        def #{name}=(value)
          @__xmlattr[#{qname.dump}] = value
        end
      EOS
    end
  end

  if RUBY_VERSION > "1.7.0"
    def define_xmlattr(obj)
      obj.instance_variable_set('@__xmlattr', {})
      unless obj.respond_to?(:__xmlattr)
        Mapping.define_attr_accessor(obj, :__xmlattr, proc { @__xmlattr })
      end
    end
  else
    def define_xmlattr(obj)
      obj.instance_variable_set('@__xmlattr', {})
      unless obj.respond_to?(:__xmlattr)
        obj.instance_eval <<-EOS
          def __xmlattr
            @__xmlattr
          end
        EOS
      end
    end
  end

  # it caches @@schema_element.  this means that @@schema_element must not be
  # changed while a lifetime of a WSDLLiteralRegistry.
  def schema_element_definition(klass)
    @schema_element_cache[klass] ||= Mapping.schema_element_definition(klass)
  end

  def schema_attribute_definition(klass)
    @schema_attribute_cache[klass] ||= Mapping.schema_attribute_definition(klass)
  end
end


end
end
PK     Z\\#  #    soap/mapping/factory.rbnu [        # SOAP4R - Mapping factory.
# Copyright (C) 2000, 2001, 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


module SOAP
module Mapping


class Factory
  include TraverseSupport

  def initialize
    # nothing to do
  end

  def obj2soap(soap_class, obj, info, map)
    raise NotImplementError.new
    # return soap_obj
  end

  def soap2obj(obj_class, node, info, map)
    raise NotImplementError.new
    # return convert_succeeded_or_not, obj
  end

  def setiv2obj(obj, node, map)
    return if node.nil?
    if obj.is_a?(Array)
      setiv2ary(obj, node, map)
    else
      setiv2struct(obj, node, map)
    end
  end

  def setiv2soap(node, obj, map)
    if obj.class.class_variables.include?('@@schema_element')
      obj.class.class_eval('@@schema_element').each do |name, info|
        type, qname = info
        if qname
          elename = qname.name
        else
          elename = Mapping.name2elename(name)
        end
        node.add(elename,
          Mapping._obj2soap(obj.instance_variable_get('@' + name), map))
      end
    else
      # should we sort instance_variables?
      obj.instance_variables.each do |var|
        name = var.sub(/^@/, '')
        elename = Mapping.name2elename(name)
        node.add(elename,
          Mapping._obj2soap(obj.instance_variable_get(var), map))
      end
    end
  end

private

  def setiv2ary(obj, node, map)
    node.each do |name, value|
      Array.instance_method(:<<).bind(obj).call(Mapping._soap2obj(value, map))
    end
  end

  def setiv2struct(obj, node, map)
    vars = {}
    node.each do |name, value|
      vars[Mapping.elename2name(name)] = Mapping._soap2obj(value, map)
    end
    Mapping.set_attributes(obj, vars)
  end
end

class StringFactory_ < Factory
  def initialize(allow_original_mapping = false)
    super()
    @allow_original_mapping = allow_original_mapping
  end

  def obj2soap(soap_class, obj, info, map)
    if !@allow_original_mapping and !obj.instance_variables.empty?
      return nil
    end
    begin
      unless XSD::Charset.is_ces(obj, Thread.current[:SOAPExternalCES])
        return nil
      end
      encoded = XSD::Charset.encoding_conv(obj,
        Thread.current[:SOAPExternalCES], XSD::Charset.encoding)
      soap_obj = soap_class.new(encoded)
    rescue XSD::ValueSpaceError
      return nil
    end
    mark_marshalled_obj(obj, soap_obj)
    soap_obj
  end

  def soap2obj(obj_class, node, info, map)
    obj = Mapping.create_empty_object(obj_class)
    decoded = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding,
      Thread.current[:SOAPExternalCES])
    obj.replace(decoded)
    mark_unmarshalled_obj(node, obj)
    return true, obj
  end
end

class BasetypeFactory_ < Factory
  def initialize(allow_original_mapping = false)
    super()
    @allow_original_mapping = allow_original_mapping
  end

  def obj2soap(soap_class, obj, info, map)
    if !@allow_original_mapping and !obj.instance_variables.empty?
      return nil
    end
    soap_obj = nil
    begin
      soap_obj = soap_class.new(obj)
    rescue XSD::ValueSpaceError
      return nil
    end
    if @allow_original_mapping
      # Basetype except String should not be multiref-ed in SOAP/1.1.
      mark_marshalled_obj(obj, soap_obj)
    end
    soap_obj
  end

  def soap2obj(obj_class, node, info, map)
    obj = node.data
    mark_unmarshalled_obj(node, obj)
    return true, obj
  end
end

class DateTimeFactory_ < Factory
  def initialize(allow_original_mapping = false)
    super()
    @allow_original_mapping = allow_original_mapping
  end

  def obj2soap(soap_class, obj, info, map)
    if !@allow_original_mapping and
	Time === obj and !obj.instance_variables.empty?
      return nil
    end
    soap_obj = nil
    begin
      soap_obj = soap_class.new(obj)
    rescue XSD::ValueSpaceError
      return nil
    end
    mark_marshalled_obj(obj, soap_obj)
    soap_obj
  end

  def soap2obj(obj_class, node, info, map)
    if node.respond_to?(:to_obj)
      obj = node.to_obj(obj_class)
      return false if obj.nil?
      mark_unmarshalled_obj(node, obj)
      return true, obj
    else
      return false
    end
  end
end

class Base64Factory_ < Factory
  def obj2soap(soap_class, obj, info, map)
    return nil unless obj.instance_variables.empty?
    soap_obj = soap_class.new(obj)
    mark_marshalled_obj(obj, soap_obj) if soap_obj
    soap_obj
  end

  def soap2obj(obj_class, node, info, map)
    obj = node.string
    mark_unmarshalled_obj(node, obj)
    return true, obj
  end
end

class URIFactory_ < Factory
  def obj2soap(soap_class, obj, info, map)
    soap_obj = soap_class.new(obj)
    mark_marshalled_obj(obj, soap_obj) if soap_obj
    soap_obj
  end

  def soap2obj(obj_class, node, info, map)
    obj = node.data
    mark_unmarshalled_obj(node, obj)
    return true, obj
  end
end

class ArrayFactory_ < Factory
  def initialize(allow_original_mapping = false)
    super()
    @allow_original_mapping = allow_original_mapping
  end

  # [[1], [2]] is converted to Array of Array, not 2-D Array.
  # To create M-D Array, you must call Mapping.ary2md.
  def obj2soap(soap_class, obj, info, map)
    if !@allow_original_mapping and !obj.instance_variables.empty?
      return nil
    end
    arytype = Mapping.obj2element(obj)
    if arytype.name
      arytype.namespace ||= RubyTypeNamespace
    else
      arytype = XSD::AnyTypeName
    end
    soap_obj = SOAPArray.new(ValueArrayName, 1, arytype)
    mark_marshalled_obj(obj, soap_obj)
    obj.each do |item|
      soap_obj.add(Mapping._obj2soap(item, map))
    end
    soap_obj
  end

  def soap2obj(obj_class, node, info, map)
    obj = Mapping.create_empty_object(obj_class)
    mark_unmarshalled_obj(node, obj)
    node.soap2array(obj) do |elem|
      elem ? Mapping._soap2obj(elem, map) : nil
    end
    return true, obj
  end
end

class TypedArrayFactory_ < Factory
  def initialize(allow_original_mapping = false)
    super()
    @allow_original_mapping = allow_original_mapping
  end

  def obj2soap(soap_class, obj, info, map)
    if !@allow_original_mapping and !obj.instance_variables.empty?
      return nil
    end
    arytype = info[:type] || info[0]
    soap_obj = SOAPArray.new(ValueArrayName, 1, arytype)
    mark_marshalled_obj(obj, soap_obj)
    obj.each do |var|
      soap_obj.add(Mapping._obj2soap(var, map))
    end
    soap_obj
  end

  def soap2obj(obj_class, node, info, map)
    if node.rank > 1
      return false
    end
    arytype = info[:type] || info[0]
    unless node.arytype == arytype
      return false
    end
    obj = Mapping.create_empty_object(obj_class)
    mark_unmarshalled_obj(node, obj)
    node.soap2array(obj) do |elem|
      elem ? Mapping._soap2obj(elem, map) : nil
    end
    return true, obj
  end
end

class TypedStructFactory_ < Factory
  def obj2soap(soap_class, obj, info, map)
    type = info[:type] || info[0]
    soap_obj = soap_class.new(type)
    mark_marshalled_obj(obj, soap_obj)
    if obj.class <= SOAP::Marshallable
      setiv2soap(soap_obj, obj, map)
    else
      setiv2soap(soap_obj, obj, map)
    end
    soap_obj
  end

  def soap2obj(obj_class, node, info, map)
    type = info[:type] || info[0]
    unless node.type == type
      return false
    end
    obj = Mapping.create_empty_object(obj_class)
    mark_unmarshalled_obj(node, obj)
    setiv2obj(obj, node, map)
    return true, obj
  end
end

MapQName = XSD::QName.new(ApacheSOAPTypeNamespace, 'Map')
class HashFactory_ < Factory
  def initialize(allow_original_mapping = false)
    super()
    @allow_original_mapping = allow_original_mapping
  end

  def obj2soap(soap_class, obj, info, map)
    if !@allow_original_mapping and !obj.instance_variables.empty?
      return nil
    end
    if !obj.default.nil? or
	(obj.respond_to?(:default_proc) and obj.default_proc)
      return nil
    end
    soap_obj = SOAPStruct.new(MapQName)
    mark_marshalled_obj(obj, soap_obj)
    obj.each do |key, value|
      elem = SOAPStruct.new
      elem.add("key", Mapping._obj2soap(key, map))
      elem.add("value", Mapping._obj2soap(value, map))
      # ApacheAxis allows only 'item' here.
      soap_obj.add("item", elem)
    end
    soap_obj
  end

  def soap2obj(obj_class, node, info, map)
    unless node.type == MapQName
      return false
    end
    if node.class == SOAPStruct and node.key?('default')
      return false
    end
    obj = Mapping.create_empty_object(obj_class)
    mark_unmarshalled_obj(node, obj)
    if node.class == SOAPStruct
      node.each do |key, value|
	obj[Mapping._soap2obj(value['key'], map)] =
	  Mapping._soap2obj(value['value'], map)
      end
    else
      node.each do |value|
	obj[Mapping._soap2obj(value['key'], map)] =
	  Mapping._soap2obj(value['value'], map)
      end
    end
    return true, obj
  end
end


end
end
PK     Z\.C-      soap/mapping/typeMap.rbnu [        # SOAP4R - Base type mapping definition
# Copyright (C) 2000, 2001, 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


module SOAP


TypeMap = {
  XSD::XSDAnySimpleType::Type => SOAPAnySimpleType,
  XSD::XSDString::Type => SOAPString,
  XSD::XSDBoolean::Type => SOAPBoolean,
  XSD::XSDDecimal::Type => SOAPDecimal,
  XSD::XSDFloat::Type => SOAPFloat,
  XSD::XSDDouble::Type => SOAPDouble,
  XSD::XSDDuration::Type => SOAPDuration,
  XSD::XSDDateTime::Type => SOAPDateTime,
  XSD::XSDTime::Type => SOAPTime,
  XSD::XSDDate::Type => SOAPDate,
  XSD::XSDGYearMonth::Type => SOAPGYearMonth,
  XSD::XSDGYear::Type => SOAPGYear,
  XSD::XSDGMonthDay::Type => SOAPGMonthDay,
  XSD::XSDGDay::Type => SOAPGDay,
  XSD::XSDGMonth::Type => SOAPGMonth,
  XSD::XSDHexBinary::Type => SOAPHexBinary,
  XSD::XSDBase64Binary::Type => SOAPBase64,
  XSD::XSDAnyURI::Type => SOAPAnyURI,
  XSD::XSDQName::Type => SOAPQName,
  XSD::XSDInteger::Type => SOAPInteger,
  XSD::XSDNonPositiveInteger::Type => SOAPNonPositiveInteger,
  XSD::XSDNegativeInteger::Type => SOAPNegativeInteger,
  XSD::XSDLong::Type => SOAPLong,
  XSD::XSDInt::Type => SOAPInt,
  XSD::XSDShort::Type => SOAPShort,
  XSD::XSDByte::Type => SOAPByte,
  XSD::XSDNonNegativeInteger::Type => SOAPNonNegativeInteger,
  XSD::XSDUnsignedLong::Type => SOAPUnsignedLong,
  XSD::XSDUnsignedInt::Type => SOAPUnsignedInt,
  XSD::XSDUnsignedShort::Type => SOAPUnsignedShort,
  XSD::XSDUnsignedByte::Type => SOAPUnsignedByte,
  XSD::XSDPositiveInteger::Type => SOAPPositiveInteger,

  SOAP::SOAPBase64::Type => SOAPBase64,
}


end
PK     Z\X&+  +    soap/mapping/mapping.rbnu [        # SOAP4R - Ruby type mapping utility.
# Copyright (C) 2000, 2001, 2003-2005  NAKAMURA Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/codegen/gensupport'


module SOAP


module Mapping
  RubyTypeNamespace = 'http://www.ruby-lang.org/xmlns/ruby/type/1.6'
  RubyTypeInstanceNamespace =
    'http://www.ruby-lang.org/xmlns/ruby/type-instance'
  RubyCustomTypeNamespace = 'http://www.ruby-lang.org/xmlns/ruby/type/custom'
  ApacheSOAPTypeNamespace = 'http://xml.apache.org/xml-soap'


  # TraverseSupport breaks following thread variables.
  #   Thread.current[:SOAPMarshalDataKey]
  module TraverseSupport
    def mark_marshalled_obj(obj, soap_obj)
      raise if obj.nil?
      Thread.current[:SOAPMarshalDataKey][obj.__id__] = soap_obj
    end

    def mark_unmarshalled_obj(node, obj)
      return if obj.nil?
      # node.id is not Object#id but SOAPReference#id
      Thread.current[:SOAPMarshalDataKey][node.id] = obj
    end
  end


  EMPTY_OPT = {}
  def self.obj2soap(obj, registry = nil, type = nil, opt = EMPTY_OPT)
    registry ||= Mapping::DefaultRegistry
    soap_obj = nil
    protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do
      Thread.current[:SOAPMarshalDataKey] = {}
      Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE
      Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]
      soap_obj = _obj2soap(obj, registry, type)
    end
    soap_obj
  end

  def self.soap2obj(node, registry = nil, klass = nil, opt = EMPTY_OPT)
    registry ||= Mapping::DefaultRegistry
    obj = nil
    protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do
      Thread.current[:SOAPMarshalDataKey] = {}
      Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE
      Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]
      obj = _soap2obj(node, registry, klass)
    end
    obj
  end

  def self.ary2soap(ary, type_ns = XSD::Namespace, typename = XSD::AnyTypeLiteral, registry = nil, opt = EMPTY_OPT)
    registry ||= Mapping::DefaultRegistry
    type = XSD::QName.new(type_ns, typename)
    soap_ary = SOAPArray.new(ValueArrayName, 1, type)
    protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do
      Thread.current[:SOAPMarshalDataKey] = {}
      Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE
      Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]
      ary.each do |ele|
        soap_ary.add(_obj2soap(ele, registry, type))
      end
    end
    soap_ary
  end

  def self.ary2md(ary, rank, type_ns = XSD::Namespace, typename = XSD::AnyTypeLiteral, registry = nil, opt = EMPTY_OPT)
    registry ||= Mapping::DefaultRegistry
    type = XSD::QName.new(type_ns, typename)
    md_ary = SOAPArray.new(ValueArrayName, rank, type)
    protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do
      Thread.current[:SOAPMarshalDataKey] = {}
      Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE
      Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]
      add_md_ary(md_ary, ary, [], registry)
    end
    md_ary
  end

  def self.fault2exception(fault, registry = nil)
    registry ||= Mapping::DefaultRegistry
    detail = if fault.detail
        soap2obj(fault.detail, registry) || ""
      else
        ""
      end
    if detail.is_a?(Mapping::SOAPException)
      begin
        e = detail.to_e
	remote_backtrace = e.backtrace
        e.set_backtrace(nil)
        raise e # ruby sets current caller as local backtrace of e => e2.
      rescue Exception => e
	e.set_backtrace(remote_backtrace + e.backtrace[1..-1])
        raise
      end
    else
      fault.detail = detail
      fault.set_backtrace(
        if detail.is_a?(Array)
	  detail
        else
          [detail.to_s]
        end
      )
      raise
    end
  end

  def self._obj2soap(obj, registry, type = nil)
    if referent = Thread.current[:SOAPMarshalDataKey][obj.__id__] and
        !Thread.current[:SOAPMarshalNoReference]
      SOAPReference.new(referent)
    elsif registry
      registry.obj2soap(obj, type)
    else
      raise MappingError.new("no mapping registry given")
    end
  end

  def self._soap2obj(node, registry, klass = nil)
    if node.nil?
      return nil
    elsif node.is_a?(SOAPReference)
      target = node.__getobj__
      # target.id is not Object#id but SOAPReference#id
      if referent = Thread.current[:SOAPMarshalDataKey][target.id] and
          !Thread.current[:SOAPMarshalNoReference]
        return referent
      else
        return _soap2obj(target, registry, klass)
      end
    end
    return registry.soap2obj(node, klass)
  end

  if Object.respond_to?(:allocate)
    # ruby/1.7 or later.
    def self.create_empty_object(klass)
      klass.allocate
    end
  else
    MARSHAL_TAG = {
      String => ['"', 1],
      Regexp => ['/', 2],
      Array => ['[', 1],
      Hash => ['{', 1]
    }
    def self.create_empty_object(klass)
      if klass <= Struct
	name = klass.name
	return ::Marshal.load(sprintf("\004\006S:%c%s\000", name.length + 5, name))
      end
      if MARSHAL_TAG.has_key?(klass)
	tag, terminate = MARSHAL_TAG[klass]
	return ::Marshal.load(sprintf("\004\006%s%s", tag, "\000" * terminate))
      end
      MARSHAL_TAG.each do |k, v|
	if klass < k
	  name = klass.name
	  tag, terminate = v
	  return ::Marshal.load(sprintf("\004\006C:%c%s%s%s", name.length + 5, name, tag, "\000" * terminate))
	end
      end
      name = klass.name
      ::Marshal.load(sprintf("\004\006o:%c%s\000", name.length + 5, name))
    end
  end

  # Allow only (Letter | '_') (Letter | Digit | '-' | '_')* here.
  # Caution: '.' is not allowed here.
  # To follow XML spec., it should be NCName.
  #   (denied chars) => .[0-F][0-F]
  #   ex. a.b => a.2eb
  #
  def self.name2elename(name)
    name.gsub(/([^a-zA-Z0-9:_\-]+)/n) {
      '.' << $1.unpack('H2' * $1.size).join('.')
    }.gsub(/::/n, '..')
  end

  def self.elename2name(name)
    name.gsub(/\.\./n, '::').gsub(/((?:\.[0-9a-fA-F]{2})+)/n) {
      [$1.delete('.')].pack('H*')
    }
  end

  def self.const_from_name(name, lenient = false)
    const = ::Object
    name.sub(/\A::/, '').split('::').each do |const_str|
      if XSD::CodeGen::GenSupport.safeconstname?(const_str)
        if const.const_defined?(const_str)
          const = const.const_get(const_str)
          next
        end
      elsif lenient
        const_str = XSD::CodeGen::GenSupport.safeconstname(const_str)
        if const.const_defined?(const_str)
          const = const.const_get(const_str)
          next
        end
      end
      return nil
    end
    const
  end

  def self.class_from_name(name, lenient = false)
    const = const_from_name(name, lenient)
    if const.is_a?(::Class)
      const
    else
      nil
    end
  end

  def self.module_from_name(name, lenient = false)
    const = const_from_name(name, lenient)
    if const.is_a?(::Module)
      const
    else
      nil
    end
  end

  def self.class2qname(klass)
    name = schema_type_definition(klass)
    namespace = schema_ns_definition(klass)
    XSD::QName.new(namespace, name)
  end

  def self.class2element(klass)
    type = Mapping.class2qname(klass)
    type.name ||= Mapping.name2elename(klass.name)
    type.namespace ||= RubyCustomTypeNamespace
    type
  end

  def self.obj2element(obj)
    name = namespace = nil
    ivars = obj.instance_variables
    if ivars.include?('@schema_type')
      name = obj.instance_variable_get('@schema_type')
    end
    if ivars.include?('@schema_ns')
      namespace = obj.instance_variable_get('@schema_ns')
    end
    if !name or !namespace
      class2qname(obj.class)
    else
      XSD::QName.new(namespace, name)
    end
  end

  def self.define_singleton_method(obj, name, &block)
    sclass = (class << obj; self; end)
    sclass.class_eval {
      define_method(name, &block)
    }
  end

  def self.get_attribute(obj, attr_name)
    if obj.is_a?(::Hash)
      obj[attr_name] || obj[attr_name.intern]
    else
      name = XSD::CodeGen::GenSupport.safevarname(attr_name)
      if obj.instance_variables.include?('@' + name)
        obj.instance_variable_get('@' + name)
      elsif ((obj.is_a?(::Struct) or obj.is_a?(Marshallable)) and
          obj.respond_to?(name))
        obj.__send__(name)
      end
    end
  end

  def self.set_attributes(obj, values)
    if obj.is_a?(::SOAP::Mapping::Object)
      values.each do |attr_name, value|
        obj.__add_xmlele_value(attr_name, value)
      end
    else
      values.each do |attr_name, value|
        name = XSD::CodeGen::GenSupport.safevarname(attr_name)
        setter = name + "="
        if obj.respond_to?(setter)
          obj.__send__(setter, value)
        else
          obj.instance_variable_set('@' + name, value)
          begin
            define_attr_accessor(obj, name,
              proc { instance_variable_get('@' + name) },
              proc { |value| instance_variable_set('@' + name, value) })
          rescue TypeError
            # singleton class may not exist (e.g. Float)
          end
        end
      end
    end
  end

  def self.define_attr_accessor(obj, name, getterproc, setterproc = nil)
    define_singleton_method(obj, name, &getterproc)
    define_singleton_method(obj, name + '=', &setterproc) if setterproc
  end

  def self.schema_type_definition(klass)
    class_schema_variable(:schema_type, klass)
  end

  def self.schema_ns_definition(klass)
    class_schema_variable(:schema_ns, klass)
  end

  def self.schema_element_definition(klass)
    schema_element = class_schema_variable(:schema_element, klass) or return nil
    schema_ns = schema_ns_definition(klass)
    elements = []
    as_array = []
    schema_element.each do |varname, definition|
      class_name, name = definition
      if /\[\]$/ =~ class_name
        class_name = class_name.sub(/\[\]$/, '')
        as_array << (name ? name.name : varname)
      end
      elements << [name || XSD::QName.new(schema_ns, varname), class_name]
    end
    [elements, as_array]
  end

  def self.schema_attribute_definition(klass)
    class_schema_variable(:schema_attribute, klass)
  end

  class << Mapping
  private

    def class_schema_variable(sym, klass)
      var = "@@#{sym}"
      klass.class_variables.include?(var) ? klass.class_eval(var) : nil
    end

    def protect_threadvars(*symbols)
      backup = {}
      begin
        symbols.each do |sym|
          backup[sym] = Thread.current[sym]
        end
        yield
      ensure
        symbols.each do |sym|
          Thread.current[sym] = backup[sym]
        end
      end
    end

    def add_md_ary(md_ary, ary, indices, registry)
      for idx in 0..(ary.size - 1)
        if ary[idx].is_a?(Array)
          add_md_ary(md_ary, ary[idx], indices + [idx], registry)
        else
          md_ary[*(indices + [idx])] = _obj2soap(ary[idx], registry)
        end
      end
    end
  end
end


end
PK     Z\ue,  ,  #  soap/mapping/wsdlencodedregistry.rbnu [        # SOAP4R - WSDL encoded mapping registry.
# Copyright (C) 2000-2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/qname'
require 'xsd/namedelements'
require 'soap/baseData'
require 'soap/mapping/mapping'
require 'soap/mapping/typeMap'


module SOAP
module Mapping


class WSDLEncodedRegistry < Registry
  include TraverseSupport

  attr_reader :definedelements
  attr_reader :definedtypes
  attr_accessor :excn_handler_obj2soap
  attr_accessor :excn_handler_soap2obj

  def initialize(definedtypes = XSD::NamedElements::Empty)
    @definedtypes = definedtypes
    # @definedelements = definedelements  needed?
    @excn_handler_obj2soap = nil
    @excn_handler_soap2obj = nil
    # For mapping AnyType element.
    @rubytype_factory = RubytypeFactory.new(
      :allow_untyped_struct => true,
      :allow_original_mapping => true
    )
    @schema_element_cache = {}
  end

  def obj2soap(obj, qname = nil)
    soap_obj = nil
    if type = @definedtypes[qname]
      soap_obj = obj2typesoap(obj, type)
    else
      soap_obj = any2soap(obj, qname)
    end
    return soap_obj if soap_obj
    if @excn_handler_obj2soap
      soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj|
        Mapping._obj2soap(yield_obj, self)
      }
      return soap_obj if soap_obj
    end
    if qname
      raise MappingError.new("cannot map #{obj.class.name} as #{qname}")
    else
      raise MappingError.new("cannot map #{obj.class.name} to SOAP/OM")
    end
  end

  # map anything for now: must refer WSDL while mapping.  [ToDo]
  def soap2obj(node, obj_class = nil)
    begin
      return any2obj(node, obj_class)
    rescue MappingError
    end
    if @excn_handler_soap2obj
      begin
        return @excn_handler_soap2obj.call(node) { |yield_node|
	    Mapping._soap2obj(yield_node, self)
	  }
      rescue Exception
      end
    end
    raise MappingError.new("cannot map #{node.type.name} to Ruby object")
  end

private

  def any2soap(obj, qname)
    if obj.nil?
      SOAPNil.new
    elsif qname.nil? or qname == XSD::AnyTypeName
      @rubytype_factory.obj2soap(nil, obj, nil, self)
    elsif obj.is_a?(XSD::NSDBase)
      soap2soap(obj, qname)
    elsif (type = TypeMap[qname])
      base2soap(obj, type)
    else
      nil
    end
  end

  def soap2soap(obj, type_qname)
    if obj.is_a?(SOAPBasetype)
      obj
    elsif obj.is_a?(SOAPStruct) && (type = @definedtypes[type_qname])
      soap_obj = obj
      mark_marshalled_obj(obj, soap_obj)
      elements2soap(obj, soap_obj, type.content.elements)
      soap_obj
    elsif obj.is_a?(SOAPArray) && (type = @definedtypes[type_qname])
      soap_obj = obj
      contenttype = type.child_type
      mark_marshalled_obj(obj, soap_obj)
      obj.replace do |ele|
	Mapping._obj2soap(ele, self, contenttype)
      end
      soap_obj
    else
      nil
    end
  end

  def obj2typesoap(obj, type)
    if type.is_a?(::WSDL::XMLSchema::SimpleType)
      simpleobj2soap(obj, type)
    else
      complexobj2soap(obj, type)
    end
  end

  def simpleobj2soap(obj, type)
    type.check_lexical_format(obj)
    return SOAPNil.new if obj.nil?      # ToDo: check nillable.
    o = base2soap(obj, TypeMap[type.base])
    o
  end

  def complexobj2soap(obj, type)
    case type.compoundtype
    when :TYPE_STRUCT
      struct2soap(obj, type.name, type)
    when :TYPE_ARRAY
      array2soap(obj, type.name, type)
    when :TYPE_MAP
      map2soap(obj, type.name, type)
    when :TYPE_SIMPLE
      simpleobj2soap(obj, type.simplecontent)
    when :TYPE_EMPTY
      raise MappingError.new("should be empty") unless obj.nil?
      SOAPNil.new
    else
      raise MappingError.new("unknown compound type: #{type.compoundtype}")
    end
  end

  def base2soap(obj, type)
    soap_obj = nil
    if type <= XSD::XSDString
      str = XSD::Charset.encoding_conv(obj.to_s,
        Thread.current[:SOAPExternalCES], XSD::Charset.encoding)
      soap_obj = type.new(str)
      mark_marshalled_obj(obj, soap_obj)
    else
      soap_obj = type.new(obj)
    end
    soap_obj
  end

  def struct2soap(obj, type_qname, type)
    return SOAPNil.new if obj.nil?      # ToDo: check nillable.
    soap_obj = SOAPStruct.new(type_qname)
    unless obj.nil?
      mark_marshalled_obj(obj, soap_obj)
      elements2soap(obj, soap_obj, type.content.elements)
    end
    soap_obj
  end

  def array2soap(obj, type_qname, type)
    return SOAPNil.new if obj.nil?      # ToDo: check nillable.
    arytype = type.child_type
    soap_obj = SOAPArray.new(ValueArrayName, 1, arytype)
    unless obj.nil?
      mark_marshalled_obj(obj, soap_obj)
      obj.each do |item|
        soap_obj.add(Mapping._obj2soap(item, self, arytype))
      end
    end
    soap_obj
  end

  MapKeyName = XSD::QName.new(nil, "key")
  MapValueName = XSD::QName.new(nil, "value")
  def map2soap(obj, type_qname, type)
    return SOAPNil.new if obj.nil?      # ToDo: check nillable.
    keytype = type.child_type(MapKeyName) || XSD::AnyTypeName
    valuetype = type.child_type(MapValueName) || XSD::AnyTypeName
    soap_obj = SOAPStruct.new(MapQName)
    unless obj.nil?
      mark_marshalled_obj(obj, soap_obj)
      obj.each do |key, value|
        elem = SOAPStruct.new
        elem.add("key", Mapping._obj2soap(key, self, keytype))
        elem.add("value", Mapping._obj2soap(value, self, valuetype))
        # ApacheAxis allows only 'item' here.
        soap_obj.add("item", elem)
      end
    end
    soap_obj
  end

  def elements2soap(obj, soap_obj, elements)
    elements.each do |element|
      name = element.name.name
      child_obj = Mapping.get_attribute(obj, name)
      soap_obj.add(name,
        Mapping._obj2soap(child_obj, self, element.type || element.name))
    end
  end

  def any2obj(node, obj_class)
    unless obj_class
      typestr = XSD::CodeGen::GenSupport.safeconstname(node.elename.name)
      obj_class = Mapping.class_from_name(typestr)
    end
    if obj_class and obj_class.class_variables.include?('@@schema_element')
      soap2stubobj(node, obj_class)
    else
      Mapping._soap2obj(node, Mapping::DefaultRegistry, obj_class)
    end
  end

  def soap2stubobj(node, obj_class)
    obj = Mapping.create_empty_object(obj_class)
    unless node.is_a?(SOAPNil)
      add_elements2stubobj(node, obj)
    end
    obj
  end

  def add_elements2stubobj(node, obj)
    elements, as_array = schema_element_definition(obj.class)
    vars = {}
    node.each do |name, value|
      item = elements.find { |k, v| k.name == name }
      if item
        elename, class_name = item
        if klass = Mapping.class_from_name(class_name)
          # klass must be a SOAPBasetype or a class
          if klass.ancestors.include?(::SOAP::SOAPBasetype)
            if value.respond_to?(:data)
              child = klass.new(value.data).data
            else
              child = klass.new(nil).data
            end
          else
            child = Mapping._soap2obj(value, self, klass)
          end
        elsif klass = Mapping.module_from_name(class_name)
          # simpletype
          if value.respond_to?(:data)
            child = value.data
          else
            raise MappingError.new(
              "cannot map to a module value: #{class_name}")
          end
        else
          raise MappingError.new("unknown class: #{class_name}")
        end
      else      # untyped element is treated as anyType.
        child = Mapping._soap2obj(value, self)
      end
      vars[name] = child
    end
    Mapping.set_attributes(obj, vars)
  end

  # it caches @@schema_element.  this means that @@schema_element must not be
  # changed while a lifetime of a WSDLLiteralRegistry.
  def schema_element_definition(klass)
    @schema_element_cache[klass] ||= Mapping.schema_element_definition(klass)
  end
end


end
end
PK     Z\.4!  !    soap/parser.rbnu [        # SOAP4R - SOAP XML Instance Parser library.
# Copyright (C) 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/ns'
require 'xsd/xmlparser'
require 'soap/soap'
require 'soap/baseData'
require 'soap/encodingstyle/handler'


module SOAP


class Parser
  include SOAP

  class ParseError < Error; end
  class FormatDecodeError < ParseError; end
  class UnexpectedElementError < ParseError; end

private

  class ParseFrame
    attr_reader :node
    attr_reader :name
    attr_reader :ns, :encodingstyle

    class NodeContainer
      def initialize(node)
	@node = node
      end

      def node
	@node
      end

      def replace_node(node)
	@node = node
      end
    end

  public

    def initialize(ns, name, node, encodingstyle)
      @ns = ns
      @name = name
      self.node = node
      @encodingstyle = encodingstyle
    end

    def node=(node)
      @node = NodeContainer.new(node)
    end
  end

public

  attr_accessor :envelopenamespace
  attr_accessor :default_encodingstyle
  attr_accessor :decode_typemap
  attr_accessor :allow_unqualified_element

  def initialize(opt = {})
    @opt = opt
    @parser = XSD::XMLParser.create_parser(self, opt)
    @parsestack = nil
    @lastnode = nil
    @handlers = {}
    @envelopenamespace = opt[:envelopenamespace] || EnvelopeNamespace
    @default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace
    @decode_typemap = opt[:decode_typemap] || nil
    @allow_unqualified_element = opt[:allow_unqualified_element] || false
  end

  def charset
    @parser.charset
  end

  def parse(string_or_readable)
    @parsestack = []
    @lastnode = nil

    @handlers.each do |uri, handler|
      handler.decode_prologue
    end

    @parser.do_parse(string_or_readable)

    unless @parsestack.empty?
      raise FormatDecodeError.new("Unbalanced tag in XML.")
    end

    @handlers.each do |uri, handler|
      handler.decode_epilogue
    end

    @lastnode
  end

  def start_element(name, attrs)
    lastframe = @parsestack.last
    ns = parent = parent_encodingstyle = nil
    if lastframe
      ns = lastframe.ns.clone_ns
      parent = lastframe.node
      parent_encodingstyle = lastframe.encodingstyle
    else
      ns = XSD::NS.new
      parent = ParseFrame::NodeContainer.new(nil)
      parent_encodingstyle = nil
    end

    attrs = XSD::XMLParser.filter_ns(ns, attrs)
    encodingstyle = find_encodingstyle(ns, attrs)

    # Children's encodingstyle is derived from its parent.
    if encodingstyle.nil?
      if parent.node.is_a?(SOAPHeader)
        encodingstyle = LiteralNamespace
      else
        encodingstyle = parent_encodingstyle || @default_encodingstyle
      end
    end

    node = decode_tag(ns, name, attrs, parent, encodingstyle)

    @parsestack << ParseFrame.new(ns, name, node, encodingstyle)
  end

  def characters(text)
    lastframe = @parsestack.last
    if lastframe
      # Need not to be cloned because character does not have attr.
      decode_text(lastframe.ns, text, lastframe.encodingstyle)
    else
      # Ignore Text outside of SOAP Envelope.
      p text if $DEBUG
    end
  end

  def end_element(name)
    lastframe = @parsestack.pop
    unless name == lastframe.name
      raise UnexpectedElementError.new("Closing element name '#{ name }' does not match with opening element '#{ lastframe.name }'.")
    end
    decode_tag_end(lastframe.ns, lastframe.node, lastframe.encodingstyle)
    @lastnode = lastframe.node.node
  end

private

  def find_encodingstyle(ns, attrs)
    attrs.each do |key, value|
      if (ns.compare(@envelopenamespace, AttrEncodingStyle, key))
	return value
      end
    end
    nil
  end

  def decode_tag(ns, name, attrs, parent, encodingstyle)
    ele = ns.parse(name)

    # Envelope based parsing.
    if ((ele.namespace == @envelopenamespace) ||
	(@allow_unqualified_element && ele.namespace.nil?))
      o = decode_soap_envelope(ns, ele, attrs, parent)
      return o if o
    end

    # Encoding based parsing.
    handler = find_handler(encodingstyle)
    if handler
      return handler.decode_tag(ns, ele, attrs, parent)
    else
      raise FormatDecodeError.new("Unknown encodingStyle: #{ encodingstyle }.")
    end
  end

  def decode_tag_end(ns, node, encodingstyle)
    return unless encodingstyle

    handler = find_handler(encodingstyle)
    if handler
      return handler.decode_tag_end(ns, node)
    else
      raise FormatDecodeError.new("Unknown encodingStyle: #{ encodingstyle }.")
    end
  end

  def decode_text(ns, text, encodingstyle)
    handler = find_handler(encodingstyle)

    if handler
      handler.decode_text(ns, text)
    else
      # How should I do?
    end
  end

  def decode_soap_envelope(ns, ele, attrs, parent)
    o = nil
    if ele.name == EleEnvelope
      o = SOAPEnvelope.new
      if ext = @opt[:external_content]
	ext.each do |k, v|
	  o.external_content[k] = v
	end
      end
    elsif ele.name == EleHeader
      unless parent.node.is_a?(SOAPEnvelope)
	raise FormatDecodeError.new("Header should be a child of Envelope.")
      end
      o = SOAPHeader.new
      parent.node.header = o
    elsif ele.name == EleBody
      unless parent.node.is_a?(SOAPEnvelope)
	raise FormatDecodeError.new("Body should be a child of Envelope.")
      end
      o = SOAPBody.new
      parent.node.body = o
    elsif ele.name == EleFault
      unless parent.node.is_a?(SOAPBody)
	raise FormatDecodeError.new("Fault should be a child of Body.")
      end
      o = SOAPFault.new
      parent.node.fault = o
    end
    o
  end

  def find_handler(encodingstyle)
    unless @handlers.key?(encodingstyle)
      handler_factory = SOAP::EncodingStyle::Handler.handler(encodingstyle) ||
	SOAP::EncodingStyle::Handler.handler(EncodingNamespace)
      handler = handler_factory.new(@parser.charset)
      handler.decode_typemap = @decode_typemap
      handler.decode_prologue
      @handlers[encodingstyle] = handler
    end
    @handlers[encodingstyle]
  end
end


end
PK     Z\^?  ?    soap/wsdlDriver.rbnu [        # SOAP4R - SOAP WSDL driver
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'wsdl/parser'
require 'wsdl/importer'
require 'xsd/qname'
require 'xsd/codegen/gensupport'
require 'soap/mapping/wsdlencodedregistry'
require 'soap/mapping/wsdlliteralregistry'
require 'soap/rpc/driver'
require 'wsdl/soap/methodDefCreator'


module SOAP


class WSDLDriverFactory
  class FactoryError < StandardError; end

  attr_reader :wsdl

  def initialize(wsdl)
    @wsdl = import(wsdl)
    @methoddefcreator = WSDL::SOAP::MethodDefCreator.new(@wsdl)
  end
  
  def inspect
    "#<#{self.class}:#{@wsdl.name}>"
  end

  def create_rpc_driver(servicename = nil, portname = nil)
    port = find_port(servicename, portname)
    drv = SOAP::RPC::Driver.new(port.soap_address.location)
    init_driver(drv, port)
    add_operation(drv, port)
    drv
  end

  # depricated old interface
  def create_driver(servicename = nil, portname = nil)
    warn("WSDLDriverFactory#create_driver is depricated.  Use create_rpc_driver instead.")
    port = find_port(servicename, portname)
    WSDLDriver.new(@wsdl, port, nil)
  end

  # Backward compatibility.
  alias createDriver create_driver

private

  def find_port(servicename = nil, portname = nil)
    service = port = nil
    if servicename
      service = @wsdl.service(
        XSD::QName.new(@wsdl.targetnamespace, servicename))
    else
      service = @wsdl.services[0]
    end
    if service.nil?
      raise FactoryError.new("service #{servicename} not found in WSDL")
    end
    if portname
      port = service.ports[XSD::QName.new(@wsdl.targetnamespace, portname)]
      if port.nil?
        raise FactoryError.new("port #{portname} not found in WSDL")
      end
    else
      port = service.ports.find { |port| !port.soap_address.nil? }
      if port.nil?
        raise FactoryError.new("no ports have soap:address")
      end
    end
    if port.soap_address.nil?
      raise FactoryError.new("soap:address element not found in WSDL")
    end
    port
  end

  def init_driver(drv, port)
    wsdl_elements = @wsdl.collect_elements
    wsdl_types = @wsdl.collect_complextypes + @wsdl.collect_simpletypes
    rpc_decode_typemap = wsdl_types +
      @wsdl.soap_rpc_complextypes(port.find_binding)
    drv.proxy.mapping_registry =
      Mapping::WSDLEncodedRegistry.new(rpc_decode_typemap)
    drv.proxy.literal_mapping_registry =
      Mapping::WSDLLiteralRegistry.new(wsdl_types, wsdl_elements)
  end

  def add_operation(drv, port)
    port.find_binding.operations.each do |op_bind|
      op_name = op_bind.soapoperation_name
      soapaction = op_bind.soapaction || ''
      orgname = op_name.name
      name = XSD::CodeGen::GenSupport.safemethodname(orgname)
      param_def = create_param_def(op_bind)
      opt = {
        :request_style => op_bind.soapoperation_style,
        :response_style => op_bind.soapoperation_style,
        :request_use => op_bind.input.soapbody_use,
        :response_use => op_bind.output.soapbody_use,
        :elementformdefault => false,
        :attributeformdefault => false
      }
      if op_bind.soapoperation_style == :rpc
        drv.add_rpc_operation(op_name, soapaction, name, param_def, opt)
      else
        drv.add_document_operation(soapaction, name, param_def, opt)
      end
      if orgname != name and orgname.capitalize == name.capitalize
        ::SOAP::Mapping.define_singleton_method(drv, orgname) do |*arg|
          __send__(name, *arg)
        end
      end
    end
  end

  def import(location)
    WSDL::Importer.import(location)
  end

  def create_param_def(op_bind)
    op = op_bind.find_operation
    if op_bind.soapoperation_style == :rpc
      param_def = @methoddefcreator.collect_rpcparameter(op)
    else
      param_def = @methoddefcreator.collect_documentparameter(op)
    end
    # the first element of typedef in param_def is a String like
    # "::SOAP::SOAPStruct".  turn this String to a class.
    param_def.collect { |io, name, typedef|
      typedef[0] = Mapping.class_from_name(typedef[0])
      [io, name, typedef]
    }
  end

  def partqname(part)
    if part.type
      part.type
    else
      part.element
    end
  end

  def param_def(type, name, klass, partqname)
    [type, name, [klass, partqname.namespace, partqname.name]]
  end

  def filter_parts(partsdef, partssource)
    parts = partsdef.split(/\s+/)
    partssource.find_all { |part| parts.include?(part.name) }
  end
end


class WSDLDriver
  class << self
    if RUBY_VERSION >= "1.7.0"
      def __attr_proxy(symbol, assignable = false)
        name = symbol.to_s
        define_method(name) {
          @servant.__send__(name)
        }
        if assignable
          aname = name + '='
          define_method(aname) { |rhs|
            @servant.__send__(aname, rhs)
          }
        end
      end
    else
      def __attr_proxy(symbol, assignable = false)
        name = symbol.to_s
        module_eval <<-EOS
          def #{name}
            @servant.#{name}
          end
        EOS
        if assignable
          module_eval <<-EOS
            def #{name}=(value)
              @servant.#{name} = value
            end
          EOS
        end
      end
    end
  end

  __attr_proxy :options
  __attr_proxy :headerhandler
  __attr_proxy :streamhandler
  __attr_proxy :test_loopback_response
  __attr_proxy :endpoint_url, true
  __attr_proxy :mapping_registry, true		# for RPC unmarshal
  __attr_proxy :wsdl_mapping_registry, true	# for RPC marshal
  __attr_proxy :default_encodingstyle, true
  __attr_proxy :generate_explicit_type, true
  __attr_proxy :allow_unqualified_element, true

  def httpproxy
    @servant.options["protocol.http.proxy"]
  end

  def httpproxy=(httpproxy)
    @servant.options["protocol.http.proxy"] = httpproxy
  end

  def wiredump_dev
    @servant.options["protocol.http.wiredump_dev"]
  end

  def wiredump_dev=(wiredump_dev)
    @servant.options["protocol.http.wiredump_dev"] = wiredump_dev
  end

  def mandatorycharset
    @servant.options["protocol.mandatorycharset"]
  end

  def mandatorycharset=(mandatorycharset)
    @servant.options["protocol.mandatorycharset"] = mandatorycharset
  end

  def wiredump_file_base
    @servant.options["protocol.wiredump_file_base"]
  end

  def wiredump_file_base=(wiredump_file_base)
    @servant.options["protocol.wiredump_file_base"] = wiredump_file_base
  end

  def initialize(wsdl, port, logdev)
    @servant = Servant__.new(self, wsdl, port, logdev)
  end

  def inspect
    "#<#{self.class}:#{@servant.port.name}>"
  end

  def reset_stream
    @servant.reset_stream
  end

  # Backward compatibility.
  alias generateEncodeType= generate_explicit_type=

  class Servant__
    include SOAP

    attr_reader :options
    attr_reader :port

    attr_accessor :soapaction
    attr_accessor :default_encodingstyle
    attr_accessor :allow_unqualified_element
    attr_accessor :generate_explicit_type
    attr_accessor :mapping_registry
    attr_accessor :wsdl_mapping_registry

    def initialize(host, wsdl, port, logdev)
      @host = host
      @wsdl = wsdl
      @port = port
      @logdev = logdev
      @soapaction = nil
      @options = setup_options
      @default_encodingstyle = nil
      @allow_unqualified_element = nil
      @generate_explicit_type = false
      @mapping_registry = nil		# for rpc unmarshal
      @wsdl_mapping_registry = nil	# for rpc marshal
      @wiredump_file_base = nil
      @mandatorycharset = nil
      @wsdl_elements = @wsdl.collect_elements
      @wsdl_types = @wsdl.collect_complextypes + @wsdl.collect_simpletypes
      @rpc_decode_typemap = @wsdl_types +
	@wsdl.soap_rpc_complextypes(port.find_binding)
      @wsdl_mapping_registry = Mapping::WSDLEncodedRegistry.new(
        @rpc_decode_typemap)
      @doc_mapper = Mapping::WSDLLiteralRegistry.new(
        @wsdl_types, @wsdl_elements)
      endpoint_url = @port.soap_address.location
      # Convert a map which key is QName, to a Hash which key is String.
      @operation = {}
      @port.inputoperation_map.each do |op_name, op_info|
        orgname = op_name.name
        name = XSD::CodeGen::GenSupport.safemethodname(orgname)
	@operation[name] = @operation[orgname] = op_info
	add_method_interface(op_info)
      end
      @proxy = ::SOAP::RPC::Proxy.new(endpoint_url, @soapaction, @options)
    end

    def inspect
      "#<#{self.class}:#{@proxy.inspect}>"
    end

    def endpoint_url
      @proxy.endpoint_url
    end

    def endpoint_url=(endpoint_url)
      @proxy.endpoint_url = endpoint_url
    end

    def headerhandler
      @proxy.headerhandler
    end

    def streamhandler
      @proxy.streamhandler
    end

    def test_loopback_response
      @proxy.test_loopback_response
    end

    def reset_stream
      @proxy.reset_stream
    end

    def rpc_call(name, *values)
      set_wiredump_file_base(name)
      unless op_info = @operation[name]
        raise RuntimeError, "method: #{name} not defined"
      end
      req_header = create_request_header
      req_body = create_request_body(op_info, *values)
      reqopt = create_options({
        :soapaction => op_info.soapaction || @soapaction})
      resopt = create_options({
        :decode_typemap => @rpc_decode_typemap})
      env = @proxy.route(req_header, req_body, reqopt, resopt)
      raise EmptyResponseError unless env
      receive_headers(env.header)
      begin
        @proxy.check_fault(env.body)
      rescue ::SOAP::FaultError => e
	Mapping.fault2exception(e)
      end
      ret = env.body.response ?
	Mapping.soap2obj(env.body.response, @mapping_registry) : nil
      if env.body.outparams
	outparams = env.body.outparams.collect { |outparam|
  	  Mapping.soap2obj(outparam)
   	}
    	return [ret].concat(outparams)
      else
      	return ret
      end
    end

    # req_header: [[element, mustunderstand, encodingstyle(QName/String)], ...]
    # req_body: SOAPBasetype/SOAPCompoundtype
    def document_send(name, header_obj, body_obj)
      set_wiredump_file_base(name)
      unless op_info = @operation[name]
        raise RuntimeError, "method: #{name} not defined"
      end
      req_header = header_obj ? header_from_obj(header_obj, op_info) : nil
      req_body = body_from_obj(body_obj, op_info)
      opt = create_options({
        :soapaction => op_info.soapaction || @soapaction,
        :decode_typemap => @wsdl_types})
      env = @proxy.invoke(req_header, req_body, opt)
      raise EmptyResponseError unless env
      if env.body.fault
	raise ::SOAP::FaultError.new(env.body.fault)
      end
      res_body_obj = env.body.response ?
	Mapping.soap2obj(env.body.response, @mapping_registry) : nil
      return env.header, res_body_obj
    end

  private

    def create_options(hash = nil)
      opt = {}
      opt[:default_encodingstyle] = @default_encodingstyle
      opt[:allow_unqualified_element] = @allow_unqualified_element
      opt[:generate_explicit_type] = @generate_explicit_type
      opt.update(hash) if hash
      opt
    end

    def set_wiredump_file_base(name)
      if @wiredump_file_base
      	@proxy.set_wiredump_file_base(@wiredump_file_base + "_#{name}")
      end
    end

    def create_request_header
      headers = @proxy.headerhandler.on_outbound
      if headers.empty?
	nil
      else
	h = SOAPHeader.new
	headers.each do |header|
	  h.add(header.elename.name, header)
	end
	h
      end
    end

    def receive_headers(headers)
      @proxy.headerhandler.on_inbound(headers) if headers
    end

    def create_request_body(op_info, *values)
      method = create_method_struct(op_info, *values)
      SOAPBody.new(method)
    end

    def create_method_struct(op_info, *params)
      parts_names = op_info.bodyparts.collect { |part| part.name }
      obj = create_method_obj(parts_names, params)
      method = Mapping.obj2soap(obj, @wsdl_mapping_registry, op_info.op_name)
      if method.members.size != parts_names.size
	new_method = SOAPStruct.new
	method.each do |key, value|
	  if parts_names.include?(key)
	    new_method.add(key, value)
	  end
	end
	method = new_method
      end
      method.elename = op_info.op_name
      method.type = XSD::QName.new	# Request should not be typed.
      method
    end

    def create_method_obj(names, params)
      o = Object.new
      idx = 0
      while idx < params.length
        o.instance_variable_set('@' + names[idx], params[idx])
        idx += 1
      end
      o
    end

    def header_from_obj(obj, op_info)
      if obj.is_a?(SOAPHeader)
	obj
      elsif op_info.headerparts.empty?
	if obj.nil?
	  nil
	else
	  raise RuntimeError.new("no header definition in schema: #{obj}")
	end
      elsif op_info.headerparts.size == 1
       	part = op_info.headerparts[0]
	header = SOAPHeader.new()
	header.add(headeritem_from_obj(obj, part.element || part.eletype))
	header
      else
	header = SOAPHeader.new()
	op_info.headerparts.each do |part|
	  child = Mapping.get_attribute(obj, part.name)
	  ele = headeritem_from_obj(child, part.element || part.eletype)
	  header.add(part.name, ele)
	end
	header
      end
    end

    def headeritem_from_obj(obj, name)
      if obj.nil?
	SOAPElement.new(name)
      elsif obj.is_a?(SOAPHeaderItem)
	obj
      else
        Mapping.obj2soap(obj, @doc_mapper, name)
      end
    end

    def body_from_obj(obj, op_info)
      if obj.is_a?(SOAPBody)
	obj
      elsif op_info.bodyparts.empty?
	if obj.nil?
	  nil
	else
	  raise RuntimeError.new("no body found in schema")
	end
      elsif op_info.bodyparts.size == 1
       	part = op_info.bodyparts[0]
	ele = bodyitem_from_obj(obj, part.element || part.type)
	SOAPBody.new(ele)
      else
	body = SOAPBody.new
	op_info.bodyparts.each do |part|
	  child = Mapping.get_attribute(obj, part.name)
	  ele = bodyitem_from_obj(child, part.element || part.type)
	  body.add(ele.elename.name, ele)
	end
	body
      end
    end

    def bodyitem_from_obj(obj, name)
      if obj.nil?
	SOAPElement.new(name)
      elsif obj.is_a?(SOAPElement)
	obj
      else
        Mapping.obj2soap(obj, @doc_mapper, name)
      end
    end

    def add_method_interface(op_info)
      name = XSD::CodeGen::GenSupport.safemethodname(op_info.op_name.name)
      orgname = op_info.op_name.name
      parts_names = op_info.bodyparts.collect { |part| part.name }
      case op_info.style
      when :document
        if orgname != name and orgname.capitalize == name.capitalize
          add_document_method_interface(orgname, parts_names)
        end
	add_document_method_interface(name, parts_names)
      when :rpc
        if orgname != name and orgname.capitalize == name.capitalize
          add_rpc_method_interface(orgname, parts_names)
        end
	add_rpc_method_interface(name, parts_names)
      else
	raise RuntimeError.new("unknown style: #{op_info.style}")
      end
    end

    def add_rpc_method_interface(name, parts_names)
      ::SOAP::Mapping.define_singleton_method(@host, name) do |*arg|
        unless arg.size == parts_names.size
          raise ArgumentError.new(
            "wrong number of arguments (#{arg.size} for #{parts_names.size})")
        end
        @servant.rpc_call(name, *arg)
      end
      @host.method(name)
    end

    def add_document_method_interface(name, parts_names)
      ::SOAP::Mapping.define_singleton_method(@host, name) do |h, b|
        @servant.document_send(name, h, b)
      end
      @host.method(name)
    end

    def setup_options
      if opt = Property.loadproperty(::SOAP::PropertyName)
	opt = opt["client"]
      end
      opt ||= Property.new
      opt.add_hook("protocol.mandatorycharset") do |key, value|
	@mandatorycharset = value
      end
      opt.add_hook("protocol.wiredump_file_base") do |key, value|
	@wiredump_file_base = value
      end
      opt["protocol.http.charset"] ||= XSD::Charset.xml_encoding_label
      opt["protocol.http.proxy"] ||= Env::HTTP_PROXY
      opt["protocol.http.no_proxy"] ||= Env::NO_PROXY
      opt
    end
  end
end


end
PK     Z\U}  }    soap/mapping.rbnu [        # SOAP4R - Ruby type mapping utility.
# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/mapping/mapping'
require 'soap/mapping/registry'
PK     Z\      soap/element.rbnu [        # SOAP4R - SOAP elements library
# Copyright (C) 2000, 2001, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/qname'
require 'soap/baseData'


module SOAP


###
## SOAP elements
#
module SOAPEnvelopeElement; end

class SOAPFault < SOAPStruct
  include SOAPEnvelopeElement
  include SOAPCompoundtype

public

  def faultcode
    self['faultcode']
  end

  def faultstring
    self['faultstring']
  end

  def faultactor
    self['faultactor']
  end

  def detail
    self['detail']
  end

  def faultcode=(rhs)
    self['faultcode'] = rhs
  end

  def faultstring=(rhs)
    self['faultstring'] = rhs
  end

  def faultactor=(rhs)
    self['faultactor'] = rhs
  end

  def detail=(rhs)
    self['detail'] = rhs
  end

  def initialize(faultcode = nil, faultstring = nil, faultactor = nil, detail = nil)
    super(EleFaultName)
    @elename = EleFaultName
    @encodingstyle = EncodingNamespace

    if faultcode
      self.faultcode = faultcode
      self.faultstring = faultstring
      self.faultactor = faultactor
      self.detail = detail
      self.faultcode.elename = EleFaultCodeName if self.faultcode
      self.faultstring.elename = EleFaultStringName if self.faultstring
      self.faultactor.elename = EleFaultActorName if self.faultactor
      self.detail.elename = EleFaultDetailName if self.detail
    end
    faultcode.parent = self if faultcode
    faultstring.parent = self if faultstring
    faultactor.parent = self if faultactor
    detail.parent = self if detail
  end

  def encode(generator, ns, attrs = {})
    SOAPGenerator.assign_ns(attrs, ns, EnvelopeNamespace)
    SOAPGenerator.assign_ns(attrs, ns, EncodingNamespace)
    attrs[ns.name(AttrEncodingStyleName)] = EncodingNamespace
    name = ns.name(@elename)
    generator.encode_tag(name, attrs)
    yield(self.faultcode)
    yield(self.faultstring)
    yield(self.faultactor)
    yield(self.detail) if self.detail
    generator.encode_tag_end(name, true)
  end
end


class SOAPBody < SOAPStruct
  include SOAPEnvelopeElement

  def initialize(data = nil, is_fault = false)
    super(nil)
    @elename = EleBodyName
    @encodingstyle = nil
    if data
      if data.respond_to?(:elename)
        add(data.elename.name, data)
      else
        data.to_a.each do |datum|
          add(datum.elename.name, datum)
        end
      end
    end
    @is_fault = is_fault
  end

  def encode(generator, ns, attrs = {})
    name = ns.name(@elename)
    generator.encode_tag(name, attrs)
    if @is_fault
      yield(@data)
    else
      @data.each do |data|
	yield(data)
      end
    end
    generator.encode_tag_end(name, true)
  end

  def root_node
    @data.each do |node|
      if node.root == 1
	return node
      end
    end
    # No specified root...
    @data.each do |node|
      if node.root != 0
	return node
      end
    end

    raise Parser::FormatDecodeError.new('no root element')
  end
end


class SOAPHeaderItem < XSD::NSDBase
  include SOAPEnvelopeElement
  include SOAPCompoundtype

public

  attr_accessor :element
  attr_accessor :mustunderstand
  attr_accessor :encodingstyle

  def initialize(element, mustunderstand = true, encodingstyle = nil)
    super()
    @type = nil
    @element = element
    @mustunderstand = mustunderstand
    @encodingstyle = encodingstyle
    element.parent = self if element
  end

  def encode(generator, ns, attrs = {})
    attrs.each do |key, value|
      @element.extraattr[key] = value
    end
    @element.extraattr[ns.name(AttrMustUnderstandName)] =
      (@mustunderstand ? '1' : '0')
    if @encodingstyle
      @element.extraattr[ns.name(AttrEncodingStyleName)] = @encodingstyle
    end
    @element.encodingstyle = @encodingstyle if !@element.encodingstyle
    yield(@element)
  end
end


class SOAPHeader < SOAPStruct
  include SOAPEnvelopeElement

  def initialize
    super(nil)
    @elename = EleHeaderName
    @encodingstyle = nil
  end

  def encode(generator, ns, attrs = {})
    name = ns.name(@elename)
    generator.encode_tag(name, attrs)
    @data.each do |data|
      yield(data)
    end
    generator.encode_tag_end(name, true)
  end

  def add(name, value)
    mu = (value.extraattr[AttrMustUnderstandName] == '1')
    encstyle = value.extraattr[AttrEncodingStyleName]
    item = SOAPHeaderItem.new(value, mu, encstyle)
    super(name, item)
  end

  def length
    @data.length
  end
  alias size length
end


class SOAPEnvelope < XSD::NSDBase
  include SOAPEnvelopeElement
  include SOAPCompoundtype

  attr_reader :header
  attr_reader :body
  attr_reader :external_content

  def initialize(header = nil, body = nil)
    super()
    @type = nil
    @elename = EleEnvelopeName
    @encodingstyle = nil
    @header = header
    @body = body
    @external_content = {}
    header.parent = self if header
    body.parent = self if body
  end

  def header=(header)
    header.parent = self
    @header = header
  end

  def body=(body)
    body.parent = self
    @body = body
  end

  def encode(generator, ns, attrs = {})
    SOAPGenerator.assign_ns(attrs, ns, elename.namespace, SOAPNamespaceTag)
    name = ns.name(@elename)
    generator.encode_tag(name, attrs)

    yield(@header) if @header and @header.length > 0
    yield(@body)

    generator.encode_tag_end(name, true)
  end

  def to_ary
    [header, body]
  end
end


end
PK     Z\Y      soap/attachment.rbnu [        # soap/attachment.rb: SOAP4R - SwA implementation.
# Copyright (C) 2002, 2003  Jamie Herre and NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'soap/baseData'
require 'soap/mapping'


module SOAP


class SOAPAttachment < SOAPExternalReference
  attr_reader :data

  def initialize(value)
    super()
    @data = value
  end

private

  def external_contentid
    @data.contentid
  end
end


class Attachment
  attr_reader :io
  attr_accessor :contenttype

  def initialize(string_or_readable = nil)
    @string_or_readable = string_or_readable
    @contenttype = "application/octet-stream"
    @contentid = nil
  end

  def contentid
    @contentid ||= Attachment.contentid(self)
  end

  def contentid=(contentid)
    @contentid = contentid
  end

  def mime_contentid
    '<' + contentid + '>'
  end

  def content
    if @content == nil and @string_or_readable != nil
      @content = @string_or_readable.respond_to?(:read) ?
	@string_or_readable.read : @string_or_readable
    end
    @content
  end

  def to_s
    content
  end

  def write(out)
    out.write(content)
  end

  def save(filename)
    File.open(filename, "wb") do |f|
      write(f)
    end
  end

  def self.contentid(obj)
    # this needs to be fixed
    [obj.__id__.to_s, Process.pid.to_s].join('.')
  end

  def self.mime_contentid(obj)
    '<' + contentid(obj) + '>'
  end
end


module Mapping
  class AttachmentFactory < SOAP::Mapping::Factory
    def obj2soap(soap_class, obj, info, map)
      soap_obj = soap_class.new(obj)
      mark_marshalled_obj(obj, soap_obj)
      soap_obj
    end

    def soap2obj(obj_class, node, info, map)
      obj = node.data
      mark_unmarshalled_obj(node, obj)
      return true, obj
    end
  end

  DefaultRegistry.add(::SOAP::Attachment, ::SOAP::SOAPAttachment,
    AttachmentFactory.new, nil)
end


end
PK     Z\ʜay  y  	  digest.rbnu [        require 'digest.so'

module Digest
  def self.const_missing(name)
    case name
    when :SHA256, :SHA384, :SHA512
      lib = 'digest/sha2.so'
    else
      lib = File.join('digest', name.to_s.downcase)
    end

    begin
      require lib
    rescue LoadError => e
      raise LoadError, "library not found for class Digest::#{name} -- #{lib}", caller(1)
    end
    unless Digest.const_defined?(name)
      raise NameError, "uninitialized constant Digest::#{name}", caller(1)
    end
    Digest.const_get(name)
  end

  class ::Digest::Class
    # creates a digest object and reads a given file, _name_.
    # 
    #  p Digest::SHA256.file("X11R6.8.2-src.tar.bz2").hexdigest
    #  # => "f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534"
    def self.file(name)
      new.file(name)
    end
  end

  module Instance
    # updates the digest with the contents of a given file _name_ and
    # returns self.
    def file(name)
      File.open(name, "rb") {|f|
        buf = ""
        while f.read(16384, buf)
          update buf
        end
      }
      self
    end
  end
end

def Digest(name)
  Digest.const_get(name)
end
PK     Z\>O1      uri.rbnu [        #
# URI support for Ruby
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# Documentation:: Akira Yamada <akira@ruby-lang.org>, Dmitry V. Sabanin <sdmitry@lrn.ru>
# License:: 
#  Copyright (c) 2001 akira yamada <akira@ruby-lang.org>
#  You can redistribute it and/or modify it under the same term as Ruby.
# Revision:: $Id: uri.rb 16038 2008-04-15 09:41:47Z kazu $
# 
# See URI for documentation
#

module URI
  # :stopdoc:
  VERSION_CODE = '000911'.freeze
  VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze
  # :startdoc:

end

require 'uri/common'
require 'uri/generic'
require 'uri/ftp'
require 'uri/http'
require 'uri/https'
require 'uri/ldap'
require 'uri/ldaps'
require 'uri/mailto'
PK     Z\?JJ  J  
  mutex_m.rbnu [        #--
#   mutex_m.rb - 
#   	$Release Version: 3.0$
#   	$Revision: 1.7 $
#   	$Date: 1998/02/27 04:28:57 $
#       Original from mutex.rb
#   	by Keiju ISHITSUKA(keiju@ishitsuka.com)
#       modified by matz
#       patched by akira yamada
#++
#
# == Usage
#
# Extend an object and use it like a Mutex object:
#
#   require "mutex_m.rb"
#   obj = Object.new
#   obj.extend Mutex_m
#   # ...
#
# Or, include Mutex_m in a class to have its instances behave like a Mutex
# object:
#
#   class Foo
#     include Mutex_m
#     # ...
#   end
#   
#   obj = Foo.new

module Mutex_m
  def Mutex_m.define_aliases(cl)
    cl.module_eval %q{
      alias locked? mu_locked?
      alias lock mu_lock
      alias unlock mu_unlock
      alias try_lock mu_try_lock
      alias synchronize mu_synchronize
    }
  end  

  def Mutex_m.append_features(cl)
    super
    define_aliases(cl) unless cl.instance_of?(Module)
  end
  
  def Mutex_m.extend_object(obj)
    super
    obj.mu_extended
  end

  def mu_extended
    unless (defined? locked? and
	    defined? lock and
	    defined? unlock and
	    defined? try_lock and
	    defined? synchronize)
      Mutex_m.define_aliases(class<<self;self;end)
    end
    mu_initialize
  end
  
  # locking 
  def mu_synchronize
    begin
      mu_lock
      yield
    ensure
      mu_unlock
    end
  end
  
  def mu_locked?
    @mu_locked
  end
  
  def mu_try_lock
    result = false
    Thread.critical = true
    unless @mu_locked
      @mu_locked = true
      result = true
    end
    Thread.critical = false
    result
  end
  
  def mu_lock
    while (Thread.critical = true; @mu_locked)
      @mu_waiting.push Thread.current
      Thread.stop
    end
    @mu_locked = true
    Thread.critical = false
    self
  end
  
  def mu_unlock
    return unless @mu_locked
    Thread.critical = true
    wait = @mu_waiting
    @mu_waiting = []
    @mu_locked = false
    Thread.critical = false
    for w in wait
      w.run
    end
    self
  end
  
  private
  
  def mu_initialize
    @mu_waiting = []
    @mu_locked = false;
  end

  def initialize(*args)
    mu_initialize
    super
  end
end
PK     Z\OGR~  R~    time.rbnu [        
#
# == Introduction
# 
# This library extends the Time class:
# * conversion between date string and time object.
#   * date-time defined by RFC 2822
#   * HTTP-date defined by RFC 2616
#   * dateTime defined by XML Schema Part 2: Datatypes (ISO 8601)
#   * various formats handled by Date._parse (string to time only)
# 
# == Design Issues
# 
# === Specialized interface
# 
# This library provides methods dedicated to special purposes:
# * RFC 2822, RFC 2616 and XML Schema.
# * They makes usual life easier.
# 
# === Doesn't depend on strftime
# 
# This library doesn't use +strftime+.  Especially #rfc2822 doesn't depend
# on +strftime+ because:
# 
# * %a and %b are locale sensitive
# 
#   Since they are locale sensitive, they may be replaced to
#   invalid weekday/month name in some locales.
#   Since ruby-1.6 doesn't invoke setlocale by default,
#   the problem doesn't arise until some external library invokes setlocale.
#   Ruby/GTK is the example of such library.
# 
# * %z is not portable
# 
#   %z is required to generate zone in date-time of RFC 2822
#   but it is not portable.
#
# == Revision Information
#
# $Id$
#

require 'parsedate'

#
# Implements the extensions to the Time class that are described in the
# documentation for the time.rb library.
#
class Time
  class << Time

    ZoneOffset = {
      'UTC' => 0,
      # ISO 8601
      'Z' => 0,
      # RFC 822
      'UT' => 0, 'GMT' => 0,
      'EST' => -5, 'EDT' => -4,
      'CST' => -6, 'CDT' => -5,
      'MST' => -7, 'MDT' => -6,
      'PST' => -8, 'PDT' => -7,
      # Following definition of military zones is original one.
      # See RFC 1123 and RFC 2822 for the error in RFC 822.
      'A' => +1, 'B' => +2, 'C' => +3, 'D' => +4,  'E' => +5,  'F' => +6, 
      'G' => +7, 'H' => +8, 'I' => +9, 'K' => +10, 'L' => +11, 'M' => +12,
      'N' => -1, 'O' => -2, 'P' => -3, 'Q' => -4,  'R' => -5,  'S' => -6, 
      'T' => -7, 'U' => -8, 'V' => -9, 'W' => -10, 'X' => -11, 'Y' => -12,
    }
    def zone_offset(zone, year=self.now.year)
      off = nil
      zone = zone.upcase
      if /\A([+-])(\d\d):?(\d\d)\z/ =~ zone
        off = ($1 == '-' ? -1 : 1) * ($2.to_i * 60 + $3.to_i) * 60
      elsif /\A[+-]\d\d\z/ =~ zone
        off = zone.to_i * 3600
      elsif ZoneOffset.include?(zone)
        off = ZoneOffset[zone] * 3600
      elsif ((t = self.local(year, 1, 1)).zone.upcase == zone rescue false)
        off = t.utc_offset
      elsif ((t = self.local(year, 7, 1)).zone.upcase == zone rescue false)
        off = t.utc_offset
      end
      off
    end

    def zone_utc?(zone)
      # * +0000 means localtime. [RFC 2822]
      # * GMT is a localtime abbreviation in Europe/London, etc.
      if /\A(?:-00:00|-0000|-00|UTC|Z|UT)\z/i =~ zone
        true
      else
        false
      end
    end
    private :zone_utc?

    LeapYearMonthDays = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    CommonYearMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    def month_days(y, m)
      if ((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0)
        LeapYearMonthDays[m-1]
      else
        CommonYearMonthDays[m-1]
      end
    end
    private :month_days

    def apply_offset(year, mon, day, hour, min, sec, off)
      if off < 0
        off = -off
        off, o = off.divmod(60)
        if o != 0 then sec += o; o, sec = sec.divmod(60); off += o end
        off, o = off.divmod(60)
        if o != 0 then min += o; o, min = min.divmod(60); off += o end
        off, o = off.divmod(24)
        if o != 0 then hour += o; o, hour = hour.divmod(24); off += o end
        if off != 0
          day += off
          if month_days(year, mon) < day
            mon += 1
            if 12 < mon
              mon = 1
              year += 1
            end
            day = 1
          end
        end
      elsif 0 < off
        off, o = off.divmod(60)
        if o != 0 then sec -= o; o, sec = sec.divmod(60); off -= o end
        off, o = off.divmod(60)
        if o != 0 then min -= o; o, min = min.divmod(60); off -= o end
        off, o = off.divmod(24)
        if o != 0 then hour -= o; o, hour = hour.divmod(24); off -= o end
        if off != 0 then
          day -= off
          if day < 1
            mon -= 1
            if mon < 1
              year -= 1
              mon = 12
            end
            day = month_days(year, mon)
          end
        end
      end
      return year, mon, day, hour, min, sec
    end
    private :apply_offset

    def make_time(year, mon, day, hour, min, sec, sec_fraction, zone, now)
      usec = nil
      usec = (sec_fraction * 1000000).to_i if sec_fraction
      if now
        begin
          break if year; year = now.year
          break if mon; mon = now.mon
          break if day; day = now.day
          break if hour; hour = now.hour
          break if min; min = now.min
          break if sec; sec = now.sec
          break if sec_fraction; usec = now.tv_usec
        end until true
      end

      year ||= 1970
      mon ||= 1
      day ||= 1
      hour ||= 0
      min ||= 0
      sec ||= 0
      usec ||= 0

      off = nil
      off = zone_offset(zone, year) if zone

      if off
        year, mon, day, hour, min, sec =
          apply_offset(year, mon, day, hour, min, sec, off)
        t = self.utc(year, mon, day, hour, min, sec, usec)
        t.localtime if !zone_utc?(zone)
        t
      else
        self.local(year, mon, day, hour, min, sec, usec)
      end
    end
    private :make_time

    #
    # Parses +date+ using Date._parse and converts it to a Time object.
    #
    # If a block is given, the year described in +date+ is converted by the
    # block.  For example:
    #
    #     Time.parse(...) {|y| y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}
    #
    # If the upper components of the given time are broken or missing, they are
    # supplied with those of +now+.  For the lower components, the minimum
    # values (1 or 0) are assumed if broken or missing.  For example:
    #
    #     # Suppose it is "Thu Nov 29 14:33:20 GMT 2001" now and
    #     # your timezone is GMT:
    #     Time.parse("16:30")     #=> Thu Nov 29 16:30:00 GMT 2001
    #     Time.parse("7/23")      #=> Mon Jul 23 00:00:00 GMT 2001
    #     Time.parse("Aug 31")    #=> Fri Aug 31 00:00:00 GMT 2001
    #
    # Since there are numerous conflicts among locally defined timezone
    # abbreviations all over the world, this method is not made to
    # understand all of them.  For example, the abbreviation "CST" is
    # used variously as:
    #
    #     -06:00 in America/Chicago,
    #     -05:00 in America/Havana,
    #     +08:00 in Asia/Harbin,
    #     +09:30 in Australia/Darwin,
    #     +10:30 in Australia/Adelaide,
    #     etc.
    #
    # Based on the fact, this method only understands the timezone
    # abbreviations described in RFC 822 and the system timezone, in the
    # order named. (i.e. a definition in RFC 822 overrides the system
    # timezone definition.)  The system timezone is taken from
    # <tt>Time.local(year, 1, 1).zone</tt> and
    # <tt>Time.local(year, 7, 1).zone</tt>.
    # If the extracted timezone abbreviation does not match any of them,
    # it is ignored and the given time is regarded as a local time.
    #
    # ArgumentError is raised if Date._parse cannot extract information from
    # +date+ or Time class cannot represent specified date.
    #
    # This method can be used as fail-safe for other parsing methods as:
    #
    #   Time.rfc2822(date) rescue Time.parse(date)
    #   Time.httpdate(date) rescue Time.parse(date)
    #   Time.xmlschema(date) rescue Time.parse(date)
    #
    # A failure for Time.parse should be checked, though.
    #
    def parse(date, now=self.now)
      d = Date._parse(date, false)
      year = d[:year]
      year = yield(year) if year && block_given?
      make_time(year, d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now)
    end

    MonthValue = {
      'JAN' => 1, 'FEB' => 2, 'MAR' => 3, 'APR' => 4, 'MAY' => 5, 'JUN' => 6,
      'JUL' => 7, 'AUG' => 8, 'SEP' => 9, 'OCT' =>10, 'NOV' =>11, 'DEC' =>12
    }

    #
    # Parses +date+ as date-time defined by RFC 2822 and converts it to a Time
    # object.  The format is identical to the date format defined by RFC 822 and
    # updated by RFC 1123.
    #
    # ArgumentError is raised if +date+ is not compliant with RFC 2822
    # or Time class cannot represent specified date.
    #
    # See #rfc2822 for more information on this format.
    #
    def rfc2822(date)
      if /\A\s*
          (?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*,\s*)?
          (\d{1,2})\s+
          (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+
          (\d{2,})\s+
          (\d{2})\s*
          :\s*(\d{2})\s*
          (?::\s*(\d{2}))?\s+
          ([+-]\d{4}|
           UT|GMT|EST|EDT|CST|CDT|MST|MDT|PST|PDT|[A-IK-Z])/ix =~ date
        # Since RFC 2822 permit comments, the regexp has no right anchor.
        day = $1.to_i
        mon = MonthValue[$2.upcase]
        year = $3.to_i
        hour = $4.to_i
        min = $5.to_i
        sec = $6 ? $6.to_i : 0
        zone = $7

        # following year completion is compliant with RFC 2822.
        year = if year < 50
                 2000 + year
               elsif year < 1000
                 1900 + year
               else
                 year
               end

        year, mon, day, hour, min, sec =
          apply_offset(year, mon, day, hour, min, sec, zone_offset(zone))
        t = self.utc(year, mon, day, hour, min, sec)
        t.localtime if !zone_utc?(zone)
        t
      else
        raise ArgumentError.new("not RFC 2822 compliant date: #{date.inspect}")
      end
    end
    alias rfc822 rfc2822

    #
    # Parses +date+ as HTTP-date defined by RFC 2616 and converts it to a Time
    # object.
    #
    # ArgumentError is raised if +date+ is not compliant with RFC 2616 or Time
    # class cannot represent specified date.
    #
    # See #httpdate for more information on this format.
    #
    def httpdate(date)
      if /\A\s*
          (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\x20
          (\d{2})\x20
          (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\x20
          (\d{4})\x20
          (\d{2}):(\d{2}):(\d{2})\x20
          GMT
          \s*\z/ix =~ date
        self.rfc2822(date)
      elsif /\A\s*
             (?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\x20
             (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d)\x20
             (\d\d):(\d\d):(\d\d)\x20
             GMT
             \s*\z/ix =~ date
        self.parse(date)
      elsif /\A\s*
             (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\x20
             (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\x20
             (\d\d|\x20\d)\x20
             (\d\d):(\d\d):(\d\d)\x20
             (\d{4})
             \s*\z/ix =~ date
        self.utc($6.to_i, MonthValue[$1.upcase], $2.to_i,
                 $3.to_i, $4.to_i, $5.to_i)
      else
        raise ArgumentError.new("not RFC 2616 compliant date: #{date.inspect}")
      end
    end

    #
    # Parses +date+ as dateTime defined by XML Schema and converts it to a Time
    # object.  The format is restricted version of the format defined by ISO
    # 8601.
    #
    # ArgumentError is raised if +date+ is not compliant with the format or Time
    # class cannot represent specified date.
    #
    # See #xmlschema for more information on this format.
    #
    def xmlschema(date)
      if /\A\s*
          (-?\d+)-(\d\d)-(\d\d)
          T
          (\d\d):(\d\d):(\d\d)
          (\.\d*)?
          (Z|[+-]\d\d:\d\d)?
          \s*\z/ix =~ date
        year = $1.to_i
        mon = $2.to_i
        day = $3.to_i
        hour = $4.to_i
        min = $5.to_i
        sec = $6.to_i
        usec = 0
        usec = ($7[1..-1] + '000000')[0,6].to_i if $7
        if $8
          zone = $8
          year, mon, day, hour, min, sec =
            apply_offset(year, mon, day, hour, min, sec, zone_offset(zone))
          self.utc(year, mon, day, hour, min, sec, usec)
        else
          self.local(year, mon, day, hour, min, sec, usec)
        end
      else
        raise ArgumentError.new("invalid date: #{date.inspect}")
      end
    end
    alias iso8601 xmlschema
  end # class << self

  #
  # Returns a string which represents the time as date-time defined by RFC 2822:
  #
  #   day-of-week, DD month-name CCYY hh:mm:ss zone
  #
  # where zone is [+-]hhmm.
  #
  # If +self+ is a UTC time, -0000 is used as zone.
  #
  def rfc2822
    sprintf('%s, %02d %s %d %02d:%02d:%02d ',
      RFC2822_DAY_NAME[wday],
      day, RFC2822_MONTH_NAME[mon-1], year,
      hour, min, sec) +
    if utc?
      '-0000'
    else
      off = utc_offset
      sign = off < 0 ? '-' : '+'
      sprintf('%s%02d%02d', sign, *(off.abs / 60).divmod(60))
    end
  end
  alias rfc822 rfc2822

  RFC2822_DAY_NAME = [
    'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'
  ]
  RFC2822_MONTH_NAME = [
    'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
  ]

  #
  # Returns a string which represents the time as rfc1123-date of HTTP-date
  # defined by RFC 2616: 
  # 
  #   day-of-week, DD month-name CCYY hh:mm:ss GMT
  #
  # Note that the result is always UTC (GMT).
  #
  def httpdate
    t = dup.utc
    sprintf('%s, %02d %s %d %02d:%02d:%02d GMT',
      RFC2822_DAY_NAME[t.wday],
      t.day, RFC2822_MONTH_NAME[t.mon-1], t.year,
      t.hour, t.min, t.sec)
  end

  #
  # Returns a string which represents the time as dateTime defined by XML
  # Schema:
  #
  #   CCYY-MM-DDThh:mm:ssTZD
  #   CCYY-MM-DDThh:mm:ss.sssTZD
  #
  # where TZD is Z or [+-]hh:mm.
  #
  # If self is a UTC time, Z is used as TZD.  [+-]hh:mm is used otherwise.
  #
  # +fractional_seconds+ specifies a number of digits of fractional seconds.
  # Its default value is 0.
  #
  def xmlschema(fraction_digits=0)
    sprintf('%d-%02d-%02dT%02d:%02d:%02d',
      year, mon, day, hour, min, sec) +
    if fraction_digits == 0
      ''
    elsif fraction_digits <= 6
      '.' + sprintf('%06d', usec)[0, fraction_digits]
    else
      '.' + sprintf('%06d', usec) + '0' * (fraction_digits - 6)
    end +
    if utc?
      'Z'
    else
      off = utc_offset
      sign = off < 0 ? '-' : '+'
      sprintf('%s%02d:%02d', sign, *(off.abs / 60).divmod(60))
    end
  end
  alias iso8601 xmlschema
end

if __FILE__ == $0
  require 'test/unit'

  class TimeExtentionTest < Test::Unit::TestCase # :nodoc:
    def test_rfc822
      assert_equal(Time.utc(1976, 8, 26, 14, 30) + 4 * 3600,
                   Time.rfc2822("26 Aug 76 14:30 EDT"))
      assert_equal(Time.utc(1976, 8, 27, 9, 32) + 7 * 3600,
                   Time.rfc2822("27 Aug 76 09:32 PDT"))
    end

    def test_rfc2822
      assert_equal(Time.utc(1997, 11, 21, 9, 55, 6) + 6 * 3600,
                   Time.rfc2822("Fri, 21 Nov 1997 09:55:06 -0600"))
      assert_equal(Time.utc(2003, 7, 1, 10, 52, 37) - 2 * 3600,
                   Time.rfc2822("Tue, 1 Jul 2003 10:52:37 +0200"))
      assert_equal(Time.utc(1997, 11, 21, 10, 1, 10) + 6 * 3600,
                   Time.rfc2822("Fri, 21 Nov 1997 10:01:10 -0600"))
      assert_equal(Time.utc(1997, 11, 21, 11, 0, 0) + 6 * 3600,
                   Time.rfc2822("Fri, 21 Nov 1997 11:00:00 -0600"))
      assert_equal(Time.utc(1997, 11, 24, 14, 22, 1) + 8 * 3600,
                   Time.rfc2822("Mon, 24 Nov 1997 14:22:01 -0800"))
      begin
        Time.at(-1)
      rescue ArgumentError
        # ignore
      else
        assert_equal(Time.utc(1969, 2, 13, 23, 32, 54) + 3 * 3600 + 30 * 60,
                     Time.rfc2822("Thu, 13 Feb 1969 23:32:54 -0330"))
        assert_equal(Time.utc(1969, 2, 13, 23, 32, 0) + 3 * 3600 + 30 * 60,
                     Time.rfc2822(" Thu,
        13
          Feb
            1969
        23:32
                 -0330 (Newfoundland Time)"))
      end
      assert_equal(Time.utc(1997, 11, 21, 9, 55, 6),
                   Time.rfc2822("21 Nov 97 09:55:06 GMT"))
      assert_equal(Time.utc(1997, 11, 21, 9, 55, 6) + 6 * 3600,
                   Time.rfc2822("Fri, 21 Nov 1997 09 :   55  :  06 -0600"))
      assert_raise(ArgumentError) {
        # inner comment is not supported.
        Time.rfc2822("Fri, 21 Nov 1997 09(comment):   55  :  06 -0600")
      }
    end

    def test_rfc2616
      t = Time.utc(1994, 11, 6, 8, 49, 37)
      assert_equal(t, Time.httpdate("Sun, 06 Nov 1994 08:49:37 GMT"))
      assert_equal(t, Time.httpdate("Sunday, 06-Nov-94 08:49:37 GMT"))
      assert_equal(t, Time.httpdate("Sun Nov  6 08:49:37 1994"))
      assert_equal(Time.utc(1995, 11, 15, 6, 25, 24),
                   Time.httpdate("Wed, 15 Nov 1995 06:25:24 GMT"))
      assert_equal(Time.utc(1995, 11, 15, 4, 58, 8),
                   Time.httpdate("Wed, 15 Nov 1995 04:58:08 GMT"))
      assert_equal(Time.utc(1994, 11, 15, 8, 12, 31),
                   Time.httpdate("Tue, 15 Nov 1994 08:12:31 GMT"))
      assert_equal(Time.utc(1994, 12, 1, 16, 0, 0),
                   Time.httpdate("Thu, 01 Dec 1994 16:00:00 GMT"))
      assert_equal(Time.utc(1994, 10, 29, 19, 43, 31),
                   Time.httpdate("Sat, 29 Oct 1994 19:43:31 GMT"))
      assert_equal(Time.utc(1994, 11, 15, 12, 45, 26),
                   Time.httpdate("Tue, 15 Nov 1994 12:45:26 GMT"))
      assert_equal(Time.utc(1999, 12, 31, 23, 59, 59),
                   Time.httpdate("Fri, 31 Dec 1999 23:59:59 GMT"))
    end

    def test_rfc3339
      t = Time.utc(1985, 4, 12, 23, 20, 50, 520000)
      s = "1985-04-12T23:20:50.52Z"
      assert_equal(t, Time.iso8601(s))
      assert_equal(s, t.iso8601(2))

      t = Time.utc(1996, 12, 20, 0, 39, 57)
      s = "1996-12-19T16:39:57-08:00"
      assert_equal(t, Time.iso8601(s))
      # There is no way to generate time string with arbitrary timezone.
      s = "1996-12-20T00:39:57Z"
      assert_equal(t, Time.iso8601(s))
      assert_equal(s, t.iso8601)

      t = Time.utc(1990, 12, 31, 23, 59, 60)
      s = "1990-12-31T23:59:60Z"
      assert_equal(t, Time.iso8601(s))
      # leap second is representable only if timezone file has it.
      s = "1990-12-31T15:59:60-08:00"
      assert_equal(t, Time.iso8601(s))

      begin
        Time.at(-1)
      rescue ArgumentError
        # ignore
      else
        t = Time.utc(1937, 1, 1, 11, 40, 27, 870000)
        s = "1937-01-01T12:00:27.87+00:20"
        assert_equal(t, Time.iso8601(s))
      end
    end

    # http://www.w3.org/TR/xmlschema-2/
    def test_xmlschema
      assert_equal(Time.utc(1999, 5, 31, 13, 20, 0) + 5 * 3600,
                   Time.xmlschema("1999-05-31T13:20:00-05:00"))
      assert_equal(Time.local(2000, 1, 20, 12, 0, 0),
                   Time.xmlschema("2000-01-20T12:00:00"))
      assert_equal(Time.utc(2000, 1, 20, 12, 0, 0),
                   Time.xmlschema("2000-01-20T12:00:00Z"))
      assert_equal(Time.utc(2000, 1, 20, 12, 0, 0) - 12 * 3600,
                   Time.xmlschema("2000-01-20T12:00:00+12:00"))
      assert_equal(Time.utc(2000, 1, 20, 12, 0, 0) + 13 * 3600,
                   Time.xmlschema("2000-01-20T12:00:00-13:00"))
      assert_equal(Time.utc(2000, 3, 4, 23, 0, 0) - 3 * 3600,
                   Time.xmlschema("2000-03-04T23:00:00+03:00"))
      assert_equal(Time.utc(2000, 3, 4, 20, 0, 0),
                   Time.xmlschema("2000-03-04T20:00:00Z"))
      assert_equal(Time.local(2000, 1, 15, 0, 0, 0),
                   Time.xmlschema("2000-01-15T00:00:00"))
      assert_equal(Time.local(2000, 2, 15, 0, 0, 0),
                   Time.xmlschema("2000-02-15T00:00:00"))
      assert_equal(Time.local(2000, 1, 15, 12, 0, 0),
                   Time.xmlschema("2000-01-15T12:00:00"))
      assert_equal(Time.utc(2000, 1, 16, 12, 0, 0),
                   Time.xmlschema("2000-01-16T12:00:00Z"))
      assert_equal(Time.local(2000, 1, 1, 12, 0, 0),
                   Time.xmlschema("2000-01-01T12:00:00"))
      assert_equal(Time.utc(1999, 12, 31, 23, 0, 0),
                   Time.xmlschema("1999-12-31T23:00:00Z"))
      assert_equal(Time.local(2000, 1, 16, 12, 0, 0),
                   Time.xmlschema("2000-01-16T12:00:00"))
      assert_equal(Time.local(2000, 1, 16, 0, 0, 0),
                   Time.xmlschema("2000-01-16T00:00:00"))
      assert_equal(Time.utc(2000, 1, 12, 12, 13, 14),
                   Time.xmlschema("2000-01-12T12:13:14Z"))
      assert_equal(Time.utc(2001, 4, 17, 19, 23, 17, 300000),
                   Time.xmlschema("2001-04-17T19:23:17.3Z"))
    end

    def test_encode_xmlschema
      t = Time.utc(2001, 4, 17, 19, 23, 17, 300000)
      assert_equal("2001-04-17T19:23:17Z", t.xmlschema)
      assert_equal("2001-04-17T19:23:17.3Z", t.xmlschema(1))
      assert_equal("2001-04-17T19:23:17.300000Z", t.xmlschema(6))
      assert_equal("2001-04-17T19:23:17.3000000Z", t.xmlschema(7))

      t = Time.utc(2001, 4, 17, 19, 23, 17, 123456)
      assert_equal("2001-04-17T19:23:17.1234560Z", t.xmlschema(7))
      assert_equal("2001-04-17T19:23:17.123456Z", t.xmlschema(6))
      assert_equal("2001-04-17T19:23:17.12345Z", t.xmlschema(5))
      assert_equal("2001-04-17T19:23:17.1Z", t.xmlschema(1))

      begin
        Time.at(-1)
      rescue ArgumentError
        # ignore
      else
        t = Time.utc(1960, 12, 31, 23, 0, 0, 123456)
        assert_equal("1960-12-31T23:00:00.123456Z", t.xmlschema(6))
      end

      assert_equal(249, Time.xmlschema("2008-06-05T23:49:23.000249+09:00").usec)
    end

    def test_completion
      now = Time.local(2001,11,29,21,26,35)
      assert_equal(Time.local( 2001,11,29,21,12),
                   Time.parse("2001/11/29 21:12", now))
      assert_equal(Time.local( 2001,11,29),
                   Time.parse("2001/11/29", now))
      assert_equal(Time.local( 2001,11,29),
                   Time.parse(     "11/29", now))
      #assert_equal(Time.local(2001,11,1), Time.parse("Nov", now))
      assert_equal(Time.local( 2001,11,29,10,22),
                   Time.parse(           "10:22", now))
    end

    def test_invalid
      # They were actually used in some web sites.
      assert_raise(ArgumentError) { Time.httpdate("1 Dec 2001 10:23:57 GMT") }
      assert_raise(ArgumentError) { Time.httpdate("Sat, 1 Dec 2001 10:25:42 GMT") }
      assert_raise(ArgumentError) { Time.httpdate("Sat,  1-Dec-2001 10:53:55 GMT") }
      assert_raise(ArgumentError) { Time.httpdate("Saturday, 01-Dec-2001 10:15:34 GMT") }
      assert_raise(ArgumentError) { Time.httpdate("Saturday, 01-Dec-101 11:10:07 GMT") }
      assert_raise(ArgumentError) { Time.httpdate("Fri, 30 Nov 2001 21:30:00 JST") }

      # They were actually used in some mails.
      assert_raise(ArgumentError) { Time.rfc2822("01-5-20") }
      assert_raise(ArgumentError) { Time.rfc2822("7/21/00") }
      assert_raise(ArgumentError) { Time.rfc2822("2001-8-28") }
      assert_raise(ArgumentError) { Time.rfc2822("00-5-6 1:13:06") }
      assert_raise(ArgumentError) { Time.rfc2822("2001-9-27 9:36:49") }
      assert_raise(ArgumentError) { Time.rfc2822("2000-12-13 11:01:11") }
      assert_raise(ArgumentError) { Time.rfc2822("2001/10/17 04:29:55") }
      assert_raise(ArgumentError) { Time.rfc2822("9/4/2001 9:23:19 PM") }
      assert_raise(ArgumentError) { Time.rfc2822("01 Nov 2001 09:04:31") }
      assert_raise(ArgumentError) { Time.rfc2822("13 Feb 2001 16:4 GMT") }
      assert_raise(ArgumentError) { Time.rfc2822("01 Oct 00 5:41:19 PM") }
      assert_raise(ArgumentError) { Time.rfc2822("2 Jul 00 00:51:37 JST") }
      assert_raise(ArgumentError) { Time.rfc2822("01 11 2001 06:55:57 -0500") }
      assert_raise(ArgumentError) { Time.rfc2822("18 \343\366\356\341\370 2000") }
      assert_raise(ArgumentError) { Time.rfc2822("Fri, Oct 2001  18:53:32") }
      assert_raise(ArgumentError) { Time.rfc2822("Fri, 2 Nov 2001 03:47:54") }
      assert_raise(ArgumentError) { Time.rfc2822("Fri, 27 Jul 2001 11.14.14 +0200") }
      assert_raise(ArgumentError) { Time.rfc2822("Thu, 2 Nov 2000 04:13:53 -600") }
      assert_raise(ArgumentError) { Time.rfc2822("Wed, 5 Apr 2000 22:57:09 JST") }
      assert_raise(ArgumentError) { Time.rfc2822("Mon, 11 Sep 2000 19:47:33 00000") }
      assert_raise(ArgumentError) { Time.rfc2822("Fri, 28 Apr 2000 20:40:47 +-900") }
      assert_raise(ArgumentError) { Time.rfc2822("Fri, 19 Jan 2001 8:15:36 AM -0500") }
      assert_raise(ArgumentError) { Time.rfc2822("Thursday, Sep 27 2001 7:42:35 AM EST") }
      assert_raise(ArgumentError) { Time.rfc2822("3/11/2001 1:31:57 PM Pacific Daylight Time") }
      assert_raise(ArgumentError) { Time.rfc2822("Mi, 28 Mrz 2001 11:51:36") }
      assert_raise(ArgumentError) { Time.rfc2822("P, 30 sept 2001 23:03:14") }
      assert_raise(ArgumentError) { Time.rfc2822("fr, 11 aug 2000 18:39:22") }
      assert_raise(ArgumentError) { Time.rfc2822("Fr, 21 Sep 2001 17:44:03 -1000") }
      assert_raise(ArgumentError) { Time.rfc2822("Mo, 18 Jun 2001 19:21:40 -1000") }
      assert_raise(ArgumentError) { Time.rfc2822("l\366, 12 aug 2000 18:53:20") }
      assert_raise(ArgumentError) { Time.rfc2822("l\366, 26 maj 2001 00:15:58") }
      assert_raise(ArgumentError) { Time.rfc2822("Dom, 30 Sep 2001 17:36:30") }
      assert_raise(ArgumentError) { Time.rfc2822("%&, 31 %2/ 2000 15:44:47 -0500") }
      assert_raise(ArgumentError) { Time.rfc2822("dom, 26 ago 2001 03:57:07 -0300") }
      assert_raise(ArgumentError) { Time.rfc2822("ter, 04 set 2001 16:27:58 -0300") }
      assert_raise(ArgumentError) { Time.rfc2822("Wen, 3 oct 2001 23:17:49 -0400") }
      assert_raise(ArgumentError) { Time.rfc2822("Wen, 3 oct 2001 23:17:49 -0400") }
      assert_raise(ArgumentError) { Time.rfc2822("ele, 11 h: 2000 12:42:15 -0500") }
      assert_raise(ArgumentError) { Time.rfc2822("Tue, 14 Aug 2001 3:55:3 +0200") }
      assert_raise(ArgumentError) { Time.rfc2822("Fri, 25 Aug 2000 9:3:48 +0800") }
      assert_raise(ArgumentError) { Time.rfc2822("Fri, 1 Dec 2000 0:57:50 EST") }
      assert_raise(ArgumentError) { Time.rfc2822("Mon, 7 May 2001 9:39:51 +0200") }
      assert_raise(ArgumentError) { Time.rfc2822("Wed, 1 Aug 2001 16:9:15 +0200") }
      assert_raise(ArgumentError) { Time.rfc2822("Wed, 23 Aug 2000 9:17:36 +0800") }
      assert_raise(ArgumentError) { Time.rfc2822("Fri, 11 Aug 2000 10:4:42 +0800") }
      assert_raise(ArgumentError) { Time.rfc2822("Sat, 15 Sep 2001 13:22:2 +0300") }
      assert_raise(ArgumentError) { Time.rfc2822("Wed,16 \276\305\324\302 2001 20:06:25 +0800") }
      assert_raise(ArgumentError) { Time.rfc2822("Wed,7 \312\256\322\273\324\302 2001 23:47:22 +0800") }
      assert_raise(ArgumentError) { Time.rfc2822("=?iso-8859-1?Q?(=C5=DA),?= 10   2 2001 23:32:26 +0900 (JST)") }
      assert_raise(ArgumentError) { Time.rfc2822("\307\341\314\343\332\311, 30 \344\346\335\343\310\321 2001 10:01:06") }
      assert_raise(ArgumentError) { Time.rfc2822("=?iso-8859-1?Q?(=BF=E5),?= 12  =?iso-8859-1?Q?9=B7=EE?= 2001 14:52:41\n+0900 (JST)") }
    end

    def test_zone_0000
      assert_equal(true, Time.parse("2000-01-01T00:00:00Z").utc?)
      assert_equal(true, Time.parse("2000-01-01T00:00:00-00:00").utc?)
      assert_equal(false, Time.parse("2000-01-01T00:00:00+00:00").utc?)
      assert_equal(false, Time.parse("Sat, 01 Jan 2000 00:00:00 GMT").utc?)
      assert_equal(true, Time.parse("Sat, 01 Jan 2000 00:00:00 -0000").utc?)
      assert_equal(false, Time.parse("Sat, 01 Jan 2000 00:00:00 +0000").utc?)
      assert_equal(false, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 GMT").utc?)
      assert_equal(true, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 -0000").utc?)
      assert_equal(false, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 +0000").utc?)
      assert_equal(true, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 UTC").utc?)
    end

    def test_parse_leap_second
      t = Time.utc(1998,12,31,23,59,59)
      assert_equal(t, Time.parse("Thu Dec 31 23:59:59 UTC 1998"))
      assert_equal(t, Time.parse("Fri Dec 31 23:59:59 -0000 1998"));t.localtime
      assert_equal(t, Time.parse("Fri Jan  1 08:59:59 +0900 1999"))
      assert_equal(t, Time.parse("Fri Jan  1 00:59:59 +0100 1999"))
      assert_equal(t, Time.parse("Fri Dec 31 23:59:59 +0000 1998"))
      assert_equal(t, Time.parse("Fri Dec 31 22:59:59 -0100 1998"));t.utc
      t += 1
      assert_equal(t, Time.parse("Thu Dec 31 23:59:60 UTC 1998"))
      assert_equal(t, Time.parse("Fri Dec 31 23:59:60 -0000 1998"));t.localtime
      assert_equal(t, Time.parse("Fri Jan  1 08:59:60 +0900 1999"))
      assert_equal(t, Time.parse("Fri Jan  1 00:59:60 +0100 1999"))
      assert_equal(t, Time.parse("Fri Dec 31 23:59:60 +0000 1998"))
      assert_equal(t, Time.parse("Fri Dec 31 22:59:60 -0100 1998"));t.utc
      t += 1 if t.sec == 60
      assert_equal(t, Time.parse("Thu Jan  1 00:00:00 UTC 1999"))
      assert_equal(t, Time.parse("Fri Jan  1 00:00:00 -0000 1999"));t.localtime
      assert_equal(t, Time.parse("Fri Jan  1 09:00:00 +0900 1999"))
      assert_equal(t, Time.parse("Fri Jan  1 01:00:00 +0100 1999"))
      assert_equal(t, Time.parse("Fri Jan  1 00:00:00 +0000 1999"))
      assert_equal(t, Time.parse("Fri Dec 31 23:00:00 -0100 1998"))
    end

    def test_rfc2822_leap_second
      t = Time.utc(1998,12,31,23,59,59)
      assert_equal(t, Time.rfc2822("Thu, 31 Dec 1998 23:59:59 UTC"))
      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 -0000"));t.localtime                                  
      assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 08:59:59 +0900"))
      assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 00:59:59 +0100"))
      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 +0000"))
      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 22:59:59 -0100"));t.utc                                  
      t += 1
      assert_equal(t, Time.rfc2822("Thu, 31 Dec 1998 23:59:60 UTC"))
      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 -0000"));t.localtime                                  
      assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 08:59:60 +0900"))
      assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 00:59:60 +0100"))
      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 +0000"))
      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 22:59:60 -0100"));t.utc                                  
      t += 1 if t.sec == 60
      assert_equal(t, Time.rfc2822("Thu,  1 Jan 1999 00:00:00 UTC"))
      assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 00:00:00 -0000"));t.localtime                                  
      assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 09:00:00 +0900"))
      assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 01:00:00 +0100"))
      assert_equal(t, Time.rfc2822("Fri,  1 Jan 1999 00:00:00 +0000"))
      assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:00:00 -0100"))
    end

    def test_xmlschema_leap_second
      t = Time.utc(1998,12,31,23,59,59)
      assert_equal(t, Time.xmlschema("1998-12-31T23:59:59Z"))
      assert_equal(t, Time.xmlschema("1998-12-31T23:59:59-00:00"));t.localtime
      assert_equal(t, Time.xmlschema("1999-01-01T08:59:59+09:00"))
      assert_equal(t, Time.xmlschema("1999-01-01T00:59:59+01:00"))
      assert_equal(t, Time.xmlschema("1998-12-31T23:59:59+00:00"))
      assert_equal(t, Time.xmlschema("1998-12-31T22:59:59-01:00"));t.utc
      t += 1
      assert_equal(t, Time.xmlschema("1998-12-31T23:59:60Z"))
      assert_equal(t, Time.xmlschema("1998-12-31T23:59:60-00:00"));t.localtime
      assert_equal(t, Time.xmlschema("1999-01-01T08:59:60+09:00"))
      assert_equal(t, Time.xmlschema("1999-01-01T00:59:60+01:00"))
      assert_equal(t, Time.xmlschema("1998-12-31T23:59:60+00:00"))
      assert_equal(t, Time.xmlschema("1998-12-31T22:59:60-01:00"));t.utc
      t += 1 if t.sec == 60
      assert_equal(t, Time.xmlschema("1999-01-01T00:00:00Z"))
      assert_equal(t, Time.xmlschema("1999-01-01T00:00:00-00:00"));t.localtime
      assert_equal(t, Time.xmlschema("1999-01-01T09:00:00+09:00"))
      assert_equal(t, Time.xmlschema("1999-01-01T01:00:00+01:00"))
      assert_equal(t, Time.xmlschema("1999-01-01T00:00:00+00:00"))
      assert_equal(t, Time.xmlschema("1998-12-31T23:00:00-01:00"))
    end

    def test_ruby_talk_152866
      t = Time::xmlschema('2005-08-30T22:48:00-07:00')
      assert_equal(31, t.day)
      assert_equal(8, t.mon)
    end

    def test_parse_fraction
      assert_equal(500000, Time.parse("2000-01-01T00:00:00.5+00:00").tv_usec)
    end
  end
end
PK     Z\zU  U    erb.rbnu [        # = ERB -- Ruby Templating
#
# Author:: Masatoshi SEKI
# Documentation:: James Edward Gray II and Gavin Sinclair
#
# See ERB for primary documentation and ERB::Util for a couple of utility
# routines.
#
# Copyright (c) 1999-2000,2002,2003 Masatoshi SEKI
#
# You can redistribute it and/or modify it under the same terms as Ruby.

#
# = ERB -- Ruby Templating
#
# == Introduction
#
# ERB provides an easy to use but powerful templating system for Ruby.  Using
# ERB, actual Ruby code can be added to any plain text document for the
# purposes of generating document information details and/or flow control.
#
# A very simple example is this:
# 
#   require 'erb'
#
#   x = 42
#   template = ERB.new <<-EOF
#     The value of x is: <%= x %>
#   EOF
#   puts template.result(binding)
#
# <em>Prints:</em> The value of x is: 42
#
# More complex examples are given below.
#
#
# == Recognized Tags
#
# ERB recognizes certain tags in the provided template and converts them based
# on the rules below:
#
#   <% Ruby code -- inline with output %>
#   <%= Ruby expression -- replace with result %>
#   <%# comment -- ignored -- useful in testing %>
#   % a line of Ruby code -- treated as <% line %> (optional -- see ERB.new)
#   %% replaced with % if first thing on a line and % processing is used
#   <%% or %%> -- replace with <% or %> respectively
#
# All other text is passed through ERB filtering unchanged.
#
#
# == Options
#
# There are several settings you can change when you use ERB:
# * the nature of the tags that are recognized;
# * the value of <tt>$SAFE</tt> under which the template is run;
# * the binding used to resolve local variables in the template.
#
# See the ERB.new and ERB#result methods for more detail.
#
#
# == Examples
#
# === Plain Text
#
# ERB is useful for any generic templating situation.  Note that in this example, we use the
# convenient "% at start of line" tag, and we quote the template literally with
# <tt>%q{...}</tt> to avoid trouble with the backslash.
#
#   require "erb"
#   
#   # Create template.
#   template = %q{
#     From:  James Edward Gray II <james@grayproductions.net>
#     To:  <%= to %>
#     Subject:  Addressing Needs
#   
#     <%= to[/\w+/] %>:
#   
#     Just wanted to send a quick note assuring that your needs are being
#     addressed.
#   
#     I want you to know that my team will keep working on the issues,
#     especially:
#   
#     <%# ignore numerous minor requests -- focus on priorities %>
#     % priorities.each do |priority|
#       * <%= priority %>
#     % end
#   
#     Thanks for your patience.
#   
#     James Edward Gray II
#   }.gsub(/^  /, '')
#   
#   message = ERB.new(template, 0, "%<>")
#   
#   # Set up template data.
#   to = "Community Spokesman <spokesman@ruby_community.org>"
#   priorities = [ "Run Ruby Quiz",
#                  "Document Modules",
#                  "Answer Questions on Ruby Talk" ]
#   
#   # Produce result.
#   email = message.result
#   puts email
#
# <i>Generates:</i>
#
#   From:  James Edward Gray II <james@grayproductions.net>
#   To:  Community Spokesman <spokesman@ruby_community.org>
#   Subject:  Addressing Needs
#   
#   Community:
#   
#   Just wanted to send a quick note assuring that your needs are being addressed.
#   
#   I want you to know that my team will keep working on the issues, especially:
#   
#       * Run Ruby Quiz
#       * Document Modules
#       * Answer Questions on Ruby Talk
#   
#   Thanks for your patience.
#   
#   James Edward Gray II
#
# === Ruby in HTML
#
# ERB is often used in <tt>.rhtml</tt> files (HTML with embedded Ruby).  Notice the need in
# this example to provide a special binding when the template is run, so that the instance
# variables in the Product object can be resolved.
#
#   require "erb"
#   
#   # Build template data class.
#   class Product
#     def initialize( code, name, desc, cost )
#       @code = code
#       @name = name
#       @desc = desc
#       @cost = cost
#        	
#       @features = [ ]
#     end
#   
#     def add_feature( feature )
#       @features << feature
#     end
#   
#     # Support templating of member data.
#     def get_binding
#       binding
#     end
#   
#     # ...
#   end
#   
#   # Create template.
#   template = %{
#     <html>
#       <head><title>Ruby Toys -- <%= @name %></title></head>
#       <body>
#   
#         <h1><%= @name %> (<%= @code %>)</h1>
#         <p><%= @desc %></p>
#   
#         <ul>
#           <% @features.each do |f| %>
#             <li><b><%= f %></b></li>
#           <% end %>
#         </ul>
#   
#         <p>
#           <% if @cost < 10 %>
#             <b>Only <%= @cost %>!!!</b>
#           <% else %>
#              Call for a price, today!
#           <% end %>
#         </p>
#    
#       </body>
#     </html>
#   }.gsub(/^  /, '')
#   
#   rhtml = ERB.new(template)
#   
#   # Set up template data.
#   toy = Product.new( "TZ-1002",
#                      "Rubysapien",
#                      "Geek's Best Friend!  Responds to Ruby commands...",
#                      999.95 )
#   toy.add_feature("Listens for verbal commands in the Ruby language!")
#   toy.add_feature("Ignores Perl, Java, and all C variants.")
#   toy.add_feature("Karate-Chop Action!!!")
#   toy.add_feature("Matz signature on left leg.")
#   toy.add_feature("Gem studded eyes... Rubies, of course!")
#   
#   # Produce result.
#   rhtml.run(toy.get_binding)
#
# <i>Generates (some blank lines removed):</i>
#
#    <html>
#      <head><title>Ruby Toys -- Rubysapien</title></head>
#      <body>
#    
#        <h1>Rubysapien (TZ-1002)</h1>
#        <p>Geek's Best Friend!  Responds to Ruby commands...</p>
#    
#        <ul>
#            <li><b>Listens for verbal commands in the Ruby language!</b></li>
#            <li><b>Ignores Perl, Java, and all C variants.</b></li>
#            <li><b>Karate-Chop Action!!!</b></li>
#            <li><b>Matz signature on left leg.</b></li>
#            <li><b>Gem studded eyes... Rubies, of course!</b></li>
#        </ul>
#    
#        <p>
#             Call for a price, today!
#        </p>
#    
#      </body>
#    </html>
#
# 
# == Notes
#
# There are a variety of templating solutions available in various Ruby projects:
# * ERB's big brother, eRuby, works the same but is written in C for speed;
# * Amrita (smart at producing HTML/XML);
# * cs/Template (written in C for speed);
# * RDoc, distributed with Ruby, uses its own template engine, which can be reused elsewhere;
# * and others; search the RAA.
#
# Rails, the web application framework, uses ERB to create views.
#
class ERB
  Revision = '$Date: 2009-02-24 02:44:50 +0900 (Tue, 24 Feb 2009) $' 	#'

  # Returns revision information for the erb.rb module.
  def self.version
    "erb.rb [2.1.0 #{ERB::Revision.split[1]}]"
  end
end

#--
# ERB::Compiler
class ERB
  class Compiler # :nodoc:
    class PercentLine # :nodoc:
      def initialize(str)
        @value = str
      end
      attr_reader :value
      alias :to_s :value

      def empty?
        @value.empty?
      end
    end

    class Scanner # :nodoc:
      @scanner_map = {}
      def self.regist_scanner(klass, trim_mode, percent)
	@scanner_map[[trim_mode, percent]] = klass
      end

      def self.default_scanner=(klass)
	@default_scanner = klass
      end

      def self.make_scanner(src, trim_mode, percent)
	klass = @scanner_map.fetch([trim_mode, percent], @default_scanner)
	klass.new(src, trim_mode, percent)
      end

      def initialize(src, trim_mode, percent)
	@src = src
	@stag = nil
      end
      attr_accessor :stag

      def scan; end
    end

    class TrimScanner < Scanner # :nodoc:
      def initialize(src, trim_mode, percent)
	super
	@trim_mode = trim_mode
	@percent = percent
	if @trim_mode == '>'
	  @scan_line = self.method(:trim_line1)
	elsif @trim_mode == '<>'
	  @scan_line = self.method(:trim_line2)
	elsif @trim_mode == '-'
	  @scan_line = self.method(:explicit_trim_line)
	else
	  @scan_line = self.method(:scan_line)
	end
      end
      attr_accessor :stag
      
      def scan(&block)
	@stag = nil
	if @percent
	  @src.each do |line|
	    percent_line(line, &block)
	  end
	else
          @scan_line.call(@src, &block)
	end
	nil
      end

      def percent_line(line, &block)
	if @stag || line[0] != ?%
	  return @scan_line.call(line, &block)
	end

	line[0] = ''
	if line[0] == ?%
	  @scan_line.call(line, &block)
	else
          yield(PercentLine.new(line.chomp))
	end
      end

      def scan_line(line)
        line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>|\n|\z)/m) do |tokens|
          tokens.each do |token|
            next if token.empty?
            yield(token)
          end
	end
      end

      def trim_line1(line)
        line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
          tokens.each do |token|
            next if token.empty?
            if token == "%>\n"
              yield('%>')
              yield(:cr)
            else
              yield(token)
            end
          end
	end
      end

      def trim_line2(line)
	head = nil
        line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
          tokens.each do |token|
            next if token.empty?
            head = token unless head
            if token == "%>\n"
              yield('%>')
              if is_erb_stag?(head)
                yield(:cr)
              else
                yield("\n")
              end
              head = nil
            else
              yield(token)
              head = nil if token == "\n"
            end
          end
	end
      end

      def explicit_trim_line(line)
        line.scan(/(.*?)(^[ \t]*<%\-|<%\-|<%%|%%>|<%=|<%#|<%|-%>\n|-%>|%>|\z)/m) do |tokens|
          tokens.each do |token|
            next if token.empty?
            if @stag.nil? && /[ \t]*<%-/ =~ token
              yield('<%')
            elsif @stag && token == "-%>\n"
              yield('%>')
              yield(:cr)
            elsif @stag && token == '-%>'
              yield('%>')
            else
              yield(token)
            end
          end
        end
      end

      ERB_STAG = %w(<%= <%# <%)
      def is_erb_stag?(s)
	ERB_STAG.member?(s)
      end
    end

    Scanner.default_scanner = TrimScanner

    class SimpleScanner < Scanner # :nodoc:
      def scan
        @src.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>|\n|\z)/m) do |tokens|
          tokens.each do |token|
            next if token.empty?
            yield(token)
          end
	end
      end
    end
    
    Scanner.regist_scanner(SimpleScanner, nil, false)

    begin
      require 'strscan'
      class SimpleScanner2 < Scanner # :nodoc:
        def scan
          stag_reg = /(.*?)(<%%|<%=|<%#|<%|\z)/m
          etag_reg = /(.*?)(%%>|%>|\z)/m
          scanner = StringScanner.new(@src)
          while ! scanner.eos?
            scanner.scan(@stag ? etag_reg : stag_reg)
            yield(scanner[1])
            yield(scanner[2])
          end
        end
      end
      Scanner.regist_scanner(SimpleScanner2, nil, false)

      class ExplicitScanner < Scanner # :nodoc:
	def scan
          stag_reg = /(.*?)(^[ \t]*<%-|<%%|<%=|<%#|<%-|<%|\z)/m
          etag_reg = /(.*?)(%%>|-%>|%>|\z)/m
          scanner = StringScanner.new(@src)
          while ! scanner.eos?
	    scanner.scan(@stag ? etag_reg : stag_reg)
            yield(scanner[1])

            elem = scanner[2]
            if /[ \t]*<%-/ =~ elem
              yield('<%')
            elsif elem == '-%>'
	      yield('%>')
	      yield(:cr) if scanner.scan(/(\n|\z)/)
	    else
	      yield(elem)
	    end
          end
        end
      end
      Scanner.regist_scanner(ExplicitScanner, '-', false)

    rescue LoadError
    end

    class Buffer # :nodoc:
      def initialize(compiler)
	@compiler = compiler
	@line = []
	@script = ""
	@compiler.pre_cmd.each do |x|
	  push(x)
	end
      end
      attr_reader :script

      def push(cmd)
	@line << cmd
      end
      
      def cr
	@script << (@line.join('; '))
	@line = []
	@script << "\n"
      end
      
      def close
	return unless @line
	@compiler.post_cmd.each do |x|
	  push(x)
	end
	@script << (@line.join('; '))
	@line = nil
      end
    end

    def content_dump(s)
      n = s.count("\n")
      if n > 0
        s.dump + "\n" * n
      else
        s.dump
      end
    end

    def compile(s)
      out = Buffer.new(self)

      content = ''
      scanner = make_scanner(s)
      scanner.scan do |token|
        next if token.nil? 
        next if token == ''
	if scanner.stag.nil?
	  case token
          when PercentLine
	    out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
	    content = ''
            out.push(token.to_s)
            out.cr
	  when :cr
	    out.cr
	  when '<%', '<%=', '<%#'
	    scanner.stag = token
	    out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
	    content = ''
	  when "\n"
	    content << "\n"
	    out.push("#{@put_cmd} #{content_dump(content)}")
	    content = ''
	  when '<%%'
	    content << '<%'
	  else
	    content << token
	  end
	else
	  case token
	  when '%>'
	    case scanner.stag
	    when '<%'
	      if content[-1] == ?\n
		content.chop!
		out.push(content)
		out.cr
	      else
		out.push(content)
	      end
	    when '<%='
	      out.push("#{@insert_cmd}((#{content}).to_s)")
	    when '<%#'
	      # out.push("# #{content_dump(content)}")
	    end
	    scanner.stag = nil
	    content = ''
	  when '%%>'
	    content << '%>'
	  else
	    content << token
	  end
	end
      end
      out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
      out.close
      out.script
    end

    def prepare_trim_mode(mode)
      case mode
      when 1
	return [false, '>']
      when 2
	return [false, '<>']
      when 0
	return [false, nil]
      when String
	perc = mode.include?('%')
	if mode.include?('-')
	  return [perc, '-']
	elsif mode.include?('<>')
	  return [perc, '<>']
	elsif mode.include?('>')
	  return [perc, '>']
	else
	  [perc, nil]
	end
      else
	return [false, nil]
      end
    end

    def make_scanner(src)
      Scanner.make_scanner(src, @trim_mode, @percent)
    end

    def initialize(trim_mode)
      @percent, @trim_mode = prepare_trim_mode(trim_mode)
      @put_cmd = 'print'
      @insert_cmd = @put_cmd
      @pre_cmd = []
      @post_cmd = []
    end
    attr_reader :percent, :trim_mode
    attr_accessor :put_cmd, :insert_cmd, :pre_cmd, :post_cmd
  end
end

#--
# ERB
class ERB
  #
  # Constructs a new ERB object with the template specified in _str_.
  # 
  # An ERB object works by building a chunk of Ruby code that will output
  # the completed template when run. If _safe_level_ is set to a non-nil value,
  # ERB code will be run in a separate thread with <b>$SAFE</b> set to the
  # provided level.
  # 
  # If _trim_mode_ is passed a String containing one or more of the following
  # modifiers, ERB will adjust its code generation as listed:
  # 
  # 	%  enables Ruby code processing for lines beginning with %
  # 	<> omit newline for lines starting with <% and ending in %>
  # 	>  omit newline for lines ending in %>
  # 
  # _eoutvar_ can be used to set the name of the variable ERB will build up
  # its output in.  This is useful when you need to run multiple ERB
  # templates through the same binding and/or when you want to control where
  # output ends up.  Pass the name of the variable to be used inside a String.
  #
  # === Example
  #
  #  require "erb"
  #  
  #  # build data class
  #  class Listings
  #    PRODUCT = { :name => "Chicken Fried Steak",
  #                :desc => "A well messages pattie, breaded and fried.",
  #                :cost => 9.95 }
  #  
  #    attr_reader :product, :price
  #    
  #    def initialize( product = "", price = "" )
  #      @product = product
  #      @price = price
  #    end
  #    
  #    def build
  #      b = binding
  #      # create and run templates, filling member data variables
  #      ERB.new(<<-'END_PRODUCT'.gsub(/^\s+/, ""), 0, "", "@product").result b
  #        <%= PRODUCT[:name] %>
  #        <%= PRODUCT[:desc] %>
  #      END_PRODUCT
  #      ERB.new(<<-'END_PRICE'.gsub(/^\s+/, ""), 0, "", "@price").result b
  #        <%= PRODUCT[:name] %> -- <%= PRODUCT[:cost] %>
  #        <%= PRODUCT[:desc] %>
  #      END_PRICE
  #    end
  #  end
  #  
  #  # setup template data
  #  listings = Listings.new
  #  listings.build
  #  
  #  puts listings.product + "\n" + listings.price
  #
  # _Generates_
  #
  #  Chicken Fried Steak
  #  A well messages pattie, breaded and fried.
  #  
  #  Chicken Fried Steak -- 9.95
  #  A well messages pattie, breaded and fried.
  #  
  def initialize(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout')
    @safe_level = safe_level
    compiler = ERB::Compiler.new(trim_mode)
    set_eoutvar(compiler, eoutvar)
    @src = compiler.compile(str)
    @filename = nil
  end

  # The Ruby code generated by ERB
  attr_reader :src

  # The optional _filename_ argument passed to Kernel#eval when the ERB code
  # is run
  attr_accessor :filename

  #
  # Can be used to set _eoutvar_ as described in ERB#new.  It's probably easier
  # to just use the constructor though, since calling this method requires the
  # setup of an ERB _compiler_ object.
  #
  def set_eoutvar(compiler, eoutvar = '_erbout')
    compiler.put_cmd = "#{eoutvar}.concat"
    compiler.insert_cmd = "#{eoutvar}.concat"

    cmd = []
    cmd.push "#{eoutvar} = ''"
    
    compiler.pre_cmd = cmd

    cmd = []
    cmd.push(eoutvar)

    compiler.post_cmd = cmd
  end

  # Generate results and print them. (see ERB#result)
  def run(b=TOPLEVEL_BINDING)
    print self.result(b)
  end

  #
  # Executes the generated ERB code to produce a completed template, returning
  # the results of that code.  (See ERB#new for details on how this process can
  # be affected by _safe_level_.)
  # 
  # _b_ accepts a Binding or Proc object which is used to set the context of
  # code evaluation.
  #
  def result(b=TOPLEVEL_BINDING)
    if @safe_level
      proc { 
	$SAFE = @safe_level
	eval(@src, b, (@filename || '(erb)'), 1)
      }.call
    else
      eval(@src, b, (@filename || '(erb)'), 1)
    end
  end

  # Define _methodname_ as instance method of _mod_ from compiled ruby source.
  #
  # example:
  #   filename = 'example.rhtml'   # 'arg1' and 'arg2' are used in example.rhtml
  #   erb = ERB.new(File.read(filename))
  #   erb.def_method(MyClass, 'render(arg1, arg2)', filename)
  #   print MyClass.new.render('foo', 123)
  def def_method(mod, methodname, fname='(ERB)')
    mod.module_eval("def #{methodname}\n" + self.src + "\nend\n", fname, 0)
  end

  # Create unnamed module, define _methodname_ as instance method of it, and return it.
  #
  # example:
  #   filename = 'example.rhtml'   # 'arg1' and 'arg2' are used in example.rhtml
  #   erb = ERB.new(File.read(filename))
  #   erb.filename = filename
  #   MyModule = erb.def_module('render(arg1, arg2)')
  #   class MyClass
  #     include MyModule
  #   end
  def def_module(methodname='erb')
    mod = Module.new
    def_method(mod, methodname, @filename || '(ERB)')
    mod
  end

  # Define unnamed class which has _methodname_ as instance method, and return it.
  #
  # example:
  #   class MyClass_
  #     def initialize(arg1, arg2)
  #       @arg1 = arg1;  @arg2 = arg2
  #     end
  #   end
  #   filename = 'example.rhtml'  # @arg1 and @arg2 are used in example.rhtml
  #   erb = ERB.new(File.read(filename))
  #   erb.filename = filename
  #   MyClass = erb.def_class(MyClass_, 'render()')
  #   print MyClass.new('foo', 123).render()
  def def_class(superklass=Object, methodname='result')
    cls = Class.new(superklass)
    def_method(cls, methodname, @filename || '(ERB)')
    cls
  end
end

#--
# ERB::Util
class ERB
  # A utility module for conversion routines, often handy in HTML generation.
  module Util
    public
    #
    # A utility method for escaping HTML tag characters in _s_.
    # 
    # 	require "erb"
    # 	include ERB::Util
    # 	
    # 	puts html_escape("is a > 0 & a < 10?")
    # 
    # _Generates_
    # 
    # 	is a &gt; 0 &amp; a &lt; 10?
    #
    def html_escape(s)
      s.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
    end
    alias h html_escape
    module_function :h
    module_function :html_escape
    
    #
    # A utility method for encoding the String _s_ as a URL.
    # 
    # 	require "erb"
    # 	include ERB::Util
    # 	
    # 	puts url_encode("Programming Ruby:  The Pragmatic Programmer's Guide")
    # 
    # _Generates_
    # 
    # 	Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide
    #
    def url_encode(s)
      s.to_s.gsub(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) }
    end
    alias u url_encode
    module_function :u
    module_function :url_encode
  end
end

#--
# ERB::DefMethod
class ERB
  # Utility module to define eRuby script as instance method.
  #
  # === Example
  #
  # example.rhtml:
  #   <% for item in @items %>
  #   <b><%= item %></b>
  #   <% end %>
  #
  # example.rb:
  #   require 'erb'
  #   class MyClass
  #     extend ERB::DefMethod
  #     def_erb_method('render()', 'example.rhtml')
  #     def initialize(items)
  #       @items = items
  #     end
  #   end
  #   print MyClass.new([10,20,30]).render()
  #
  # result:
  #
  #   <b>10</b>
  #
  #   <b>20</b>
  #
  #   <b>30</b>
  #
  module DefMethod
    public
  # define _methodname_ as instance method of current module, using ERB object or eRuby file
    def def_erb_method(methodname, erb_or_fname)
      if erb_or_fname.kind_of? String
        fname = erb_or_fname
        erb = ERB.new(File.read(fname))
        erb.def_method(self, methodname, fname)
      else
        erb = erb_or_fname
        erb.def_method(self, methodname, erb.filename || '(ERB)')
      end
    end
    module_function :def_erb_method
  end
end
PK     Z\|  |    optparse.rbnu [        #
# optparse.rb - command-line option analysis with the OptionParser class.
# 
# Author:: Nobu Nakada
# Documentation:: Nobu Nakada and Gavin Sinclair.
#
# See OptionParser for documentation. 
#


# == Developer Documentation (not for RDoc output) 
# 
# === Class tree
#
# - OptionParser:: front end
# - OptionParser::Switch:: each switches
# - OptionParser::List:: options list
# - OptionParser::ParseError:: errors on parsing
#   - OptionParser::AmbiguousOption
#   - OptionParser::NeedlessArgument
#   - OptionParser::MissingArgument
#   - OptionParser::InvalidOption
#   - OptionParser::InvalidArgument
#     - OptionParser::AmbiguousArgument
#
# === Object relationship diagram
#
#   +--------------+
#   | OptionParser |<>-----+
#   +--------------+       |                      +--------+
#                          |                    ,-| Switch |
#        on_head -------->+---------------+    /  +--------+
#        accept/reject -->| List          |<|>-
#                         |               |<|>-  +----------+
#        on ------------->+---------------+    `-| argument |
#                           :           :        |  class   |
#                         +---------------+      |==========|
#        on_tail -------->|               |      |pattern   |
#                         +---------------+      |----------|
#   OptionParser.accept ->| DefaultList   |      |converter |
#                reject   |(shared between|      +----------+
#                         | all instances)|
#                         +---------------+
#
# == OptionParser
#
# === Introduction
#
# OptionParser is a class for command-line option analysis.  It is much more
# advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented
# solution.
#
# === Features
# 
# 1. The argument specification and the code to handle it are written in the
#    same place.
# 2. It can output an option summary; you don't need to maintain this string
#    separately.
# 3. Optional and mandatory arguments are specified very gracefully.
# 4. Arguments can be automatically converted to a specified class.
# 5. Arguments can be restricted to a certain set.
#
# All of these features are demonstrated in the examples below.
#
# === Minimal example
#
#   require 'optparse'
#
#   options = {}
#   OptionParser.new do |opts|
#     opts.banner = "Usage: example.rb [options]"
#
#     opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
#       options[:verbose] = v
#     end
#   end.parse!
#
#   p options
#   p ARGV
#
# === Complete example
#
# The following example is a complete Ruby program.  You can run it and see the
# effect of specifying various options.  This is probably the best way to learn
# the features of +optparse+.
#
#   require 'optparse'
#   require 'optparse/time'
#   require 'ostruct'
#   require 'pp'
#   
#   class OptparseExample
#   
#     CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
#     CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
#   
#     #
#     # Return a structure describing the options.
#     #
#     def self.parse(args)
#       # The options specified on the command line will be collected in *options*.
#       # We set default values here.
#       options = OpenStruct.new
#       options.library = []
#       options.inplace = false
#       options.encoding = "utf8"
#       options.transfer_type = :auto
#       options.verbose = false
#       
#       opts = OptionParser.new do |opts|
#         opts.banner = "Usage: example.rb [options]"
#       
#         opts.separator ""
#         opts.separator "Specific options:"
#       
#         # Mandatory argument.
#         opts.on("-r", "--require LIBRARY",
#                 "Require the LIBRARY before executing your script") do |lib|
#           options.library << lib
#         end
#       
#         # Optional argument; multi-line description.
#         opts.on("-i", "--inplace [EXTENSION]",
#                 "Edit ARGV files in place",
#                 "  (make backup if EXTENSION supplied)") do |ext|
#           options.inplace = true
#           options.extension = ext || ''
#           options.extension.sub!(/\A\.?(?=.)/, ".")  # Ensure extension begins with dot.
#         end
#       
#         # Cast 'delay' argument to a Float.
#         opts.on("--delay N", Float, "Delay N seconds before executing") do |n|
#           options.delay = n
#         end
#       
#         # Cast 'time' argument to a Time object.
#         opts.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
#           options.time = time
#         end
#       
#         # Cast to octal integer.
#         opts.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger,
#                 "Specify record separator (default \\0)") do |rs|
#           options.record_separator = rs
#         end
#       
#         # List of arguments.
#         opts.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
#           options.list = list
#         end
#       
#         # Keyword completion.  We are specifying a specific set of arguments (CODES
#         # and CODE_ALIASES - notice the latter is a Hash), and the user may provide
#         # the shortest unambiguous text.
#         code_list = (CODE_ALIASES.keys + CODES).join(',')
#         opts.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
#                 "  (#{code_list})") do |encoding|
#           options.encoding = encoding
#         end
#       
#         # Optional argument with keyword completion.
#         opts.on("--type [TYPE]", [:text, :binary, :auto],
#                 "Select transfer type (text, binary, auto)") do |t|
#           options.transfer_type = t
#         end
#       
#         # Boolean switch.
#         opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
#           options.verbose = v
#         end
#       
#         opts.separator ""
#         opts.separator "Common options:"
#       
#         # No argument, shows at tail.  This will print an options summary.
#         # Try it and see!
#         opts.on_tail("-h", "--help", "Show this message") do
#           puts opts
#           exit
#         end
#       
#         # Another typical switch to print the version.
#         opts.on_tail("--version", "Show version") do
#           puts OptionParser::Version.join('.')
#           exit
#         end
#       end
#       
#       opts.parse!(args)
#       options
#     end  # parse()
#   
#   end  # class OptparseExample
#   
#   options = OptparseExample.parse(ARGV)
#   pp options
#
# === Further documentation
#
# The above examples should be enough to learn how to use this class.  If you
# have any questions, email me (gsinclair@soyabean.com.au) and I will update
# this document.
#
class OptionParser
  # :stopdoc:
  RCSID = %w$Id: optparse.rb 22469 2009-02-20 11:43:35Z shyouhei $[1..-1].each {|s| s.freeze}.freeze
  Version = (RCSID[1].split('.').collect {|s| s.to_i}.extend(Comparable).freeze if RCSID[1])
  LastModified = (Time.gm(*RCSID[2, 2].join('-').scan(/\d+/).collect {|s| s.to_i}) if RCSID[2])
  Release = RCSID[2]

  NoArgument = [NO_ARGUMENT = :NONE, nil].freeze
  RequiredArgument = [REQUIRED_ARGUMENT = :REQUIRED, true].freeze
  OptionalArgument = [OPTIONAL_ARGUMENT = :OPTIONAL, false].freeze
  # :startdoc:

  #
  # Keyword completion module.  This allows partial arguments to be specified
  # and resolved against a list of acceptable values.
  #
  module Completion
    def complete(key, icase = false, pat = nil)
      pat ||= Regexp.new('\A' + Regexp.quote(key).gsub(/\w+\b/, '\&\w*'),
                         icase)
      canon, sw, k, v, cn = nil
      candidates = []
      each do |k, *v|
        (if Regexp === k
           kn = nil
           k === key
         else
           kn = defined?(k.id2name) ? k.id2name : k
           pat === kn
         end) or next
        v << k if v.empty?
        candidates << [k, v, kn]
      end
      candidates = candidates.sort_by {|k, v, kn| kn.size}
      if candidates.size == 1
        canon, sw, * = candidates[0]
      elsif candidates.size > 1
        canon, sw, cn = candidates.shift
        candidates.each do |k, v, kn|
          next if sw == v
          if String === cn and String === kn
            if cn.rindex(kn, 0)
              canon, sw, cn = k, v, kn
              next
            elsif kn.rindex(cn, 0)
              next
            end
          end
          throw :ambiguous, key
        end
      end
      if canon
        block_given? or return key, *sw
        yield(key, *sw)
      end
    end

    def convert(opt = nil, val = nil, *)
      val
    end
  end


  #
  # Map from option/keyword string to object with completion.
  #
  class OptionMap < Hash
    include Completion
  end


  #
  # Individual switch class.  Not important to the user.
  #
  # Defined within Switch are several Switch-derived classes: NoArgument,
  # RequiredArgument, etc. 
  #
  class Switch
    attr_reader :pattern, :conv, :short, :long, :arg, :desc, :block

    #
    # Guesses argument style from +arg+.  Returns corresponding
    # OptionParser::Switch class (OptionalArgument, etc.).
    #
    def self.guess(arg)
      case arg
      when ""
        t = self
      when /\A=?\[/
        t = Switch::OptionalArgument
      when /\A\s+\[/
        t = Switch::PlacedArgument
      else
        t = Switch::RequiredArgument
      end
      self >= t or incompatible_argument_styles(arg, t)
      t
    end

    def self.incompatible_argument_styles(arg, t)
      raise ArgumentError, "#{arg}: incompatible argument styles\n  #{self}, #{t}"
    end

    def self.pattern
      NilClass
    end

    def initialize(pattern = nil, conv = nil,
                   short = nil, long = nil, arg = nil,
                   desc = ([] if short or long), block = Proc.new)
      raise if Array === pattern
      @pattern, @conv, @short, @long, @arg, @desc, @block =
        pattern, conv, short, long, arg, desc, block
    end

    #
    # Parses +arg+ and returns rest of +arg+ and matched portion to the
    # argument pattern. Yields when the pattern doesn't match substring.
    #
    def parse_arg(arg)
      pattern or return nil, arg
      unless m = pattern.match(arg)
        yield(InvalidArgument, arg)
        return arg, nil
      end
      if String === m
        m = [s = m]
      else
        m = m.to_a
        s = m[0]
        return nil, m unless String === s
      end
      raise InvalidArgument, arg unless arg.rindex(s, 0)
      return nil, m if s.length == arg.length
      yield(InvalidArgument, arg) # didn't match whole arg
      return arg[s.length..-1], m
    end
    private :parse_arg

    #
    # Parses argument, converts and returns +arg+, +block+ and result of
    # conversion. Yields at semi-error condition instead of raising an
    # exception.
    #
    def conv_arg(arg, val = nil)
      if conv
        val = conv.call(*val)
      else
        val = proc {|val| val}.call(*val)
      end
      return arg, block, val
    end
    private :conv_arg

    #
    # Produces the summary text. Each line of the summary is yielded to the
    # block (without newline).
    #
    # +sdone+::  Already summarized short style options keyed hash.
    # +ldone+::  Already summarized long style options keyed hash.
    # +width+::  Width of left side (option part). In other words, the right
    #            side (description part) starts after +width+ columns.
    # +max+::    Maximum width of left side -> the options are filled within
    #            +max+ columns.
    # +indent+:: Prefix string indents all summarized lines.
    #
    def summarize(sdone = [], ldone = [], width = 1, max = width - 1, indent = "")
      sopts, lopts, s = [], [], nil
      @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
      @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
      return if sopts.empty? and lopts.empty? # completely hidden

      left = [sopts.join(', ')]
      right = desc.dup

      while s = lopts.shift
        l = left[-1].length + s.length
        l += arg.length if left.size == 1 && arg
        l < max or sopts.empty? or left << ''
        left[-1] << if left[-1].empty? then ' ' * 4 else ', ' end << s
      end

      left[0] << arg if arg
      mlen = left.collect {|s| s.length}.max.to_i
      while mlen > width and l = left.shift
        mlen = left.collect {|s| s.length}.max.to_i if l.length == mlen
        yield(indent + l)
      end

      while begin l = left.shift; r = right.shift; l or r end
        l = l.to_s.ljust(width) + ' ' + r if r and !r.empty?
        yield(indent + l)
      end

      self
    end

    def add_banner(to)  # :nodoc:
      unless @short or @long
        s = desc.join
        to << " [" + s + "]..." unless s.empty?
      end
      to
    end

    def match_nonswitch?(str) # :nodoc:
      @pattern =~ str unless @short or @long
    end

    #
    # Main name of the switch.
    #
    def switch_name
      (long.first || short.first).sub(/\A-+(?:\[no-\])?/, '')
    end

    #
    # Switch that takes no arguments.
    #
    class NoArgument < self

      #
      # Raises an exception if any arguments given.
      #
      def parse(arg, argv)
        yield(NeedlessArgument, arg) if arg
        conv_arg(arg)
      end

      def self.incompatible_argument_styles(*)
      end

      def self.pattern
        Object
      end
    end

    #
    # Switch that takes an argument.
    #
    class RequiredArgument < self

      #
      # Raises an exception if argument is not present.
      #
      def parse(arg, argv)
        unless arg
          raise MissingArgument if argv.empty?
          arg = argv.shift
        end
        conv_arg(*parse_arg(arg) {|*exc| raise(*exc)})
      end
    end

    #
    # Switch that can omit argument.
    #
    class OptionalArgument < self

      #
      # Parses argument if given, or uses default value.
      #
      def parse(arg, argv, &error)
        if arg
          conv_arg(*parse_arg(arg, &error))
        else
          conv_arg(arg)
        end
      end
    end

    #
    # Switch that takes an argument, which does not begin with '-'.
    #
    class PlacedArgument < self

      #
      # Returns nil if argument is not present or begins with '-'.
      #
      def parse(arg, argv, &error)
        if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
          return nil, block, nil
        end
        opt = (val = parse_arg(val, &error))[1]
        val = conv_arg(*val)
        if opt and !arg
          argv.shift
        else
          val[0] = nil
        end
        val
      end
    end
  end

  #
  # Simple option list providing mapping from short and/or long option
  # string to OptionParser::Switch and mapping from acceptable argument to
  # matching pattern and converter pair. Also provides summary feature.
  #
  class List
    # Map from acceptable argument types to pattern and converter pairs.
    attr_reader :atype
    
    # Map from short style option switches to actual switch objects.
    attr_reader :short
    
    # Map from long style option switches to actual switch objects.
    attr_reader :long
    
    # List of all switches and summary string.
    attr_reader :list

    #
    # Just initializes all instance variables.
    #
    def initialize
      @atype = {}
      @short = OptionMap.new
      @long = OptionMap.new
      @list = []
    end

    #
    # See OptionParser.accept.
    #
    def accept(t, pat = /.*/nm, &block)
      if pat
        pat.respond_to?(:match) or raise TypeError, "has no `match'"
      else
        pat = t if t.respond_to?(:match)
      end
      unless block
        block = pat.method(:convert).to_proc if pat.respond_to?(:convert)
      end
      @atype[t] = [pat, block]
    end

    #
    # See OptionParser.reject.
    #
    def reject(t)
      @atype.delete(t)
    end

    #
    # Adds +sw+ according to +sopts+, +lopts+ and +nlopts+.
    #
    # +sw+::     OptionParser::Switch instance to be added.
    # +sopts+::  Short style option list.
    # +lopts+::  Long style option list.
    # +nlopts+:: Negated long style options list.
    #
    def update(sw, sopts, lopts, nsw = nil, nlopts = nil)
      o = nil
      sopts.each {|o| @short[o] = sw} if sopts
      lopts.each {|o| @long[o] = sw} if lopts
      nlopts.each {|o| @long[o] = nsw} if nsw and nlopts
      used = @short.invert.update(@long.invert)
      @list.delete_if {|o| Switch === o and !used[o]}
    end
    private :update

    #
    # Inserts +switch+ at the head of the list, and associates short, long
    # and negated long options. Arguments are:
    # 
    # +switch+::      OptionParser::Switch instance to be inserted.
    # +short_opts+::  List of short style options.
    # +long_opts+::   List of long style options.
    # +nolong_opts+:: List of long style options with "no-" prefix.
    #
    #   prepend(switch, short_opts, long_opts, nolong_opts)
    #
    def prepend(*args)
      update(*args)
      @list.unshift(args[0])
    end

    #
    # Appends +switch+ at the tail of the list, and associates short, long
    # and negated long options. Arguments are:
    # 
    # +switch+::      OptionParser::Switch instance to be inserted.
    # +short_opts+::  List of short style options.
    # +long_opts+::   List of long style options.
    # +nolong_opts+:: List of long style options with "no-" prefix.
    #
    #   append(switch, short_opts, long_opts, nolong_opts)
    #
    def append(*args)
      update(*args)
      @list.push(args[0])
    end

    #
    # Searches +key+ in +id+ list. The result is returned or yielded if a
    # block is given. If it isn't found, nil is returned.
    #
    def search(id, key)
      if list = __send__(id)
        val = list.fetch(key) {return nil}
        block_given? ? yield(val) : val
      end
    end

    #
    # Searches list +id+ for +opt+ and the optional patterns for completion
    # +pat+. If +icase+ is true, the search is case insensitive. The result
    # is returned or yielded if a block is given. If it isn't found, nil is
    # returned.
    #
    def complete(id, opt, icase = false, *pat, &block)
      __send__(id).complete(opt, icase, *pat, &block)
    end

    #
    # Iterates over each option, passing the option to the +block+.
    #
    def each_option(&block)
      list.each(&block)
    end

    #
    # Creates the summary table, passing each line to the +block+ (without
    # newline). The arguments +args+ are passed along to the summarize
    # method which is called on every option.
    #
    def summarize(*args, &block)
      sum = []
      list.reverse_each do |opt|
        if opt.respond_to?(:summarize) # perhaps OptionParser::Switch
          s = []
          opt.summarize(*args) {|l| s << l}
          sum.concat(s.reverse)
        elsif !opt or opt.empty?
          sum << ""
        elsif opt.respond_to?(:each_line)
          sum.concat([*opt.each_line].reverse)
        else
          sum.concat([*opt.each].reverse)
        end
      end
      sum.reverse_each(&block)
    end

    def add_banner(to)  # :nodoc:
      list.each do |opt|
        if opt.respond_to?(:add_banner)
          opt.add_banner(to)
        end
      end
      to
    end
  end

  #
  # Hash with completion search feature. See OptionParser::Completion.
  #
  class CompletingHash < Hash
    include Completion

    #
    # Completion for hash key.
    #
    def match(key)
      return key, *fetch(key) {
        raise AmbiguousArgument, catch(:ambiguous) {return complete(key)}
      }
    end
  end

  # :stopdoc:

  #
  # Enumeration of acceptable argument styles. Possible values are:
  #
  # NO_ARGUMENT::       The switch takes no arguments. (:NONE)
  # REQUIRED_ARGUMENT:: The switch requires an argument. (:REQUIRED)
  # OPTIONAL_ARGUMENT:: The switch requires an optional argument. (:OPTIONAL)
  #
  # Use like --switch=argument (long style) or -Xargument (short style). For
  # short style, only portion matched to argument pattern is dealed as
  # argument.
  #
  ArgumentStyle = {}
  NoArgument.each {|el| ArgumentStyle[el] = Switch::NoArgument}
  RequiredArgument.each {|el| ArgumentStyle[el] = Switch::RequiredArgument}
  OptionalArgument.each {|el| ArgumentStyle[el] = Switch::OptionalArgument}
  ArgumentStyle.freeze

  #
  # Switches common used such as '--', and also provides default
  # argument classes
  #
  DefaultList = List.new
  DefaultList.short['-'] = Switch::NoArgument.new {}
  DefaultList.long[''] = Switch::NoArgument.new {throw :terminate}

  #
  # Default options for ARGV, which never appear in option summary.
  #
  Officious = {}

  #
  # --help
  # Shows option summary.
  #
  Officious['help'] = proc do |parser|
    Switch::NoArgument.new do
      puts parser.help
      exit
    end
  end

  #
  # --version
  # Shows version string if Version is defined.
  #
  Officious['version'] = proc do |parser|
    Switch::OptionalArgument.new do |pkg|
      if pkg
        begin
          require 'optparse/version'
        rescue LoadError
        else
          show_version(*pkg.split(/,/)) or
            abort("#{parser.program_name}: no version found in package #{pkg}")
          exit
        end
      end
      v = parser.ver or abort("#{parser.program_name}: version unknown")
      puts v
      exit
    end
  end

  # :startdoc:

  #
  # Class methods
  #

  #
  # Initializes a new instance and evaluates the optional block in context
  # of the instance. Arguments +args+ are passed to #new, see there for
  # description of parameters.
  # 
  # This method is *deprecated*, its behavior corresponds to the older #new
  # method.
  #
  def self.with(*args, &block)
    opts = new(*args)
    opts.instance_eval(&block)
    opts
  end

  #
  # Returns an incremented value of +default+ according to +arg+.
  #
  def self.inc(arg, default = nil)
    case arg
    when Integer
      arg.nonzero?
    when nil
      default.to_i + 1
    end
  end
  def inc(*args)
    self.class.inc(*args)
  end

  #
  # Initializes the instance and yields itself if called with a block.
  #
  # +banner+:: Banner message.
  # +width+::  Summary width.
  # +indent+:: Summary indent.
  #
  def initialize(banner = nil, width = 32, indent = ' ' * 4)
    @stack = [DefaultList, List.new, List.new]
    @program_name = nil
    @banner = banner
    @summary_width = width
    @summary_indent = indent
    @default_argv = ARGV
    add_officious
    yield self if block_given?
  end

  def add_officious  # :nodoc:
    list = base()
    Officious.each do |opt, block|
      list.long[opt] ||= block.call(self)
    end
  end

  #
  # Terminates option parsing. Optional parameter +arg+ is a string pushed
  # back to be the first non-option argument.
  #
  def terminate(arg = nil)
    self.class.terminate(arg)
  end
  def self.terminate(arg = nil)
    throw :terminate, arg
  end

  @stack = [DefaultList]
  def self.top() DefaultList end

  #
  # Directs to accept specified class +t+. The argument string is passed to
  # the block in which it should be converted to the desired class.
  #
  # +t+::   Argument class specifier, any object including Class.
  # +pat+:: Pattern for argument, defaults to +t+ if it responds to match.
  #
  #   accept(t, pat, &block)
  #
  def accept(*args, &blk) top.accept(*args, &blk) end
  #
  # See #accept.
  #
  def self.accept(*args, &blk) top.accept(*args, &blk) end

  #
  # Directs to reject specified class argument.
  #
  # +t+:: Argument class specifier, any object including Class.
  #
  #   reject(t)
  #
  def reject(*args, &blk) top.reject(*args, &blk) end
  #
  # See #reject.
  #
  def self.reject(*args, &blk) top.reject(*args, &blk) end

  #
  # Instance methods
  #

  # Heading banner preceding summary.
  attr_writer :banner

  # Program name to be emitted in error message and default banner,
  # defaults to $0.
  attr_writer :program_name

  # Width for option list portion of summary. Must be Numeric.
  attr_accessor :summary_width

  # Indentation for summary. Must be String (or have + String method).
  attr_accessor :summary_indent

  # Strings to be parsed in default.
  attr_accessor :default_argv

  #
  # Heading banner preceding summary.
  #
  def banner
    unless @banner
      @banner = "Usage: #{program_name} [options]"
      visit(:add_banner, @banner)
    end
    @banner
  end

  #
  # Program name to be emitted in error message and default banner, defaults
  # to $0.
  #
  def program_name
    @program_name || File.basename($0, '.*')
  end

  # for experimental cascading :-)
  alias set_banner banner=
  alias set_program_name program_name=
  alias set_summary_width summary_width=
  alias set_summary_indent summary_indent=

  # Version
  attr_writer :version
  # Release code
  attr_writer :release

  #
  # Version
  #
  def version
    @version || (defined?(::Version) && ::Version)
  end

  #
  # Release code
  #
  def release
    @release || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE)
  end

  #
  # Returns version string from program_name, version and release.
  #
  def ver
    if v = version
      str = "#{program_name} #{[v].join('.')}"
      str << " (#{v})" if v = release
      str
    end
  end

  def warn(mesg = $!)
    super("#{program_name}: #{mesg}")
  end

  def abort(mesg = $!)
    super("#{program_name}: #{mesg}")
  end

  #
  # Subject of #on / #on_head, #accept / #reject
  #
  def top
    @stack[-1]
  end

  #
  # Subject of #on_tail.
  #
  def base
    @stack[1]
  end

  #
  # Pushes a new List.
  #
  def new
    @stack.push(List.new)
    if block_given?
      yield self
    else
      self
    end
  end

  #
  # Removes the last List.
  #
  def remove
    @stack.pop
  end

  #
  # Puts option summary into +to+ and returns +to+. Yields each line if
  # a block is given.
  #
  # +to+:: Output destination, which must have method <<. Defaults to [].
  # +width+:: Width of left side, defaults to @summary_width.
  # +max+:: Maximum length allowed for left side, defaults to +width+ - 1.
  # +indent+:: Indentation, defaults to @summary_indent.
  #
  def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk)
    blk ||= proc {|l| to << (l.index($/, -1) ? l : l + $/)}
    visit(:summarize, {}, {}, width, max, indent, &blk)
    to
  end

  #
  # Returns option summary string.
  #
  def help; summarize(banner.to_s.sub(/\n?\z/, "\n")) end
  alias to_s help

  #
  # Returns option summary list.
  #
  def to_a; summarize(banner.to_a.dup) end

  #
  # Checks if an argument is given twice, in which case an ArgumentError is
  # raised. Called from OptionParser#switch only.
  #
  # +obj+:: New argument.
  # +prv+:: Previously specified argument.
  # +msg+:: Exception message.
  #
  def notwice(obj, prv, msg)
    unless !prv or prv == obj
      begin
        raise ArgumentError, "argument #{msg} given twice: #{obj}"
      rescue
        $@[0, 2] = nil
        raise
      end
    end
    obj
  end
  private :notwice

  #
  # Creates an OptionParser::Switch from the parameters. The parsed argument
  # value is passed to the given block, where it can be processed.
  #
  # See at the beginning of OptionParser for some full examples.
  #
  # +opts+ can include the following elements:
  #
  # [Argument style:]
  #   One of the following:
  #     :NONE, :REQUIRED, :OPTIONAL
  #
  # [Argument pattern:]
  #   Acceptable option argument format, must be pre-defined with
  #   OptionParser.accept or OptionParser#accept, or Regexp. This can appear
  #   once or assigned as String if not present, otherwise causes an
  #   ArgumentError. Examples:
  #     Float, Time, Array
  #
  # [Possible argument values:]
  #   Hash or Array.
  #     [:text, :binary, :auto]
  #     %w[iso-2022-jp shift_jis euc-jp utf8 binary]
  #     { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
  #
  # [Long style switch:]
  #   Specifies a long style switch which takes a mandatory, optional or no
  #   argument. It's a string of the following form:
  #     "--switch=MANDATORY" or "--switch MANDATORY"
  #     "--switch[=OPTIONAL]"
  #     "--switch"
  #
  # [Short style switch:]
  #   Specifies short style switch which takes a mandatory, optional or no
  #   argument. It's a string of the following form:
  #     "-xMANDATORY"
  #     "-x[OPTIONAL]"
  #     "-x"
  #   There is also a special form which matches character range (not full
  #   set of regular expression):
  #     "-[a-z]MANDATORY"
  #     "-[a-z][OPTIONAL]" 
  #     "-[a-z]"
  #
  # [Argument style and description:]
  #   Instead of specifying mandatory or optional arguments directly in the
  #   switch parameter, this separate parameter can be used.
  #     "=MANDATORY"
  #     "=[OPTIONAL]"
  #
  # [Description:]
  #   Description string for the option.
  #     "Run verbosely"
  # 
  # [Handler:]
  #   Handler for the parsed argument value. Either give a block or pass a
  #   Proc or Method as an argument.
  #
  def make_switch(opts, block = nil)
    short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], []
    ldesc, sdesc, desc, arg = [], [], []
    default_style = Switch::NoArgument
    default_pattern = nil
    klass = nil
    o = nil
    n, q, a = nil

    opts.each do |o|
      # argument class
      next if search(:atype, o) do |pat, c|
        klass = notwice(o, klass, 'type')
        if not_style and not_style != Switch::NoArgument
          not_pattern, not_conv = pat, c
        else
          default_pattern, conv = pat, c
        end
      end

      # directly specified pattern(any object possible to match)
      if !(String === o) and o.respond_to?(:match)
        pattern = notwice(o, pattern, 'pattern')
        conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
        next
      end

      # anything others
      case o
      when Proc, Method
        block = notwice(o, block, 'block')
      when Array, Hash
        case pattern
        when CompletingHash
        when nil
          pattern = CompletingHash.new
          conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
        else
          raise ArgumentError, "argument pattern given twice"
        end
        o.each {|(o, *v)| pattern[o] = v.fetch(0) {o}}
      when Module
        raise ArgumentError, "unsupported argument type: #{o}"
      when *ArgumentStyle.keys
        style = notwice(ArgumentStyle[o], style, 'style')
      when /^--no-([^\[\]=\s]*)(.+)?/
        q, a = $1, $2
        o = notwice(a ? Object : TrueClass, klass, 'type')
        not_pattern, not_conv = search(:atype, o) unless not_style
        not_style = (not_style || default_style).guess(arg = a) if a
        default_style = Switch::NoArgument
        default_pattern, conv = search(:atype, FalseClass) unless default_pattern
        ldesc << "--no-#{q}"
        long << 'no-' + (q = q.downcase)
        nolong << q
      when /^--\[no-\]([^\[\]=\s]*)(.+)?/
        q, a = $1, $2
        o = notwice(a ? Object : TrueClass, klass, 'type')
        if a
          default_style = default_style.guess(arg = a)
          default_pattern, conv = search(:atype, o) unless default_pattern
        end
        ldesc << "--[no-]#{q}"
        long << (o = q.downcase)
        not_pattern, not_conv = search(:atype, FalseClass) unless not_style
        not_style = Switch::NoArgument
        nolong << 'no-' + o
      when /^--([^\[\]=\s]*)(.+)?/
        q, a = $1, $2
        if a
          o = notwice(NilClass, klass, 'type')
          default_style = default_style.guess(arg = a)
          default_pattern, conv = search(:atype, o) unless default_pattern
        end
        ldesc << "--#{q}"
        long << (o = q.downcase)
      when /^-(\[\^?\]?(?:[^\\\]]|\\.)*\])(.+)?/
        q, a = $1, $2
        o = notwice(Object, klass, 'type')
        if a
          default_style = default_style.guess(arg = a)
          default_pattern, conv = search(:atype, o) unless default_pattern
        end
        sdesc << "-#{q}"
        short << Regexp.new(q)
      when /^-(.)(.+)?/
        q, a = $1, $2
        if a
          o = notwice(NilClass, klass, 'type')
          default_style = default_style.guess(arg = a)
          default_pattern, conv = search(:atype, o) unless default_pattern
        end
        sdesc << "-#{q}"
        short << q
      when /^=/
        style = notwice(default_style.guess(arg = o), style, 'style')
        default_pattern, conv = search(:atype, Object) unless default_pattern
      else
        desc.push(o)
      end
    end

    default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern
    if !(short.empty? and long.empty?)
      s = (style || default_style).new(pattern || default_pattern,
                                       conv, sdesc, ldesc, arg, desc, block)
    elsif !block
      raise ArgumentError, "no switch given" if style or pattern
      s = desc
    else
      short << pattern
      s = (style || default_style).new(pattern,
                                       conv, nil, nil, arg, desc, block)
    end
    return s, short, long,
      (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style),
      nolong
  end

  def define(*opts, &block)
    top.append(*(sw = make_switch(opts, block)))
    sw[0]
  end

  #
  # Add option switch and handler. See #make_switch for an explanation of
  # parameters.
  #
  def on(*opts, &block)
    define(*opts, &block)
    self
  end
  alias def_option define

  def define_head(*opts, &block)
    top.prepend(*(sw = make_switch(opts, block)))
    sw[0]
  end

  #
  # Add option switch like with #on, but at head of summary.
  #
  def on_head(*opts, &block)
    define_head(*opts, &block)
    self
  end
  alias def_head_option define_head

  def define_tail(*opts, &block)
    base.append(*(sw = make_switch(opts, block)))
    sw[0]
  end

  #
  # Add option switch like with #on, but at tail of summary.
  #
  def on_tail(*opts, &block)
    define_tail(*opts, &block)
    self
  end
  alias def_tail_option define_tail

  #
  # Add separator in summary.
  #
  def separator(string)
    top.append(string, nil, nil)
  end

  #
  # Parses command line arguments +argv+ in order. When a block is given,
  # each non-option argument is yielded.
  #
  # Returns the rest of +argv+ left unparsed.
  #
  def order(*argv, &block)
    argv = argv[0].dup if argv.size == 1 and Array === argv[0]
    order!(argv, &block)
  end

  #
  # Same as #order, but removes switches destructively.
  #
  def order!(argv = default_argv, &nonopt)
    parse_in_order(argv, &nonopt)
  end

  def parse_in_order(argv = default_argv, setter = nil, &nonopt)  # :nodoc:
    opt, arg, sw, val, rest = nil
    nonopt ||= proc {|arg| throw :terminate, arg}
    argv.unshift(arg) if arg = catch(:terminate) {
      while arg = argv.shift
        case arg
        # long option
        when /\A--([^=]*)(?:=(.*))?/nm
          opt, rest = $1, $2
          begin
            sw, = complete(:long, opt, true)
          rescue ParseError
            raise $!.set_option(arg, true)
          end
          begin
            opt, cb, val = sw.parse(rest, argv) {|*exc| raise(*exc)}
            val = cb.call(val) if cb
            setter.call(sw.switch_name, val) if setter
          rescue ParseError
            raise $!.set_option(arg, rest)
          end

        # short option
        when /\A-(.)((=).*|.+)?/nm
          opt, has_arg, eq, val, rest = $1, $3, $3, $2, $2
          begin
            sw, = search(:short, opt)
            unless sw
              begin
                sw, = complete(:short, opt)
                # short option matched.
                val = arg.sub(/\A-/, '')
                has_arg = true
              rescue InvalidOption
                # if no short options match, try completion with long
                # options.
                sw, = complete(:long, opt)
                eq ||= !rest
              end
            end
          rescue ParseError
            raise $!.set_option(arg, true)
          end
          begin
            opt, cb, val = sw.parse(val, argv) {|*exc| raise(*exc) if eq}
            raise InvalidOption, arg if has_arg and !eq and arg == "-#{opt}"
            argv.unshift(opt) if opt and (opt = opt.sub(/\A-*/, '-')) != '-'
            val = cb.call(val) if cb
            setter.call(sw.switch_name, val) if setter
          rescue ParseError
            raise $!.set_option(arg, arg.length > 2)
          end

        # non-option argument
        else
          catch(:prune) do
            visit(:each_option) do |sw|
              sw.block.call(arg) if Switch === sw and sw.match_nonswitch?(arg)
            end
            nonopt.call(arg)
          end
        end
      end

      nil
    }

    visit(:search, :short, nil) {|sw| sw.block.call(*argv) if !sw.pattern}

    argv
  end
  private :parse_in_order

  #
  # Parses command line arguments +argv+ in permutation mode and returns
  # list of non-option arguments.
  #
  def permute(*argv)
    argv = argv[0].dup if argv.size == 1 and Array === argv[0]
    permute!(argv)
  end

  #
  # Same as #permute, but removes switches destructively.
  #
  def permute!(argv = default_argv)
    nonopts = []
    arg = nil
    order!(argv) {|arg| nonopts << arg}
    argv[0, 0] = nonopts
    argv
  end

  #
  # Parses command line arguments +argv+ in order when environment variable
  # POSIXLY_CORRECT is set, and in permutation mode otherwise.
  #
  def parse(*argv)
    argv = argv[0].dup if argv.size == 1 and Array === argv[0]
    parse!(argv)
  end

  #
  # Same as #parse, but removes switches destructively.
  #
  def parse!(argv = default_argv)
    if ENV.include?('POSIXLY_CORRECT')
      order!(argv)
    else
      permute!(argv)
    end
  end

  #
  # Wrapper method for getopts.rb.
  #
  #   params = ARGV.getopts("ab:", "foo", "bar:")
  #   # params[:a] = true   # -a
  #   # params[:b] = "1"    # -b1
  #   # params[:foo] = "1"  # --foo
  #   # params[:bar] = "x"  # --bar x
  #
  def getopts(*args)
    argv = Array === args.first ? args.shift : default_argv
    single_options, *long_options = *args

    result = {}

    single_options.scan(/(.)(:)?/) do |opt, val|
      if val
        result[opt] = nil
        define("-#{opt} VAL")
      else
        result[opt] = false
        define("-#{opt}")
      end
    end if single_options

    long_options.each do |arg|
      opt, val = arg.split(':', 2)
      if val
        result[opt] = val.empty? ? nil : val
        define("--#{opt} VAL")
      else
        result[opt] = false
        define("--#{opt}")
      end
    end

    parse_in_order(argv, result.method(:[]=))
    result
  end

  #
  # See #getopts.
  #
  def self.getopts(*args)
    new.getopts(*args)
  end

  #
  # Traverses @stack, sending each element method +id+ with +args+ and
  # +block+.
  #
  def visit(id, *args, &block)
    el = nil
    @stack.reverse_each do |el|
      el.send(id, *args, &block)
    end
    nil
  end
  private :visit

  #
  # Searches +key+ in @stack for +id+ hash and returns or yields the result.
  #
  def search(id, key)
    block_given = block_given?
    visit(:search, id, key) do |k|
      return block_given ? yield(k) : k
    end
  end
  private :search

  #
  # Completes shortened long style option switch and returns pair of
  # canonical switch and switch descriptor OptionParser::Switch.
  #
  # +id+::    Searching table.
  # +opt+::   Searching key.
  # +icase+:: Search case insensitive if true.
  # +pat+::   Optional pattern for completion.
  #
  def complete(typ, opt, icase = false, *pat)
    if pat.empty?
      search(typ, opt) {|sw| return [sw, opt]} # exact match or...
    end
    raise AmbiguousOption, catch(:ambiguous) {
      visit(:complete, typ, opt, icase, *pat) {|opt, *sw| return sw}
      raise InvalidOption, opt
    }
  end
  private :complete

  #
  # Loads options from file names as +filename+. Does nothing when the file
  # is not present. Returns whether successfully loaded.
  #
  # +filename+ defaults to basename of the program without suffix in a
  # directory ~/.options.
  #
  def load(filename = nil)
    begin
      filename ||= File.expand_path(File.basename($0, '.*'), '~/.options')
    rescue
      return false
    end
    begin
      parse(*IO.readlines(filename).each {|s| s.chomp!})
      true
    rescue Errno::ENOENT, Errno::ENOTDIR
      false
    end
  end

  #
  # Parses environment variable +env+ or its uppercase with splitting like a
  # shell.
  #
  # +env+ defaults to the basename of the program.
  #
  def environment(env = File.basename($0, '.*'))
    env = ENV[env] || ENV[env.upcase] or return
    require 'shellwords'
    parse(*Shellwords.shellwords(env))
  end

  #
  # Acceptable argument classes
  #

  #
  # Any string and no conversion. This is fall-back.
  #
  accept(Object) {|s,|s or s.nil?}

  accept(NilClass) {|s,|s}

  #
  # Any non-empty string, and no conversion.
  #
  accept(String, /.+/nm) {|s,*|s}

  #
  # Ruby/C-like integer, octal for 0-7 sequence, binary for 0b, hexadecimal
  # for 0x, and decimal for others; with optional sign prefix. Converts to
  # Integer.
  #
  decimal = '\d+(?:_\d+)*'
  binary = 'b[01]+(?:_[01]+)*'
  hex = 'x[\da-f]+(?:_[\da-f]+)*'
  octal = "0(?:[0-7]*(?:_[0-7]+)*|#{binary}|#{hex})"
  integer = "#{octal}|#{decimal}"
  accept(Integer, %r"\A[-+]?(?:#{integer})"io) {|s,| Integer(s) if s}

  #
  # Float number format, and converts to Float.
  #
  float = "(?:#{decimal}(?:\\.(?:#{decimal})?)?|\\.#{decimal})(?:E[-+]?#{decimal})?"
  floatpat = %r"\A[-+]?#{float}"io
  accept(Float, floatpat) {|s,| s.to_f if s}

  #
  # Generic numeric format, converts to Integer for integer format, Float
  # for float format.
  #
  accept(Numeric, %r"\A[-+]?(?:#{octal}|#{float})"io) {|s,| eval(s) if s}

  #
  # Decimal integer format, to be converted to Integer.
  #
  DecimalInteger = /\A[-+]?#{decimal}/io
  accept(DecimalInteger) {|s,| s.to_i if s}

  #
  # Ruby/C like octal/hexadecimal/binary integer format, to be converted to
  # Integer.
  #
  OctalInteger = /\A[-+]?(?:[0-7]+(?:_[0-7]+)*|0(?:#{binary}|#{hex}))/io
  accept(OctalInteger) {|s,| s.oct if s}

  #
  # Decimal integer/float number format, to be converted to Integer for
  # integer format, Float for float format.
  #
  DecimalNumeric = floatpat     # decimal integer is allowed as float also.
  accept(DecimalNumeric) {|s,| eval(s) if s}

  #
  # Boolean switch, which means whether it is present or not, whether it is
  # absent or not with prefix no-, or it takes an argument
  # yes/no/true/false/+/-.
  #
  yesno = CompletingHash.new
  %w[- no false].each {|el| yesno[el] = false}
  %w[+ yes true].each {|el| yesno[el] = true}
  yesno['nil'] = false          # shoud be nil?
  accept(TrueClass, yesno) {|arg, val| val == nil or val}
  #
  # Similar to TrueClass, but defaults to false.
  #
  accept(FalseClass, yesno) {|arg, val| val != nil and val}

  #
  # List of strings separated by ",".
  #
  accept(Array) do |s,|
    if s
      s = s.split(',').collect {|s| s unless s.empty?}
    end
    s
  end

  #
  # Regular expression with options.
  #
  accept(Regexp, %r"\A/((?:\\.|[^\\])*)/([[:alpha:]]+)?\z|.*") do |all, s, o|
    f = 0
    if o
      f |= Regexp::IGNORECASE if /i/ =~ o
      f |= Regexp::MULTILINE if /m/ =~ o
      f |= Regexp::EXTENDED if /x/ =~ o
      k = o.delete("^imx")
    end
    Regexp.new(s || all, f, k)
  end

  #
  # Exceptions
  #

  #
  # Base class of exceptions from OptionParser.
  #
  class ParseError < RuntimeError
    # Reason which caused the error.
    Reason = 'parse error'.freeze

    def initialize(*args)
      @args = args
      @reason = nil
    end

    attr_reader :args
    attr_writer :reason

    #
    # Pushes back erred argument(s) to +argv+.
    #
    def recover(argv)
      argv[0, 0] = @args
      argv
    end

    def set_option(opt, eq)
      if eq
        @args[0] = opt
      else
        @args.unshift(opt)
      end
      self
    end

    #
    # Returns error reason. Override this for I18N.
    #
    def reason
      @reason || self.class::Reason
    end

    def inspect
      "#<#{self.class.to_s}: #{args.join(' ')}>"
    end

    #
    # Default stringizing method to emit standard error message.
    #
    def message
      reason + ': ' + args.join(' ')
    end

    alias to_s message
  end

  #
  # Raises when ambiguously completable string is encountered.
  #
  class AmbiguousOption < ParseError
    const_set(:Reason, 'ambiguous option'.freeze)
  end

  #
  # Raises when there is an argument for a switch which takes no argument.
  #
  class NeedlessArgument < ParseError
    const_set(:Reason, 'needless argument'.freeze)
  end

  #
  # Raises when a switch with mandatory argument has no argument.
  #
  class MissingArgument < ParseError
    const_set(:Reason, 'missing argument'.freeze)
  end

  #
  # Raises when switch is undefined.
  #
  class InvalidOption < ParseError
    const_set(:Reason, 'invalid option'.freeze)
  end

  #
  # Raises when the given argument does not match required format.
  #
  class InvalidArgument < ParseError
    const_set(:Reason, 'invalid argument'.freeze)
  end

  #
  # Raises when the given argument word can't be completed uniquely.
  #
  class AmbiguousArgument < InvalidArgument
    const_set(:Reason, 'ambiguous argument'.freeze)
  end

  #
  # Miscellaneous
  #

  #
  # Extends command line arguments array (ARGV) to parse itself.
  #
  module Arguable

    #
    # Sets OptionParser object, when +opt+ is +false+ or +nil+, methods
    # OptionParser::Arguable#options and OptionParser::Arguable#options= are
    # undefined. Thus, there is no ways to access the OptionParser object
    # via the receiver object.
    #
    def options=(opt)
      unless @optparse = opt
        class << self
          undef_method(:options)
          undef_method(:options=)
        end
      end
    end

    #
    # Actual OptionParser object, automatically created if nonexistent.
    #
    # If called with a block, yields the OptionParser object and returns the
    # result of the block. If an OptionParser::ParseError exception occurs
    # in the block, it is rescued, a error message printed to STDERR and
    # +nil+ returned.
    #
    def options
      @optparse ||= OptionParser.new
      @optparse.default_argv = self
      block_given? or return @optparse
      begin
        yield @optparse
      rescue ParseError
        @optparse.warn $!
        nil
      end
    end

    #
    # Parses +self+ destructively in order and returns +self+ containing the
    # rest arguments left unparsed.
    #
    def order!(&blk) options.order!(self, &blk) end

    #
    # Parses +self+ destructively in permutation mode and returns +self+
    # containing the rest arguments left unparsed.
    #
    def permute!() options.permute!(self) end

    #
    # Parses +self+ destructively and returns +self+ containing the
    # rest arguments left unparsed.
    #
    def parse!() options.parse!(self) end

    #
    # Substitution of getopts is possible as follows. Also see
    # OptionParser#getopts.
    #
    #   def getopts(*args)
    #     ($OPT = ARGV.getopts(*args)).each do |opt, val|
    #       eval "$OPT_#{opt.gsub(/[^A-Za-z0-9_]/, '_')} = val"
    #     end
    #   rescue OptionParser::ParseError
    #   end
    #
    def getopts(*args)
      options.getopts(self, *args)
    end

    #
    # Initializes instance variable.
    #
    def self.extend_object(obj)
      super
      obj.instance_eval {@optparse = nil}
    end
    def initialize(*args)
      super
      @optparse = nil
    end
  end

  #
  # Acceptable argument classes. Now contains DecimalInteger, OctalInteger
  # and DecimalNumeric. See Acceptable argument classes (in source code).
  #
  module Acceptables
    const_set(:DecimalInteger, OptionParser::DecimalInteger)
    const_set(:OctalInteger, OptionParser::OctalInteger)
    const_set(:DecimalNumeric, OptionParser::DecimalNumeric)
  end
end

# ARGV is arguable by OptionParser
ARGV.extend(OptionParser::Arguable)

if $0 == __FILE__
  Version = OptionParser::Version
  ARGV.options {|q|
    q.parse!.empty? or puts "what's #{ARGV.join(' ')}?"
  } or abort(ARGV.options.to_s)
end
PK     Z\O      mkmf.rbnu [        # module to create Makefile for extension modules
# invoke like: ruby -r mkmf extconf.rb

require 'rbconfig'
require 'fileutils'
require 'shellwords'

CONFIG = Config::MAKEFILE_CONFIG
ORIG_LIBPATH = ENV['LIB']

CXX_EXT = %w[cc cxx cpp]
if /mswin|bccwin|mingw|msdosdjgpp|human|os2/ !~ CONFIG['build_os']
  CXX_EXT.concat(%w[C])
end
SRC_EXT = %w[c m].concat(CXX_EXT)
$static = $config_h = nil
$default_static = $static

unless defined? $configure_args
  $configure_args = {}
  args = CONFIG["configure_args"]
  if ENV["CONFIGURE_ARGS"]
    args << " " << ENV["CONFIGURE_ARGS"]
  end
  for arg in Shellwords::shellwords(args)
    arg, val = arg.split('=', 2)
    next unless arg
    arg.tr!('_', '-')
    if arg.sub!(/^(?!--)/, '--')
      val or next
      arg.downcase!
    end
    next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
    $configure_args[arg] = val || true
  end
  for arg in ARGV
    arg, val = arg.split('=', 2)
    next unless arg
    arg.tr!('_', '-')
    if arg.sub!(/^(?!--)/, '--')
      val or next
      arg.downcase!
    end
    $configure_args[arg] = val || true
  end
end

$libdir = CONFIG["libdir"]
$rubylibdir = CONFIG["rubylibdir"]
$archdir = CONFIG["archdir"]
$sitedir = CONFIG["sitedir"]
$sitelibdir = CONFIG["sitelibdir"]
$sitearchdir = CONFIG["sitearchdir"]
$vendordir = CONFIG["vendordir"]
$vendorlibdir = CONFIG["vendorlibdir"]
$vendorarchdir = CONFIG["vendorarchdir"]

$mswin = /mswin/ =~ RUBY_PLATFORM
$bccwin = /bccwin/ =~ RUBY_PLATFORM
$mingw = /mingw/ =~ RUBY_PLATFORM
$cygwin = /cygwin/ =~ RUBY_PLATFORM
$human = /human/ =~ RUBY_PLATFORM
$netbsd = /netbsd/ =~ RUBY_PLATFORM
$os2 = /os2/ =~ RUBY_PLATFORM
$beos = /beos/ =~ RUBY_PLATFORM
$solaris = /solaris/ =~ RUBY_PLATFORM
$dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)

# :stopdoc:

def config_string(key, config = CONFIG)
  s = config[key] and !s.empty? and block_given? ? yield(s) : s
end

def dir_re(dir)
  Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?')
end

INSTALL_DIRS = [
  [dir_re('commondir'), "$(RUBYCOMMONDIR)"],
  [dir_re('sitedir'), "$(RUBYCOMMONDIR)"],
  [dir_re('vendordir'), "$(RUBYCOMMONDIR)"],
  [dir_re('rubylibdir'), "$(RUBYLIBDIR)"],
  [dir_re('archdir'), "$(RUBYARCHDIR)"],
  [dir_re('sitelibdir'), "$(RUBYLIBDIR)"],
  [dir_re('vendorlibdir'), "$(RUBYLIBDIR)"],
  [dir_re('sitearchdir'), "$(RUBYARCHDIR)"],
  [dir_re('bindir'), "$(BINDIR)"],
  [dir_re('vendorarchdir'), "$(RUBYARCHDIR)"],
]

def install_dirs(target_prefix = nil)
  if $extout
    dirs = [
      ['BINDIR',        '$(extout)/bin'],
      ['RUBYCOMMONDIR', '$(extout)/common'],
      ['RUBYLIBDIR',    '$(RUBYCOMMONDIR)$(target_prefix)'],
      ['RUBYARCHDIR',   '$(extout)/$(arch)$(target_prefix)'],
      ['extout',        "#$extout"],
      ['extout_prefix', "#$extout_prefix"],
    ]
  elsif $extmk
    dirs = [
      ['BINDIR',        '$(bindir)'],
      ['RUBYCOMMONDIR', '$(rubylibdir)'],
      ['RUBYLIBDIR',    '$(rubylibdir)$(target_prefix)'],
      ['RUBYARCHDIR',   '$(archdir)$(target_prefix)'],
    ]
  elsif $configure_args.has_key?('--vendor')
    dirs = [
      ['BINDIR',        '$(bindir)'],
      ['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'],
      ['RUBYLIBDIR',    '$(vendorlibdir)$(target_prefix)'],
      ['RUBYARCHDIR',   '$(vendorarchdir)$(target_prefix)'],
    ]
  else
    dirs = [
      ['BINDIR',        '$(bindir)'],
      ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'],
      ['RUBYLIBDIR',    '$(sitelibdir)$(target_prefix)'],
      ['RUBYARCHDIR',   '$(sitearchdir)$(target_prefix)'],
    ]
  end
  dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
  dirs
end

def map_dir(dir, map = nil)
  map ||= INSTALL_DIRS
  map.inject(dir) {|dir, (orig, new)| dir.gsub(orig, new)}
end

topdir = File.dirname(libdir = File.dirname(__FILE__))
extdir = File.expand_path("ext", topdir)
$extmk = File.expand_path($0)[0, extdir.size+1] == extdir+"/"
if not $extmk and File.exist?(($hdrdir = Config::CONFIG["archdir"]) + "/ruby.h")
  $topdir = $hdrdir
elsif File.exist?(($hdrdir = ($top_srcdir ||= topdir))  + "/ruby.h") and
    File.exist?(($topdir ||= Config::CONFIG["topdir"]) + "/config.h")
else
  abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
end

OUTFLAG = CONFIG['OUTFLAG']
CPPOUTFILE = CONFIG['CPPOUTFILE']

CONFTEST_C = "conftest.c"

class String
  # Wraps a string in escaped quotes if it contains whitespace.
  def quote
    /\s/ =~ self ? "\"#{self}\"" : "#{self}"
  end

  # Generates a string used as cpp macro name.
  def tr_cpp
    strip.upcase.tr_s("^A-Z0-9_", "_")
  end
end
class Array
  # Wraps all strings in escaped quotes if they contain whitespace.
  def quote
    map {|s| s.quote}
  end
end

def rm_f(*files)
  FileUtils.rm_f(Dir[files.join("\0")])
end

# Returns time stamp of the +target+ file if it exists and is newer
# than or equal to all of +times+.
def modified?(target, times)
  (t = File.mtime(target)) rescue return nil
  Array === times or times = [times]
  t if times.all? {|n| n <= t}
end

def merge_libs(*libs)
  libs.inject([]) do |x, y|
    xy = x & y
    xn = yn = 0
    y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
    y.each_with_index do |v, yi|
      if xy.include?(v)
        xi = [x.index(v), xn].max()
        x[xi, 1] = y[yn..yi]
        xn, yn = xi + (yi - yn + 1), yi + 1
      end
    end
    x.concat(y[yn..-1] || [])
  end
end

# This is a custom logging module. It generates an mkmf.log file when you
# run your extconf.rb script. This can be useful for debugging unexpected
# failures.
#
# This module and its associated methods are meant for internal use only.
#
module Logging
  @log = nil
  @logfile = 'mkmf.log'
  @orgerr = $stderr.dup
  @orgout = $stdout.dup
  @postpone = 0
  @quiet = $extmk

  def self::open
    @log ||= File::open(@logfile, 'w')
    @log.sync = true
    $stderr.reopen(@log)
    $stdout.reopen(@log)
    yield
  ensure
    $stderr.reopen(@orgerr)
    $stdout.reopen(@orgout)
  end

  def self::message(*s)
    @log ||= File::open(@logfile, 'w')
    @log.sync = true
    @log.printf(*s)
  end

  def self::logfile file
    @logfile = file
    if @log and not @log.closed?
      @log.flush
      @log.close
      @log = nil
    end
  end
  
  def self::postpone
    tmplog = "mkmftmp#{@postpone += 1}.log"
    open do
      log, *save = @log, @logfile, @orgout, @orgerr
      @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
      begin
        log.print(open {yield})
        @log.close
        File::open(tmplog) {|t| FileUtils.copy_stream(t, log)}
      ensure
        @log, @logfile, @orgout, @orgerr = log, *save
        @postpone -= 1
        rm_f tmplog
      end
    end
  end

  class << self
    attr_accessor :quiet
  end
end

def xsystem command
  varpat = /\$\((\w+)\)|\$\{(\w+)\}/
  if varpat =~ command
    vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
    command = command.dup
    nil while command.gsub!(varpat) {vars[$1||$2]}
  end
  Logging::open do
    puts command.quote
    system(command)
  end
end

def xpopen command, *mode, &block
  Logging::open do
    case mode[0]
    when nil, /^r/
      puts "#{command} |"
    else
      puts "| #{command}"
    end
    IO.popen(command, *mode, &block)
  end
end

def log_src(src)
  src = src.split(/^/)
  fmt = "%#{src.size.to_s.size}d: %s"
  Logging::message <<"EOM"
checked program was:
/* begin */
EOM
  src.each_with_index {|line, no| Logging::message fmt, no+1, line}
  Logging::message <<"EOM"
/* end */

EOM
end

def create_tmpsrc(src)
  src = yield(src) if block_given?
  src = src.gsub(/[ \t]+$/, '').gsub(/\A\n+|^\n+$/, '').sub(/[^\n]\z/, "\\&\n")
  open(CONFTEST_C, "wb") do |cfile|
    cfile.print src
  end
  src
end

def try_do(src, command, &b)
  src = create_tmpsrc(src, &b)
  xsystem(command)
ensure
  log_src(src)
end

def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
  conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote,
                              'src' => CONFTEST_C,
                              'INCFLAGS' => $INCFLAGS,
                              'CPPFLAGS' => $CPPFLAGS,
                              'CFLAGS' => "#$CFLAGS",
                              'ARCH_FLAG' => "#$ARCH_FLAG",
                              'LDFLAGS' => "#$LDFLAGS #{ldflags}",
                              'LIBPATH' => libpathflag(libpath),
                              'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
                              'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS")
  Config::expand(TRY_LINK.dup, conf)
end

def cc_command(opt="")
  conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)
  Config::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
		 conf)
end

def cpp_command(outfile, opt="")
  conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)
  Config::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
		 conf)
end

def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
  libpath.map{|x|
    case x
    when "$(topdir)", /\A\./
      LIBPATHFLAG
    else
      LIBPATHFLAG+RPATHFLAG
    end % x.quote
  }.join
end

def try_link0(src, opt="", &b)
  try_do(src, link_command("", opt), &b)
end

def try_link(src, opt="", &b)
  try_link0(src, opt, &b)
ensure
  rm_f "conftest*", "c0x32*"
end

def try_compile(src, opt="", &b)
  try_do(src, cc_command(opt), &b)
ensure
  rm_f "conftest*"
end

def try_cpp(src, opt="", &b)
  try_do(src, cpp_command(CPPOUTFILE, opt), &b)
ensure
  rm_f "conftest*"
end

def cpp_include(header)
  if header
    header = [header] unless header.kind_of? Array
    header.map {|h| "#include <#{h}>\n"}.join
  else
    ""
  end
end

def with_cppflags(flags)
  cppflags = $CPPFLAGS
  $CPPFLAGS = flags
  ret = yield
ensure
  $CPPFLAGS = cppflags unless ret
end

def with_cflags(flags)
  cflags = $CFLAGS
  $CFLAGS = flags
  ret = yield
ensure
  $CFLAGS = cflags unless ret
end

def with_ldflags(flags)
  ldflags = $LDFLAGS
  $LDFLAGS = flags
  ret = yield
ensure
  $LDFLAGS = ldflags unless ret
end

def try_static_assert(expr, headers = nil, opt = "", &b)
  headers = cpp_include(headers)
  try_compile(<<SRC, opt, &b)
#{COMMON_HEADERS}
#{headers}
/*top*/
int conftest_const[(#{expr}) ? 1 : -1];
SRC
end

def try_constant(const, headers = nil, opt = "", &b)
  includes = cpp_include(headers)
  if CROSS_COMPILING
    if try_static_assert("#{const} > 0", headers, opt)
      # positive constant
    elsif try_static_assert("#{const} < 0", headers, opt)
      neg = true
      const = "-(#{const})"
    elsif try_static_assert("#{const} == 0", headers, opt)
      return 0
    else
      # not a constant
      return nil
    end
    upper = 1
    lower = 0
    until try_static_assert("#{const} <= #{upper}", headers, opt)
      lower = upper
      upper <<= 1
    end
    return nil unless lower
    while upper > lower + 1
      mid = (upper + lower) / 2
      if try_static_assert("#{const} > #{mid}", headers, opt)
        lower = mid
      else
        upper = mid
      end
    end
    upper = -upper if neg
    return upper
  else
    src = %{#{COMMON_HEADERS}
#{includes}
#include <stdio.h>
/*top*/
int conftest_const = (int)(#{const});
int main() {printf("%d\\n", conftest_const); return 0;}
}
    if try_link0(src, opt, &b)
      xpopen("./conftest") do |f|
        return Integer(f.gets)
      end
    end
  end
  nil
end

def try_func(func, libs, headers = nil, &b)
  headers = cpp_include(headers)
  try_link(<<"SRC", libs, &b) or try_link(<<"SRC", libs, &b)
#{COMMON_HEADERS}
#{headers}
/*top*/
int main() { return 0; }
int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; }
SRC
#{headers}
/*top*/
int main() { return 0; }
int t() { #{func}(); return 0; }
SRC
end

def try_var(var, headers = nil, &b)
  headers = cpp_include(headers)
  try_compile(<<"SRC", &b)
#{COMMON_HEADERS}
#{headers}
/*top*/
int main() { return 0; }
int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
SRC
end

def egrep_cpp(pat, src, opt = "", &b)
  src = create_tmpsrc(src, &b)
  xpopen(cpp_command('', opt)) do |f|
    if Regexp === pat
      puts("    ruby -ne 'print if #{pat.inspect}'")
      f.grep(pat) {|l|
	puts "#{f.lineno}: #{l}"
	return true
      }
      false
    else
      puts("    egrep '#{pat}'")
      begin
	stdin = $stdin.dup
	$stdin.reopen(f)
	system("egrep", pat)
      ensure
	$stdin.reopen(stdin)
      end
    end
  end
ensure
  rm_f "conftest*"
  log_src(src)
end

# This is used internally by the have_macro? method.
def macro_defined?(macro, src, opt = "", &b)
  src = src.sub(/[^\n]\z/, "\\&\n")
  try_compile(src + <<"SRC", opt, &b)
/*top*/
#ifndef #{macro}
# error
>>>>>> #{macro} undefined <<<<<<
#endif
SRC
end

def try_run(src, opt = "", &b)
  if try_link0(src, opt, &b)
    xsystem("./conftest")
  else
    nil
  end
ensure
  rm_f "conftest*"
end

def install_files(mfile, ifiles, map = nil, srcprefix = nil)
  ifiles or return
  ifiles.empty? and return
  srcprefix ||= '$(srcdir)'
  Config::expand(srcdir = srcprefix.dup)
  dirs = []
  path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
  ifiles.each do |files, dir, prefix|
    dir = map_dir(dir, map)
    prefix &&= %r|\A#{Regexp.quote(prefix)}/?|
    if /\A\.\// =~ files
      # install files which are in current working directory.
      files = files[2..-1]
      len = nil
    else
      # install files which are under the $(srcdir).
      files = File.join(srcdir, files)
      len = srcdir.size
    end
    f = nil
    Dir.glob(files) do |f|
      f[0..len] = "" if len
      case File.basename(f)
      when *$NONINSTALLFILES
        next
      end
      d = File.dirname(f)
      d.sub!(prefix, "") if prefix
      d = (d.empty? || d == ".") ? dir : File.join(dir, d)
      f = File.join(srcprefix, f) if len
      path[d] << f
    end
    unless len or f
      d = File.dirname(files)
      d.sub!(prefix, "") if prefix
      d = (d.empty? || d == ".") ? dir : File.join(dir, d)
      path[d] << files
    end
  end
  dirs
end

def install_rb(mfile, dest, srcdir = nil)
  install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
end

def append_library(libs, lib) # :no-doc:
  format(LIBARG, lib) + " " + libs
end

def message(*s)
  unless Logging.quiet and not $VERBOSE
    printf(*s)
    $stdout.flush
  end
end

# This emits a string to stdout that allows users to see the results of the
# various have* and find* methods as they are tested.
#
# Internal use only.
#
def checking_for(m, fmt = nil)
  f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim
  m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
  message "%s", m
  a = r = nil
  Logging::postpone do
    r = yield
    a = (fmt ? fmt % r : r ? "yes" : "no") << "\n"
    "#{f}#{m}-------------------- #{a}\n"
  end
  message(a)
  Logging::message "--------------------\n\n"
  r
end

def checking_message(target, place = nil, opt = nil)
  [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
    if noun
      [[:to_str], [:join, ","], [:to_s]].each do |meth, *args|
        if noun.respond_to?(meth)
          break noun = noun.send(meth, *args)
        end
      end
      msg << " #{pre} #{noun}" unless noun.empty?
    end
    msg
  end
end

# :startdoc:

# Returns whether or not +macro+ is defined either in the common header
# files or within any +headers+ you provide.
#
# Any options you pass to +opt+ are passed along to the compiler.
#
def have_macro(macro, headers = nil, opt = "", &b)
  checking_for checking_message(macro, headers, opt) do
    macro_defined?(macro, cpp_include(headers), opt, &b)
  end
end

# Returns whether or not the given entry point +func+ can be found within
# +lib+.  If +func+ is nil, the 'main()' entry point is used by default.
# If found, it adds the library to list of libraries to be used when linking
# your extension.
#
# If +headers+ are provided, it will include those header files as the
# header files it looks in when searching for +func+.
#
# The real name of the library to be linked can be altered by
# '--with-FOOlib' configuration option.
#
def have_library(lib, func = nil, headers = nil, &b)
  func = "main" if !func or func.empty?
  lib = with_config(lib+'lib', lib)
  checking_for checking_message("#{func}()", LIBARG%lib) do
    if COMMON_LIBS.include?(lib)
      true
    else
      libs = append_library($libs, lib)
      if try_func(func, libs, headers, &b)
        $libs = libs
        true
      else
        false
      end
    end
  end
end

# Returns whether or not the entry point +func+ can be found within the library
# +lib+ in one of the +paths+ specified, where +paths+ is an array of strings.
# If +func+ is nil , then the main() function is used as the entry point.
#
# If +lib+ is found, then the path it was found on is added to the list of
# library paths searched and linked against.
#
def find_library(lib, func, *paths, &b)
  func = "main" if !func or func.empty?
  lib = with_config(lib+'lib', lib)
  paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
  checking_for "#{func}() in #{LIBARG%lib}" do
    libpath = $LIBPATH
    libs = append_library($libs, lib)
    begin
      until r = try_func(func, libs, &b) or paths.empty?
	$LIBPATH = libpath | [paths.shift]
      end
      if r
	$libs = libs
	libpath = nil
      end
    ensure
      $LIBPATH = libpath if libpath
    end
    r
  end
end

# Returns whether or not the function +func+ can be found in the common
# header files, or within any +headers+ that you provide.  If found, a
# macro is passed as a preprocessor constant to the compiler using the
# function name, in uppercase, prepended with 'HAVE_'.
#
# For example, if have_func('foo') returned true, then the HAVE_FOO
# preprocessor macro would be passed to the compiler.
#
def have_func(func, headers = nil, &b)
  checking_for checking_message("#{func}()", headers) do
    if try_func(func, $libs, headers, &b)
      $defs.push(format("-DHAVE_%s", func.tr_cpp))
      true
    else
      false
    end
  end
end

# Returns whether or not the variable +var+ can be found in the common
# header files, or within any +headers+ that you provide.  If found, a
# macro is passed as a preprocessor constant to the compiler using the
# variable name, in uppercase, prepended with 'HAVE_'.
#
# For example, if have_var('foo') returned true, then the HAVE_FOO
# preprocessor macro would be passed to the compiler.
#
def have_var(var, headers = nil, &b)
  checking_for checking_message(var, headers) do
    if try_var(var, headers, &b)
      $defs.push(format("-DHAVE_%s", var.tr_cpp))
      true
    else
      false
    end
  end
end

# Returns whether or not the given +header+ file can be found on your system.
# If found, a macro is passed as a preprocessor constant to the compiler using
# the header file name, in uppercase, prepended with 'HAVE_'.
#
# For example, if have_header('foo.h') returned true, then the HAVE_FOO_H
# preprocessor macro would be passed to the compiler.
#
def have_header(header, &b)
  checking_for header do
    if try_cpp(cpp_include(header), &b)
      $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___")))
      true
    else
      false
    end
  end
end

# Instructs mkmf to search for the given +header+ in any of the +paths+
# provided, and returns whether or not it was found in those paths.
#
# If the header is found then the path it was found on is added to the list
# of included directories that are sent to the compiler (via the -I switch).
#
def find_header(header, *paths)
  message = checking_message(header, paths)
  header = cpp_include(header)
  checking_for message do
    if try_cpp(header)
      true
    else
      found = false
      paths.each do |dir|
        opt = "-I#{dir}".quote
        if try_cpp(header, opt)
          $INCFLAGS << " " << opt
          found = true
          break
        end
      end
      found
    end
  end
end

# Returns whether or not the struct of type +type+ contains +member+.  If
# it does not, or the struct type can't be found, then false is returned.  You
# may optionally specify additional +headers+ in which to look for the struct
# (in addition to the common header files).
#
# If found, a macro is passed as a preprocessor constant to the compiler using
# the member name, in uppercase, prepended with 'HAVE_ST_'.
#
# For example, if have_struct_member('struct foo', 'bar') returned true, then the
# HAVE_ST_BAR preprocessor macro would be passed to the compiler.
# 
def have_struct_member(type, member, headers = nil, &b)
  checking_for checking_message("#{type}.#{member}", headers) do
    if try_compile(<<"SRC", &b)
#{COMMON_HEADERS}
#{cpp_include(headers)}
/*top*/
int main() { return 0; }
int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
SRC
      $defs.push(format("-DHAVE_ST_%s", member.tr_cpp))
      true
    else
      false
    end
  end
end

def try_type(type, headers = nil, opt = "", &b)
  if try_compile(<<"SRC", opt, &b)
#{COMMON_HEADERS}
#{cpp_include(headers)}
/*top*/
typedef #{type} conftest_type;
int conftestval[sizeof(conftest_type)?1:-1];
SRC
    $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp))
    true
  else
    false
  end
end

# Returns whether or not the static type +type+ is defined.  You may
# optionally pass additional +headers+ to check against in addition to the
# common header files.
#
# You may also pass additional flags to +opt+ which are then passed along to
# the compiler.
#
# If found, a macro is passed as a preprocessor constant to the compiler using
# the type name, in uppercase, prepended with 'HAVE_TYPE_'.
#
# For example, if have_type('foo') returned true, then the HAVE_TYPE_FOO
# preprocessor macro would be passed to the compiler.
#
def have_type(type, headers = nil, opt = "", &b)
  checking_for checking_message(type, headers, opt) do
    try_type(type, headers, opt, &b)
  end
end

# Returns where the static type +type+ is defined.
#
# You may also pass additional flags to +opt+ which are then passed along to
# the compiler.
#
# See also +have_type+.
#
def find_type(type, opt, *headers, &b)
  opt ||= ""
  fmt = "not found"
  def fmt.%(x)
    x ? x.respond_to?(:join) ? x.join(",") : x : self
  end
  checking_for checking_message(type, nil, opt), fmt do
    headers.find do |h|
      try_type(type, h, opt, &b)
    end
  end
end

def try_const(const, headers = nil, opt = "", &b)
  const, type = *const
  if try_compile(<<"SRC", opt, &b)
#{COMMON_HEADERS}
#{cpp_include(headers)}
/*top*/
typedef #{type || 'int'} conftest_type;
conftest_type conftestval = #{type ? '' : '(int)'}#{const};
SRC
    $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp))
    true
  else
    false
  end
end

# Returns whether or not the constant +const+ is defined.  You may
# optionally pass the +type+ of +const+ as <code>[const, type]</code>,
# like as:
#
#   have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")
#
# You may also pass additional +headers+ to check against in addition
# to the common header files, and additional flags to +opt+ which are
# then passed along to the compiler.
#
# If found, a macro is passed as a preprocessor constant to the compiler using
# the type name, in uppercase, prepended with 'HAVE_CONST_'.
#
# For example, if have_const('foo') returned true, then the HAVE_CONST_FOO
# preprocessor macro would be passed to the compiler.
#
def have_const(const, headers = nil, opt = "", &b)
  checking_for checking_message([*const].compact.join(' '), headers, opt) do
    try_const(const, headers, opt, &b)
  end
end

# Returns the size of the given +type+.  You may optionally specify additional
# +headers+ to search in for the +type+.
#
# If found, a macro is passed as a preprocessor constant to the compiler using
# the type name, in uppercase, prepended with 'SIZEOF_', followed by the type
# name, followed by '=X' where 'X' is the actual size.
#
# For example, if check_sizeof('mystruct') returned 12, then the
# SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler.
#
def check_sizeof(type, headers = nil, &b)
  expr = "sizeof(#{type})"
  fmt = "%d"
  def fmt.%(x)
    x ? super : "failed"
  end
  checking_for checking_message("size of #{type}", headers), fmt do
    if size = try_constant(expr, headers, &b)
      $defs.push(format("-DSIZEOF_%s=%d", type.tr_cpp, size))
      size
    end
  end
end

# :stopdoc:

# Used internally by the what_type? method to determine if +type+ is a scalar
# pointer.
def scalar_ptr_type?(type, member = nil, headers = nil, &b)
  try_compile(<<"SRC", &b)   # pointer
#{COMMON_HEADERS}
#{cpp_include(headers)}
/*top*/
volatile #{type} conftestval;
int main() { return 0; }
int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
SRC
end

# Used internally by the what_type? method to determine if +type+ is a scalar
# pointer.
def scalar_type?(type, member = nil, headers = nil, &b)
  try_compile(<<"SRC", &b)   # pointer
#{COMMON_HEADERS}
#{cpp_include(headers)}
/*top*/
volatile #{type} conftestval;
int main() { return 0; }
int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
SRC
end

def what_type?(type, member = nil, headers = nil, &b)
  m = "#{type}"
  name = type
  if member
    m << "." << member
    name = "(((#{type} *)0)->#{member})"
  end
  fmt = "seems %s"
  def fmt.%(x)
    x ? super : "unknown"
  end
  checking_for checking_message(m, headers), fmt do
    if scalar_ptr_type?(type, member, headers, &b)
      if try_static_assert("sizeof(*#{name}) == 1", headers)
        "string"
      end
    elsif scalar_type?(type, member, headers, &b)
      if try_static_assert("sizeof(#{name}) > sizeof(long)", headers)
        "long long"
      elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers)
        "long"
      elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers)
        "int"
      elsif try_static_assert("sizeof(#{name}) > 1", headers)
        "short"
      else
        "char"
      end
    end
  end
end

# This method is used internally by the find_executable method.
#
# Internal use only.
#
def find_executable0(bin, path = nil)
  ext = config_string('EXEEXT')
  if File.expand_path(bin) == bin
    return bin if File.executable?(bin)
    ext and File.executable?(file = bin + ext) and return file
    return nil
  end
  if path ||= ENV['PATH']
    path = path.split(File::PATH_SEPARATOR)
  else
    path = %w[/usr/local/bin /usr/ucb /usr/bin /bin]
  end
  file = nil
  path.each do |dir|
    return file if File.executable?(file = File.join(dir, bin))
    return file if ext and File.executable?(file << ext)
  end
  nil
end

# :startdoc:

# Searches for the executable +bin+ on +path+. The default path is your
# PATH environment variable. If that isn't defined, it will resort to
# searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
#
# If found, it will return the full path, including the executable name,
# of where it was found.
#
# Note that this method does not actually affect the generated Makefile.
#
def find_executable(bin, path = nil)
  checking_for checking_message(bin, path) do
    find_executable0(bin, path)
  end
end

# :stopdoc:

def arg_config(config, *defaults, &block)
  $arg_config << [config, *defaults]
  defaults << nil if !block and defaults.empty?
  $configure_args.fetch(config.tr('_', '-'), *defaults, &block)
end

# :startdoc:

# Tests for the presence of a --with-<tt>config</tt> or --without-<tt>config</tt>
# option. Returns true if the with option is given, false if the without
# option is given, and the default value otherwise.
#
# This can be useful for adding custom definitions, such as debug information.
#
# Example:
#
#    if with_config("debug")
#       $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
#    end
#
def with_config(config, *defaults)
  config = config.sub(/^--with[-_]/, '')
  val = arg_config("--with-"+config) do
    if arg_config("--without-"+config)
      false
    elsif block_given?
      yield(config, *defaults)
    else
      break *defaults
    end
  end
  case val
  when "yes"
    true
  when "no"
    false
  else
    val
  end
end

# Tests for the presence of an --enable-<tt>config</tt> or
# --disable-<tt>config</tt> option. Returns true if the enable option is given,
# false if the disable option is given, and the default value otherwise.
#
# This can be useful for adding custom definitions, such as debug information.
#
# Example:
#
#    if enable_config("debug")
#       $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
#    end
#
def enable_config(config, *defaults)
  if arg_config("--enable-"+config)
    true
  elsif arg_config("--disable-"+config)
    false
  elsif block_given?
    yield(config, *defaults)
  else
    return *defaults
  end
end

# Generates a header file consisting of the various macro definitions generated
# by other methods such as have_func and have_header. These are then wrapped in
# a custom #ifndef based on the +header+ file name, which defaults to
# 'extconf.h'.
#
# For example:
# 
#    # extconf.rb
#    require 'mkmf'
#    have_func('realpath')
#    have_header('sys/utime.h')
#    create_header
#    create_makefile('foo')
#
# The above script would generate the following extconf.h file:
#
#    #ifndef EXTCONF_H
#    #define EXTCONF_H
#    #define HAVE_REALPATH 1
#    #define HAVE_SYS_UTIME_H 1
#    #endif
#
# Given that the create_header method generates a file based on definitions
# set earlier in your extconf.rb file, you will probably want to make this
# one of the last methods you call in your script.
#
def create_header(header = "extconf.h")
  message "creating %s\n", header
  sym = header.tr("a-z./\055", "A-Z___")
  hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
  for line in $defs
    case line
    when /^-D([^=]+)(?:=(.*))?/
      hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n"
    when /^-U(.*)/
      hdr << "#undef #$1\n"
    end
  end
  hdr << "#endif\n"
  hdr = hdr.join
  unless (IO.read(header) == hdr rescue false)
    open(header, "w") do |hfile|
      hfile.write(hdr)
    end
  end
  $extconf_h = header
end

# Sets a +target+ name that the user can then use to configure various 'with'
# options with on the command line by using that name.  For example, if the
# target is set to "foo", then the user could use the --with-foo-dir command
# line option.
#
# You may pass along additional 'include' or 'lib' defaults via the +idefault+
# and +ldefault+ parameters, respectively.
#
# Note that dir_config only adds to the list of places to search for libraries
# and include files.  It does not link the libraries into your application.
#
def dir_config(target, idefault=nil, ldefault=nil)
  if dir = with_config(target + "-dir", (idefault unless ldefault))
    defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
    idefault = ldefault = nil
  end

  idir = with_config(target + "-include", idefault)
  $arg_config.last[1] ||= "${#{target}-dir}/include"
  ldir = with_config(target + "-lib", ldefault)
  $arg_config.last[1] ||= "${#{target}-dir}/lib"

  idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []
  if defaults
    idirs.concat(defaults.collect {|dir| dir + "/include"})
    idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
  end
  unless idirs.empty?
    idirs.collect! {|dir| "-I" + dir}
    idirs -= Shellwords.shellwords($CPPFLAGS)
    unless idirs.empty?
      $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
    end
  end

  ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : []
  if defaults
    ldirs.concat(defaults.collect {|dir| dir + "/lib"})
    ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
  end
  $LIBPATH = ldirs | $LIBPATH

  [idir, ldir]
end

# :stopdoc:

# Handles meta information about installed libraries. Uses your platform's
# pkg-config program if it has one.
def pkg_config(pkg)
  if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
    # iff package specific config command is given
    get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
  elsif ($PKGCONFIG ||= 
         (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) &&
         find_executable0(pkgconfig) && pkgconfig) and
      system("#{$PKGCONFIG} --exists #{pkg}")
    # default to pkg-config command
    get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp}
  elsif find_executable0(pkgconfig = "#{pkg}-config")
    # default to package specific config command, as a last resort.
    get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
  end
  if get
    cflags = get['cflags']
    ldflags = get['libs']
    libs = get['libs-only-l']
    ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
    $CFLAGS += " " << cflags
    $LDFLAGS += " " << ldflags
    $libs += " " << libs
    Logging::message "package configuration for %s\n", pkg
    Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
                     cflags, ldflags, libs
    [cflags, ldflags, libs]
  else
    Logging::message "package configuration for %s is not found\n", pkg
    nil
  end
end

def with_destdir(dir)
  dir = dir.sub($dest_prefix_pattern, '')
  /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir
end

# Converts forward slashes to backslashes. Aimed at MS Windows.
#
# Internal use only.
#
def winsep(s)
  s.tr('/', '\\')
end

# Converts native path to format acceptable in Makefile
#
# Internal use only.
#
if !CROSS_COMPILING
  case CONFIG['build_os']
  when 'mingw32'
    def mkintpath(path)
      # mingw uses make from msys and it needs special care
      # converts from C:\some\path to /C/some/path
      path = path.dup
      path.tr!('\\', '/')
      path.sub!(/\A([A-Za-z]):(?=\/)/, '/\1')
      path
    end
  end
end
unless defined?(mkintpath)
  def mkintpath(path)
    path
  end
end

def configuration(srcdir)
  mk = []
  vpath = %w[$(srcdir) $(topdir) $(hdrdir)]
  if !CROSS_COMPILING
    case CONFIG['build_os']
    when 'cygwin'
      if CONFIG['target_os'] != 'cygwin'
        vpath.each {|p| p.sub!(/.*/, '$(shell cygpath -u \&)')}
      end
    when 'msdosdjgpp'
      CONFIG['PATH_SEPARATOR'] = ';'
    end
  end
  mk << %{
SHELL = /bin/sh

#### Start of system configuration section. ####
#{
if $extmk
  "top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/")
end
}
srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2])}.quote}
topdir = #{mkintpath($extmk ? CONFIG["topdir"] : $topdir).quote}
hdrdir = #{$extmk ? mkintpath(CONFIG["hdrdir"]).quote : '$(topdir)'}
VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
}
  if $extmk
    mk << "RUBYLIB = -\nRUBYOPT = -rpurelib.rb\n"
  end
  if destdir = CONFIG["prefix"][$dest_prefix_pattern, 1]
    mk << "\nDESTDIR = #{destdir}\n"
  end
  CONFIG.each do |key, var|
    next unless /prefix$/ =~ key
    mk << "#{key} = #{with_destdir(var)}\n"
  end
  CONFIG.each do |key, var|
    next if /^abs_/ =~ key
    next unless /^(?:src|top|hdr|(.*))dir$/ =~ key and $1
    mk << "#{key} = #{with_destdir(var)}\n"
  end
  if !$extmk and !$configure_args.has_key?('--ruby') and
      sep = config_string('BUILD_FILE_SEPARATOR')
    sep = ":/=#{sep}"
  else
    sep = ""
  end
  extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ")<<" "
  mk << %{
CC = #{CONFIG['CC']}
LIBRUBY = #{CONFIG['LIBRUBY']}
LIBRUBY_A = #{CONFIG['LIBRUBY_A']}
LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED
LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC

RUBY_EXTCONF_H = #{$extconf_h}
CFLAGS   = #{$static ? '' : CONFIG['CCDLFLAGS']} #$CFLAGS #$ARCH_FLAG
INCFLAGS = -I. #$INCFLAGS
DEFS     = #{CONFIG['DEFS']}
CPPFLAGS = #{extconf_h}#{$CPPFLAGS}
CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']}
ldflags  = #{$LDFLAGS}
dldflags = #{$DLDFLAGS}
archflag = #{$ARCH_FLAG}
DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
LDSHARED = #{CONFIG['LDSHARED']}
AR = #{CONFIG['AR']}
EXEEXT = #{CONFIG['EXEEXT']}

RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']}
RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']}
arch = #{CONFIG['arch']}
sitearch = #{CONFIG['sitearch']}
ruby_version = #{Config::CONFIG['ruby_version']}
ruby = #{$ruby}
RUBY = $(ruby#{sep})
RM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'}
MAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'}
INSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'}
INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'}
INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'}
COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'}

#### End of system configuration section. ####

preload = #{$preload ? $preload.join(' ') : ''}
}
  if $nmake == ?b
    mk.each do |x|
      x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
        "!ifndef " + $1 + "\n" +
        $& +
	"!endif\n"
      end
    end
  end
  mk
end

def dummy_makefile(srcdir)
  configuration(srcdir) << <<RULES << CLEANINGS
CLEANFILES = #{$cleanfiles.join(' ')}
DISTCLEANFILES = #{$distcleanfiles.join(' ')}

all install static install-so install-rb: Makefile

RULES
end
# :startdoc:

# Generates the Makefile for your extension, passing along any options and
# preprocessor constants that you may have generated through other methods.
#
# The +target+ name should correspond the name of the global function name
# defined within your C extension, minus the 'Init_'.  For example, if your
# C extension is defined as 'Init_foo', then your target would simply be 'foo'.
#
# If any '/' characters are present in the target name, only the last name
# is interpreted as the target name, and the rest are considered toplevel
# directory names, and the generated Makefile will be altered accordingly to
# follow that directory structure.
#
# For example, if you pass 'test/foo' as a target name, your extension will
# be installed under the 'test' directory.  This means that in order to
# load the file within a Ruby program later, that directory structure will
# have to be followed, e.g. "require 'test/foo'".
#
# The +srcprefix+ should be used when your source files are not in the same
# directory as your build script. This will not only eliminate the need for
# you to manually copy the source files into the same directory as your build
# script, but it also sets the proper +target_prefix+ in the generated
# Makefile.
#
# Setting the +target_prefix+ will, in turn, install the generated binary in
# a directory under your Config::CONFIG['sitearchdir'] that mimics your local
# filesystem when you run 'make install'.
#
# For example, given the following file tree:
#
#    ext/
#       extconf.rb
#       test/
#          foo.c
#
# And given the following code:
#
#    create_makefile('test/foo', 'test')
#
# That will set the +target_prefix+ in the generated Makefile to 'test'. That,
# in turn, will create the following file tree when installed via the
# 'make install' command:
#
#    /path/to/ruby/sitearchdir/test/foo.so
#
# It is recommended that you use this approach to generate your makefiles,
# instead of copying files around manually, because some third party
# libraries may depend on the +target_prefix+ being set properly.
#
# The +srcprefix+ argument can be used to override the default source
# directory, i.e. the current directory . It is included as part of the VPATH
# and added to the list of INCFLAGS.
#
def create_makefile(target, srcprefix = nil)
  $target = target
  libpath = $DEFLIBPATH|$LIBPATH
  message "creating Makefile\n"
  rm_f "conftest*"
  if CONFIG["DLEXT"] == $OBJEXT
    for lib in libs = $libs.split
      lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
    end
    $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
  end

  if target.include?('/')
    target_prefix, target = File.split(target)
    target_prefix[0,0] = '/'
  else
    target_prefix = ""
  end

  srcprefix ||= '$(srcdir)'
  Config::expand(srcdir = srcprefix.dup)

  if not $objs
    $objs = []
    srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
    for f in srcs
      obj = File.basename(f, ".*") << ".o"
      $objs.push(obj) unless $objs.index(obj)
    end
  elsif !(srcs = $srcs)
    srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')}
  end
  $srcs = srcs
  for i in $objs
    i.sub!(/\.o\z/, ".#{$OBJEXT}")
  end
  $objs = $objs.join(" ")

  target = nil if $objs == ""

  if target and EXPORT_PREFIX
    if File.exist?(File.join(srcdir, target + '.def'))
      deffile = "$(srcdir)/$(TARGET).def"
      unless EXPORT_PREFIX.empty?
        makedef = %{-pe "sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
      end
    else
      makedef = %{-e "puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'"}
    end
    if makedef
      $distcleanfiles << '$(DEFFILE)'
      origdef = deffile
      deffile = "$(TARGET)-$(arch).def"
    end
  end
  origdef ||= ''

  libpath = libpathflag(libpath)

  dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
  staticlib = target ? "$(TARGET).#$LIBEXT" : ""
  mfile = open("Makefile", "wb")
  mfile.print configuration(srcprefix)
  mfile.print "
libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
LIBPATH = #{libpath}
DEFFILE = #{deffile}

CLEANFILES = #{$cleanfiles.join(' ')}
DISTCLEANFILES = #{$distcleanfiles.join(' ')}

extout = #{$extout}
extout_prefix = #{$extout_prefix}
target_prefix = #{target_prefix}
LOCAL_LIBS = #{$LOCAL_LIBS}
LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
SRCS = #{srcs.collect(&File.method(:basename)).join(' ')}
OBJS = #{$objs}
TARGET = #{target}
DLLIB = #{dllib}
EXTSTATIC = #{$static || ""}
STATIC_LIB = #{staticlib unless $static.nil?}
#{!$extout && defined?($installed_list) ? "INSTALLED_LIST = #{$installed_list}\n" : ""}
"
  install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
  n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET).'
  mfile.print "
TARGET_SO     = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
CLEANLIBS     = #{n}#{CONFIG['DLEXT']} #{n}il? #{n}tds #{n}map
CLEANOBJS     = *.#{$OBJEXT} *.#{$LIBEXT} *.s[ol] *.pdb *.exp *.bak

all:		#{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
static:		$(STATIC_LIB)#{$extout ? " install-rb" : ""}
"
  mfile.print CLEANINGS
  dirs = []
  mfile.print "install: install-so install-rb\n\n"
  sodir = (dir = "$(RUBYARCHDIR)").dup
  mfile.print("install-so: ")
  if target
    f = "$(DLLIB)"
    dest = "#{dir}/#{f}"
    mfile.puts dir, "install-so: #{dest}"
    unless $extout
      mfile.print "#{dest}: #{f}\n"
      if (sep = config_string('BUILD_FILE_SEPARATOR'))
        f.gsub!("/", sep)
        dir.gsub!("/", sep)
        sep = ":/="+sep
        f.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
        f.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
        dir.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
        dir.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
      end
      mfile.print "\t$(INSTALL_PROG) #{f} #{dir}\n"
      if defined?($installed_list)
	mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
      end
    end
  else
    mfile.puts "Makefile"
  end
  mfile.print("install-rb: pre-install-rb install-rb-default\n")
  mfile.print("install-rb-default: pre-install-rb-default\n")
  mfile.print("pre-install-rb: Makefile\n")
  mfile.print("pre-install-rb-default: Makefile\n")
  for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
    files = install_files(mfile, i, nil, srcprefix) or next
    for dir, *files in files
      unless dirs.include?(dir)
	dirs << dir
	mfile.print "pre-install-rb#{sfx}: #{dir}\n"
      end
      files.each do |f|
	dest = "#{dir}/#{File.basename(f)}"
	mfile.print("install-rb#{sfx}: #{dest}\n")
	mfile.print("#{dest}: #{f} #{dir}\n\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ")
	sep = config_string('BUILD_FILE_SEPARATOR')
	if sep
	  f = f.gsub("/", sep)
	  sep = ":/="+sep
	  f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
	  f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
	else
	  sep = ""
	end
	mfile.print("#{f} $(@D#{sep})\n")
	if defined?($installed_list) and !$extout
	  mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
	end
      end
    end
  end
  dirs.unshift(sodir) if target and !dirs.include?(sodir)
  dirs.each {|dir| mfile.print "#{dir}:\n\t$(MAKEDIRS) $@\n"}

  mfile.print <<-SITEINSTALL

site-install: site-install-so site-install-rb
site-install-so: install-so
site-install-rb: install-rb

  SITEINSTALL

  return unless target

  mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b
  mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
  mfile.print "\n"

  CXX_EXT.each do |ext|
    COMPILE_RULES.each do |rule|
      mfile.printf(rule, ext, $OBJEXT)
      mfile.printf("\n\t%s\n\n", COMPILE_CXX)
    end
  end
  %w[c].each do |ext|
    COMPILE_RULES.each do |rule|
      mfile.printf(rule, ext, $OBJEXT)
      mfile.printf("\n\t%s\n\n", COMPILE_C)
    end
  end

  mfile.print "$(RUBYARCHDIR)/" if $extout
  mfile.print "$(DLLIB): "
  mfile.print "$(DEFFILE) " if makedef
  mfile.print "$(OBJS) Makefile\n"
  mfile.print "\t@-$(RM) $@\n"
  mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout
  link_so = LINK_SO.gsub(/^/, "\t")
  mfile.print link_so, "\n\n"
  unless $static.nil?
    mfile.print "$(STATIC_LIB): $(OBJS)\n\t"
    mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
    config_string('RANLIB') do |ranlib|
      mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true"
    end
  end
  mfile.print "\n\n"
  if makedef
    mfile.print "$(DEFFILE): #{origdef}\n"
    mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n"
  end

  depend = File.join(srcdir, "depend")
  if File.exist?(depend)
    suffixes = []
    depout = []
    open(depend, "r") do |dfile|
      mfile.printf "###\n"
      cont = implicit = nil
      impconv = proc do
	COMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]}
	implicit = nil
      end
      ruleconv = proc do |line|
	if implicit
	  if /\A\t/ =~ line
	    implicit[1] << line
	    next
	  else
	    impconv[]
	  end
	end
	if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
	  suffixes << m[1] << m[2]
	  implicit = [[m[1], m[2]], [m.post_match]]
	  next
	elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
	  line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
	end
	depout << line
      end
      while line = dfile.gets()
	line.gsub!(/\.o\b/, ".#{$OBJEXT}")
	line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h) if $config_h
	if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
	  (cont ||= []) << line
	  next
	elsif cont
	  line = (cont << line).join
	  cont = nil
	end
	ruleconv.call(line)
      end
      if cont
	ruleconv.call(cont.join)
      elsif implicit
	impconv.call
      end
    end
    unless suffixes.empty?
      mfile.print ".SUFFIXES: .", suffixes.uniq.join(" ."), "\n\n"
    end
    mfile.print "$(OBJS): $(RUBY_EXTCONF_H)\n\n" if $extconf_h
    mfile.print depout
  else
    headers = %w[ruby.h defines.h]
    if RULE_SUBST
      headers.each {|h| h.sub!(/.*/) {|*m| RULE_SUBST % m}}
    end
    headers << $config_h if $config_h
    headers << "$(RUBY_EXTCONF_H)" if $extconf_h
    mfile.print "$(OBJS): ", headers.join(' '), "\n"
  end

  $makefile_created = true
ensure
  mfile.close if mfile
end

# :stopdoc:

def init_mkmf(config = CONFIG)
  $makefile_created = false
  $arg_config = []
  $enable_shared = config['ENABLE_SHARED'] == 'yes'
  $defs = []
  $extconf_h = nil
  $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup
  $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup
  $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup
  $LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup
  $INCFLAGS = "-I$(topdir) -I$(hdrdir) -I$(srcdir)"
  $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup
  $LIBEXT = config['LIBEXT'].dup
  $OBJEXT = config["OBJEXT"].dup
  $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}"
  $LIBRUBYARG = ""
  $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
  $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
  $DEFLIBPATH = [$extmk ? "$(topdir)" : "$(libdir)"]
  $DEFLIBPATH.unshift(".")
  $LIBPATH = []
  $INSTALLFILES = []
  $NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/]

  $objs = nil
  $srcs = nil
  $libs = ""
  if $enable_shared or Config.expand(config["LIBRUBY"].dup) != Config.expand(config["LIBRUBY_A"].dup)
    $LIBRUBYARG = config['LIBRUBYARG']
  end

  $LOCAL_LIBS = ""

  $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
  $cleanfiles << "mkmf.log"
  $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []

  $extout ||= nil
  $extout_prefix ||= nil

  $arg_config.clear
  dir_config("opt")
end

FailedMessage = <<MESSAGE
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
MESSAGE

# Returns whether or not the Makefile was successfully generated. If not,
# the script will abort with an error message.
#
# Internal use only.
#
def mkmf_failed(path)
  unless $makefile_created or File.exist?("Makefile")
    opts = $arg_config.collect {|t, n| "\t#{t}#{n ? "=#{n}" : ""}\n"}
    abort "*** #{path} failed ***\n" + FailedMessage + opts.join
  end
end

# :startdoc:

init_mkmf

$make = with_config("make-prog", ENV["MAKE"] || "make")
make, = Shellwords.shellwords($make)
$nmake = nil
case
when $mswin
  $nmake = ?m if /nmake/i =~ make
when $bccwin
  $nmake = ?b if /Borland/i =~ `#{make} -h`
end

Config::CONFIG["srcdir"] = CONFIG["srcdir"] =
  $srcdir = arg_config("--srcdir", File.dirname($0))
$configure_args["--topsrcdir"] ||= $srcdir
if $curdir = arg_config("--curdir")
  Config.expand(curdir = $curdir.dup)
else
  curdir = $curdir = "."
end
unless File.expand_path(Config::CONFIG["topdir"]) == File.expand_path(curdir)
  CONFIG["topdir"] = $curdir
  Config::CONFIG["topdir"] = curdir
end
$configure_args["--topdir"] ||= $curdir
$ruby = arg_config("--ruby", File.join(Config::CONFIG["bindir"], CONFIG["ruby_install_name"]))

split = Shellwords.method(:shellwords).to_proc

EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}

hdr = []
config_string('COMMON_MACROS') do |s|
  Shellwords.shellwords(s).each do |w|
    hdr << "#define " + w.split(/=/, 2).join(" ")
  end
end
config_string('COMMON_HEADERS') do |s|
  Shellwords.shellwords(s).each {|s| hdr << "#include <#{s}>"}
end
COMMON_HEADERS = hdr.join("\n")
COMMON_LIBS = config_string('COMMON_LIBS', &split) || []

COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
RULE_SUBST = config_string('RULE_SUBST')
COMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<'
COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<'
TRY_LINK = config_string('TRY_LINK') ||
  "$(CC) #{OUTFLAG}conftest $(INCFLAGS) $(CPPFLAGS) " \
  "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
LINK_SO = config_string('LINK_SO') ||
  if CONFIG["DLEXT"] == $OBJEXT
    "ld $(DLDFLAGS) -r -o $@ $(OBJS)\n"
  else
    "$(LDSHARED) #{OUTFLAG}$@ $(OBJS) " \
    "$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)"
  end
LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L"%s"'
RPATHFLAG = config_string('RPATHFLAG') || ''
LIBARG = config_string('LIBARG') || '-l%s'

sep = config_string('BUILD_FILE_SEPARATOR') {|sep| ":/=#{sep}" if sep != "/"} || ""
CLEANINGS = "
clean:
		@-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep})

distclean:	clean
		@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
		@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})

realclean:	distclean
"

if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0)
  END {mkmf_failed($0)}
end
PK     Z\g#  #    mailread.rbnu [        # The Mail class represents an internet mail message (as per RFC822, RFC2822)
# with headers and a body. 
class Mail

  # Create a new Mail where +f+ is either a stream which responds to gets(),
  # or a path to a file.  If +f+ is a path it will be opened.
  #
  # The whole message is read so it can be made available through the #header,
  # #[] and #body methods.
  #
  # The "From " line is ignored if the mail is in mbox format.
  def initialize(f)
    unless defined? f.gets
      f = open(f, "r")
      opened = true
    end

    @header = {}
    @body = []
    begin
      while line = f.gets()
	line.chop!
	next if /^From /=~line	# skip From-line
	break if /^$/=~line	# end of header

	if /^(\S+?):\s*(.*)/=~line
	  (attr = $1).capitalize!
	  @header[attr] = $2
	elsif attr
	  line.sub!(/^\s*/, '')
	  @header[attr] += "\n" + line
	end
      end
  
      return unless line

      while line = f.gets()
	break if /^From /=~line
	@body.push(line)
      end
    ensure
      f.close if opened
    end
  end

  # Return the headers as a Hash.
  def header
    return @header
  end

  # Return the message body as an Array of lines
  def body
    return @body
  end

  # Return the header corresponding to +field+. 
  #
  # Matching is case-insensitive.
  def [](field)
    @header[field.capitalize]
  end
end
PK       bY\_Q  Q                  open-uri.rbnu [        PK       dY\/+rRF  F              1R  benchmark.rbnu [        PK       dY\}ޢf   f               X  generator.rbnu [        PK       eY\v%&  &  	              e2mmap.rbnu [        PK       eY\^f%+  +  
            Y  webrick.rbnu [        PK       eY\f*=l  l  	              matrix.rbnu [        PK       fY\buM'  '              : webrick/httprequest.rbnu [        PK       hY\{L
  
              c webrick/httpstatus.rbnu [        PK       iY\ͩ                Wq webrick/cgi.rbnu [        PK       jY\/ݔv  v              > webrick/httpversion.rbnu [        PK       jY\!G                 webrick/httpserver.rbnu [        PK       kY\W'  '              ƨ webrick/httputils.rbnu [        PK       lY\`>H  H               webrick/htmlutils.rbnu [        PK       lY\بj#  #              q webrick/log.rbnu [        PK       mY\
_                 webrick/https.rbnu [        PK       mY\2                 webrick/httpresponse.rbnu [        PK       nY\DgQ,
  ,
               webrick/utils.rbnu [        PK       oY\~                + webrick/httpproxy.rbnu [        PK       pY\O-                F+ webrick/accesslog.rbnu [        PK       qY\rO                4 webrick/server.rbnu [        PK       sY\ɒQ=  =              I webrick/httpauth.rbnu [        PK       vY\	t8                eO webrick/ssl.rbnu [        PK       vY\=%w                ` webrick/config.rbnu [        PK       xY\n>                Qm webrick/httpservlet.rbnu [        PK       yY\`                4p webrick/httpservlet/abstract.rbnu [        PK       yY\Bh    "            w webrick/httpservlet/prochandler.rbnu [        PK       zY\8iɚ    !            z webrick/httpservlet/erbhandler.rbnu [        PK       zY\XgV    !            x webrick/httpservlet/cgihandler.rbnu [        PK       {Y\'6  6  "             webrick/httpservlet/filehandler.rbnu [        PK       {Y\-!    !             webrick/httpservlet/cgi_runner.rbnu [        PK       |Y\6f|u                E webrick/compat.rbnu [        PK       Y\9
E	  E	  !            : webrick/httpauth/authenticator.rbnu [        PK       Y\x{,  ,               webrick/httpauth/digestauth.rbnu [        PK       Y\^                 webrick/httpauth/basicauth.rbnu [        PK       Y\VL                	 webrick/httpauth/userdb.rbnu [        PK       Y\[                < webrick/httpauth/htgroup.rbnu [        PK       Y\w  w              ) webrick/httpauth/htdigest.rbnu [        PK       Y\U؝m                 webrick/httpauth/htpasswd.rbnu [        PK       Y\-G_  _              %# webrick/version.rbnu [        PK       Y\F!  !              $ webrick/cookie.rbnu [        PK       Y\"HZ   Z   
            (1 profile.rbnu [        PK       Y\[k  k  
            1 ostruct.rbnu [        PK       Y\$@	  @	  
            a? rss/2.0.rbnu [        PK       Y\;}Px  x              H rss/image.rbnu [        PK       Y\Ye    
            [ rss/xml.rbnu [        PK       Y\]S                  a rss/dublincore/2.0.rbnu [        PK       Y\T                b rss/dublincore/atom.rbnu [        PK       Y\G/  /               d rss/dublincore/1.0.rbnu [        PK       Y\/H                e rss/content.rbnu [        PK       Y\usK  K              h rss/atom.rbnu [        PK       Y\?y                   rss/content/2.0.rbnu [        PK       Y\
                   rss/content/1.0.rbnu [        PK       Y\Vq@  @  
            z rss/rss.rbnu [        PK       Y\                 : rss/xml-stylesheet.rbnu [        PK       Y\o                C rss/slash.rbnu [        PK       Y\LN{
  {
              H rss/utils.rbnu [        PK       Y\&@                S rss/taxonomy.rbnu [        PK       Y\Y%  %  
            _ rss/0.9.rbnu [        PK       Y\(|  |               rss/xmlscanner.rbnu [        PK       Y\#                ؎ rss/syndication.rbnu [        PK       Y\vEJ  J              & rss/xmlparser.rbnu [        PK       Y\J"u"  u"  
             rss/1.0.rbnu [        PK       Y\P                _ rss/converter.rbnu [        PK       Y\*:e	  	              { rss/maker/2.0.rbnu [        PK       Y\ئf  f               rss/maker/image.rbnu [        PK       Y\ë                l rss/maker/content.rbnu [        PK       Y\}Z[  [              0 rss/maker/base.rbnu [        PK       Y\DG`                
O rss/maker/atom.rbnu [        PK       Y\                Ja rss/maker/slash.rbnu [        PK       Y\_                kd rss/maker/taxonomy.rbnu [        PK       Y\)j,  ,              8q rss/maker/0.9.rbnu [        PK       Y\r]  ]              M rss/maker/syndication.rbnu [        PK       Y\ƾ                 rss/maker/entry.rbnu [        PK       Y\Fv(  (               rss/maker/1.0.rbnu [        PK       Y\-c                s rss/maker/dublincore.rbnu [        PK       Y\g                m rss/maker/itunes.rbnu [        PK       Y\tP  P               rss/maker/trackback.rbnu [        PK       Y\ц2  2              Q rss/maker/feed.rbnu [        PK       Y\%I{                B rss/dublincore.rbnu [        PK       Y\9'  '              GS rss/itunes.rbnu [        PK       Y\*>>:  :              V{ rss/parser.rbnu [        PK       Y\V
                + rss/trackback.rbnu [        PK       Y\#                 rss/maker.rbnu [        PK       Y\>sq  q               rss/rexmlparser.rbnu [        PK       Y\x6&OS  S  	             resolv.rbnu [        PK       Y\E                Q securerandom.rbnu [        PK       Y\G                 io/nonblock.rbnu [        PK       Y\WR    
            w gserver.rbnu [        PK       Y\XZF  ZF  	            j logger.rbnu [        PK       Y\r FO   O               0 singleton.rbnu [        PK       Y\/7lO  O              Q parsedate.rbnu [        PK       Y\
    
            W monitor.rbnu [        PK       Y\1P7  7              w parsearg.rbnu [        PK       Y\$ū                s} x86_64-linux/defines.hnu [        PK       Y\)                d x86_64-linux/util.hnu [        PK       Y\kkP8W  W               x86_64-linux/ruby.hnu [        PK       Y\.  .               x86_64-linux/io/wait.sonu ȯ        PK       Y\qA8a  8a              #	 x86_64-linux/dbm.sonu ȯ        PK       Y\: r   r              |	 x86_64-linux/sdbm.sonu ȯ        PK       Y\}=                	 x86_64-linux/zlib.sonu ȯ        PK       Y\kBQ  Q              
 x86_64-linux/thread.sonu ȯ        PK       Y\`<,  ,              
 x86_64-linux/version.hnu [        PK       Y\@  @               x86_64-linux/etc.sonu ȯ        PK       Y\˚ b   b              ?B x86_64-linux/strscan.sonu ȯ        PK       Y\!"  "               x86_64-linux/dl.hnu [        PK       Y\v A  A              m x86_64-linux/digest/sha2.sonu ȯ        PK       Y\N                  p	 x86_64-linux/digest/sha1.sonu ȯ        PK       Y\7Ǡ                  S* x86_64-linux/digest/md5.sonu ȯ        PK       Y\pC                  =K x86_64-linux/digest/rmd160.sonu ȯ        PK       Y\;.  .  #            *l x86_64-linux/digest/bubblebabble.sonu ȯ        PK       Y\%0Q  0Q              e x86_64-linux/iconv.sonu ȯ        PK       Y\a7` b   b               x86_64-linux/gdbm.sonu ȯ        PK       Y\2              O x86_64-linux/syck.sonu ȯ        PK       Y\xJHM  HM              JL x86_64-linux/intern.hnu [        PK       Y\ʏ                י x86_64-linux/re.hnu [        PK       Y\O                  & x86_64-linux/dln.hnu [        PK       Y\39
  
               x86_64-linux/missing.hnu [        PK       Y\mɐ                 x86_64-linux/bigdecimal.sonu ȯ        PK       Y\Ka  a               x86_64-linux/readline.sonu ȯ        PK       Y\VEB{  {               x86_64-linux/digest.hnu [        PK       Y\uR                  j x86_64-linux/fcntl.sonu ȯ        PK       Y\ve               x86_64-linux/dl.sonu ȯ        PK       Y\Х               x86_64-linux/nkf.sonu ȯ        PK       Y\wAC                 x86_64-linux/curses.sonu ȯ        PK       Y\
(h@  h@              Zi x86_64-linux/pty.sonu ȯ        PK       Y\M{	  	               x86_64-linux/rubyio.hnu [        PK       Y\Q)3  3              + x86_64-linux/node.hnu [        PK       Y\ߖ P   P               x86_64-linux/racc/cparse.sonu ȯ        PK       Y\.v>J  J              e8 x86_64-linux/rubysig.hnu [        PK       Y\)oŝ                C x86_64-linux/dlconfig.hnu [        PK       Y\|q  q              E x86_64-linux/stringio.sonu ȯ        PK       Y\MVpP  P               x86_64-linux/st.hnu [        PK       Y\M3e@  @               x86_64-linux/digest.sonu ȯ        PK       Y\                p  x86_64-linux/config.hnu [        PK       Y\ʈx  x              z x86_64-linux/env.hnu [        PK       Y\L@  @              4 x86_64-linux/syslog.sonu ȯ        PK       Y\f"  "              ] x86_64-linux/rbconfig.rbnu [        PK       Y\X                8 x86_64-linux/socket.sonu ȯ        PK       Y\                VU x86_64-linux/openssl.sonu ȯ        PK       Y\g<#  #              < x86_64-linux/regex.hnu [        PK       Y\8                $[ observer.rbnu [        PK       Y\aW  W  	            o ipaddr.rbnu [        PK       Y\8  8              
 rinda/ring.rbnu [        PK       Y\zn@?  ?               rinda/rinda.rbnu [        PK       Y\гJ7  7               rinda/tuplespace.rbnu [        PK       Y\̛& &             .  cgi.rbnu [        PK       Y\0)  )              V! openssl/pkcs7.rbnu [        PK       Y\
  
              yX! openssl/x509-internal.rbnu [        PK       Y\`                i! openssl/cipher.rbnu [        PK       Y\z                p! openssl/bn.rbnu [        PK       Y\p3`                ss! openssl/buffering.rbnu [        PK       Y\)s                  ! openssl/ssl.rbnu [        PK       Y\E=L  L              ! openssl/config.rbnu [        PK       Y\=f                v! openssl/digest.rbnu [        PK       Y\8                 ~! openssl/ssl-internal.rbnu [        PK       Y\)s                  ! openssl/x509.rbnu [        PK       Y\ھ                ! rexml/syncenumerator.rbnu [        PK       Y\Bu                ! rexml/output.rbnu [        PK       Y\nFj  j              ̾! rexml/entity.rbnu [        PK       Y\Fyk  k              u! rexml/dtd/dtd.rbnu [        PK       Y\|昶                   ! rexml/dtd/attlistdecl.rbnu [        PK       Y\
_                ! rexml/dtd/elementdecl.rbnu [        PK       Y\kZ*                ! rexml/dtd/entitydecl.rbnu [        PK       Y\ oa                ! rexml/dtd/notationdecl.rbnu [        PK       Y\$돇                ! rexml/light/node.rbnu [        PK       Y\"2+  2+              ! rexml/functions.rbnu [        PK       Y\W
  
              8 " rexml/formatters/default.rbnu [        PK       Y\˂o-                X+" rexml/formatters/transitive.rbnu [        PK       Y\	S_  _              2" rexml/formatters/pretty.rbnu [        PK       Y\9  9              >D" rexml/source.rbnu [        PK       Y\\
bI,  ,              `" rexml/text.rbnu [        PK       Y\a                " rexml/namespace.rbnu [        PK       Y\;ŝ                ̑" rexml/quickpath.rbnu [        PK       Y\3%                " rexml/xmltokens.rbnu [        PK       Y\(:2
  
              " rexml/xmldecl.rbnu [        PK       Y\L                " rexml/rexml.rbnu [        PK       Y\4
a.  .              " rexml/attlistdecl.rbnu [        PK       Y\聓_:  :              H" rexml/validation/relaxng.rbnu [        PK       Y\Yڑ      '            # rexml/validation/validationexception.rbnu [        PK       Y\R_5  5              # rexml/validation/validation.rbnu [        PK       Y\Sŕ                ~# rexml/parent.rbnu [        PK       Y\                R*# rexml/doctype.rbnu [        PK       Y\`      $            !E# rexml/undefinednamespaceexception.rbnu [        PK       Y\x                GF# rexml/instruction.rbnu [        PK       Y\:i                !N# rexml/comment.rbnu [        PK       Y\)*                ]V# rexml/encodings/ICONV.rbnu [        PK       Y\*                VX# rexml/encodings/UNILE.rbnu [        PK       Y\3#                [# rexml/encodings/UTF-8.rbnu [        PK       Y\,v>                  \# rexml/encodings/ISO-8859-1.rbnu [        PK       Y\                ]# rexml/encodings/US-ASCII.rbnu [        PK       Y\F	m	  	              `# rexml/encodings/ISO-8859-15.rbnu [        PK       Y\(FS  S              i# rexml/encodings/EUC-JP.rbnu [        PK       Y\M&  &              ul# rexml/encodings/CP-1252.rbnu [        PK       Y\(;8                |# rexml/encodings/UTF-16.rbnu [        PK       Y\<rއ                G# rexml/encodings/SHIFT-JIS.rbnu [        PK       Y\`m$   $               # rexml/encodings/SHIFT_JIS.rbnu [        PK       Y\{{S  S              # rexml/encoding.rbnu [        PK       Y\                # rexml/parsers/sax2parser.rbnu [        PK       Y\L  L              c# rexml/parsers/xpathparser.rbnu [        PK       Y\UHJ  J              # rexml/parsers/baseparser.rbnu [        PK       Y\^=                ^B$ rexml/parsers/streamparser.rbnu [        PK       Y\@H    !            >H$ rexml/parsers/ultralightparser.rbnu [        PK       Y\廋z  z              gM$ rexml/parsers/treeparser.rbnu [        PK       Y\l W  W              ,[$ rexml/parsers/pullparser.rbnu [        PK       Y\O"g  g              o$ rexml/parsers/lightparser.rbnu [        PK       Y\K7                u$ rexml/document.rbnu [        PK       Y\)                $ rexml/node.rbnu [        PK       Y\z                w$ rexml/sax2listener.rbnu [        PK       Y\
\	  	              $ rexml/xpath.rbnu [        PK       Y\uL                N$ rexml/streamlistener.rbnu [        PK       Y\#&                n$ rexml/parseexception.rbnu [        PK       Y\                $ rexml/element.rbnu [        PK       Y\Jq|                v% rexml/cdata.rbnu [        PK       Y\                |% rexml/attribute.rbnu [        PK       Y\	  	              % rexml/child.rbnu [        PK       Y\d  d              ,% rexml/xpath_parser.rbnu [        PK       Y\8Fc	  	  
             & getopts.rbnu [        PK       Y\?  ?              I	& pp.rbnu [        PK       Y\Fb                [I& shell.rbnu [        PK       Y\C    	            2\& eregex.rbnu [        PK       Y\ԌI                  R^& kconv.rbnu [        PK       Y\N7Nl  Nl              	& set.rbnu [        PK       Y\N>el1  l1              & yaml.rbnu [        PK       Y\Q                  0' rubyunit.rbnu [        PK       Y\8h   h   	            ' thread.rbnu [        PK       Y\V	    
            ' cgi-lib.rbnu [        PK       Y\:                :' digest/sha2.rbnu [        PK       Y\?  ?  
            @' openssl.rbnu [        PK       Y\1w                C' rss.rbnu [        PK       Y\xCR  R              2E' scanf.rbnu [        PK       Y\R                ' yaml/basenode.rbnu [        PK       Y\3v                "' yaml/stream.rbnu [        PK       Y\                ' yaml/syck.rbnu [        PK       Y\]                g' yaml/constants.rbnu [        PK       Y\7O  O              J' yaml/tag.rbnu [        PK       Y\k"u(  (              ' yaml/loader.rbnu [        PK       Y\b\1                :' yaml/types.rbnu [        PK       Y\C0  0              ' yaml/ypath.rbnu [        PK       Y\Uy  y              n' yaml/baseemitter.rbnu [        PK       Y\׏                *' yaml/stringio.rbnu [        PK       Y\uo]  ]              ' yaml/encoding.rbnu [        PK       Y\!                ( yaml/store.rbnu [        PK       Y\t                ( yaml/yamlnode.rbnu [        PK       Y\g\2  2              	( yaml/rubytypes.rbnu [        PK       Y\;N-  -              <( yaml/error.rbnu [        PK       Y\
8O4                JA( yaml/dbm.rbnu [        PK       Y\G,r  r              J( tempfile.rbnu [        PK       Y\'6  6              ,^( resolv-replace.rbnu [        PK       Y\ܽ                d( date.rbnu [        PK       Y\+0    
            8) timeout.rbnu [        PK       Y\g~^Z  Z              2E) runit/testresult.rbnu [        PK       Y\?W                H) runit/cui/testrunner.rbnu [        PK       Y\>@/  /              M) runit/assert.rbnu [        PK       Y\Ϋa                  IU) runit/topublic.rbnu [        PK       Y\0                 :V) runit/testcase.rbnu [        PK       Y\2'L                Z) runit/testsuite.rbnu [        PK        Z\}3$                  \) runit/error.rbnu [        PK        Z\H~qd  d              &^) open3.rbnu [        PK        Z\}                  f) date2.rbnu [        PK        Z\=RnpR  pR              zg) debug.rbnu [        PK        Z\?rK[  [              ") profiler.rbnu [        PK        Z\                ) tsort.rbnu [        PK        Z\ &	y  y  	            ) expect.rbnu [        PK        Z\UWI  WI              ) prettyprint.rbnu [        PK        Z\-!~a  a              0-* csv.rbnu [        PK        Z\y|8X  X              <* find.rbnu [        PK        Z\_&ݧ                ˖* forwardable.rbnu [        PK       Z\H&                * xsd/codegen.rbnu [        PK       Z\@{ژ                * xsd/namedelements.rbnu [        PK       Z\LY                * xsd/datatypes1999.rbnu [        PK       Z\'t`  `              g* xsd/datatypes.rbnu [        PK       Z\h                + xsd/qname.rbnu [        PK       Z\OG                 + xsd/charset.rbnu [        PK       Z\E+                5+ xsd/iconvcharset.rbnu [        PK       Z\o]                8+ xsd/xmlparser.rbnu [        PK       Z\b )  )              =+ xsd/codegen/classdef.rbnu [        PK       Z\w^  ^              OO+ xsd/codegen/commentdef.rbnu [        PK       Z\ Y  Y              Q+ xsd/codegen/gensupport.rbnu [        PK       Z\Sb4;                ]+ xsd/codegen/moduledef.rbnu [        PK       Z\uD<                m+ xsd/codegen/methoddef.rbnu [        PK       Z\r
  
  	            r+ xsd/ns.rbnu [        PK       Z\                }+ xsd/mapping.rbnu [        PK       Z\8v
  
              + xsd/xmlparser/xmlscanner.rbnu [        PK       Z\Vn  n              + xsd/xmlparser/xmlparser.rbnu [        PK       Z\);T_  _              + xsd/xmlparser/parser.rbnu [        PK       Z\hG  G              B+ xsd/xmlparser/rexmlparser.rbnu [        PK       	Z\3);#  ;#              ՝+ delegate.rbnu [        PK       	Z\]&  &              K+ un.rbnu [        PK       
Z\    	            + tmpdir.rbnu [        PK       
Z\р    	            + ftools.rbnu [        PK       Z\a ?                + fileutils.rbnu [        PK       Z\ojV                , md5.rbnu [        PK       Z\                , ping.rbnu [        PK       Z\0mr  r              , date/format.rbnu [        PK       Z\׎1                - wsdl/part.rbnu [        PK       Z\f                "- wsdl/wsdl.rbnu [        PK       Z\>w@1	  1	              %- wsdl/data.rbnu [        PK       Z\}@9  9              y.- wsdl/importer.rbnu [        PK       Z\4                1- wsdl/operationBinding.rbnu [        PK       Z\	[                	:- wsdl/types.rbnu [        PK       Z\Iƽ&e  e               =- wsdl/xmlSchema/complexContent.rbnu [        PK       Z\fU                D- wsdl/xmlSchema/complexType.rbnu [        PK       Z\	
t                P- wsdl/xmlSchema/data.rbnu [        PK       Z\@                ^- wsdl/xmlSchema/importer.rbnu [        PK       Z\֩D                g- wsdl/xmlSchema/pattern.rbnu [        PK       Z\    #            i- wsdl/xmlSchema/simpleRestriction.rbnu [        PK       Z\(R  R               p- wsdl/xmlSchema/length.rbnu [        PK       Z\]  ]              r- wsdl/xmlSchema/content.rbnu [        PK       Z\TS                @y- wsdl/xmlSchema/schema.rbnu [        PK       Z\H  H              - wsdl/xmlSchema/unique.rbnu [        PK        Z\rY  Y              ,- wsdl/xmlSchema/annotation.rbnu [        PK       !Z\Σu/                ъ- wsdl/xmlSchema/all.rbnu [        PK       !Z\	6%                - wsdl/xmlSchema/sequence.rbnu [        PK       "Z\Z
T  T              - wsdl/xmlSchema/xsd2ruby.rbnu [        PK       "Z\U%                1- wsdl/xmlSchema/enumeration.rbnu [        PK       "Z\p                - wsdl/xmlSchema/import.rbnu [        PK       #Z\8n                - wsdl/xmlSchema/simpleContent.rbnu [        PK       $Z\#                - wsdl/xmlSchema/choice.rbnu [        PK       %Z\.O                ï- wsdl/xmlSchema/parser.rbnu [        PK       %Z\@  @              - wsdl/xmlSchema/any.rbnu [        PK       &Z\L                7- wsdl/xmlSchema/include.rbnu [        PK       'Z\#*{A  A              v- wsdl/xmlSchema/element.rbnu [        PK       'Z\=t    !             - wsdl/xmlSchema/simpleExtension.rbnu [        PK       'Z\#~  ~              - wsdl/xmlSchema/simpleType.rbnu [        PK       (Z\
  
              - wsdl/xmlSchema/attribute.rbnu [        PK       (Z\^0  0              %- wsdl/info.rbnu [        PK       (Z\J;                - wsdl/definitions.rbnu [        PK       )Z\_WA  A              . wsdl/documentation.rbnu [        PK       *Z\;pn                -. wsdl/message.rbnu [        PK       *Z\)J                	. wsdl/param.rbnu [        PK       *Z\B                . wsdl/binding.rbnu [        PK       +Z\,;                . wsdl/portType.rbnu [        PK       ,Z\˃ʱ                . wsdl/import.rbnu [        PK       -Z\y5
  5
              !. wsdl/operation.rbnu [        PK       -Z\	                <,. wsdl/parser.rbnu [        PK       .Z\UIla  a              <. wsdl/service.rbnu [        PK       .Z\G	  	  (            @. wsdl/soap/standaloneServerStubCreator.rbnu [        PK       .Z\L!`  `              J. wsdl/soap/cgiStubCreator.rbnu [        PK       /Z\R͛                S. wsdl/soap/complexType.rbnu [        PK       /Z\Q	  	              c. wsdl/soap/data.rbnu [        PK       /Z\7	(                h. wsdl/soap/address.rbnu [        PK       1Z\7K:  :              k. wsdl/soap/headerfault.rbnu [        PK       1Z\P0Y    "            ;p. wsdl/soap/servantSkeltonCreator.rbnu [        PK       2Z\Z~  ~              v. wsdl/soap/definitions.rbnu [        PK       3Z\#Ph  h              o. wsdl/soap/body.rbnu [        PK       3Z\^8	  	  #            . wsdl/soap/classDefCreatorSupport.rbnu [        PK       4Z\#{(  (              g. wsdl/soap/fault.rbnu [        PK       5Z\u?D    !            ћ. wsdl/soap/clientSkeltonCreator.rbnu [        PK       6Z\Xd	  	              â. wsdl/soap/driverCreator.rbnu [        PK       7Z\6vq  q              . wsdl/soap/wsdl2ruby.rbnu [        PK       7Z\X L                . wsdl/soap/binding.rbnu [        PK       8Z\q                 . wsdl/soap/header.rbnu [        PK       8Z\RG
  
              u. wsdl/soap/operation.rbnu [        PK       9Z\8P    #            . wsdl/soap/mappingRegistryCreator.rbnu [        PK       ;Z\S!  S!              . wsdl/soap/classDefCreator.rbnu [        PK       <Z\٢I"r  r              r / wsdl/soap/methodDefCreator.rbnu [        PK       =Z\&                1/ wsdl/soap/element.rbnu [        PK       AZ\^Df  f              / wsdl/port.rbnu [        PK       CZ\܃t30  30              /#/ rational.rbnu [        PK       DZ\pgVq  q              S/ drb/observer.rbnu [        PK       EZ\M}	  	              MU/ drb/unix.rbnu [        PK       FZ\>2g  g              ?_/ drb/extservm.rbnu [        PK       FZ\$УS
  S
  
            e/ drb/acl.rbnu [        PK       GZ\"                rp/ drb/timeridconv.rbnu [        PK       GZ\vg'F                v/ drb/invokemethod.rbnu [        PK       HZ\5s    
            y/ drb/ssl.rbnu [        PK       HZ\WJ    
            / drb/drb.rbnu [        PK       IZ\܉̕      	            ^0 drb/eq.rbnu [        PK       IZ\j    	            _0 drb/gw.rbnu [        PK       IZ\+6{9  9              g0 drb/extserv.rbnu [        PK       JZ\P EE  E              #l0 cgi/session.rbnu [        PK       KZ\T#p4  4              r0 cgi/session/pstore.rbnu [        PK       KZ\Ј                0 bigdecimal/newton.rbnu [        PK       LZ\!                =0 bigdecimal/util.rbnu [        PK       LZ\:O  O              u0 bigdecimal/ludcmp.rbnu [        PK       NZ\                 0 bigdecimal/math.rbnu [        PK       OZ\ y                0 bigdecimal/jacobian.rbnu [        PK       QZ\Iُ ُ             !0 net/imap.rbnu [        PK       QZ\w;`                52 net/protocol.rbnu [        PK       RZ\^/Yap  p              2 net/smtp.rbnu [        PK       SZ\/ ;                 N3 net/https.rbnu [        PK       TZ\QC  C              $3 net/telnets.rbnu [        PK       TZ\ҝf  f  
            %D3 net/pop.rbnu [        PK       UZ\f                L3 net/http.rbnu [        PK       UZ\@                y4 net/ftptls.rbnu [        PK       UZ\e;V  ;V  
            4 net/ftp.rbnu [        PK       UZ\C~  ~              	5 net/telnet.rbnu [        PK       UZ\\·                	5 irb/ruby-token.rbnu [        PK       VZ\SW  W              5 irb/init.rbnu [        PK       VZ\r)X  X              5 irb/cmd/nop.rbnu [        PK       VZ\o  o              )5 irb/cmd/fork.rbnu [        PK       WZ\$b                 5 irb/cmd/subirb.rbnu [        PK       WZ\k=                5 irb/cmd/chws.rbnu [        PK       WZ\L M  M              5 irb/cmd/help.rbnu [        PK       XZ\E1                5 irb/cmd/pushws.rbnu [        PK       XZ\ิ                L5 irb/cmd/load.rbnu [        PK       YZ\|Ӑ~y  y              ;5 irb/ext/history.rbnu [        PK       ZZ\Jx  x              5 irb/ext/save-history.rbnu [        PK       [Z\	  	              5 irb/ext/loader.rbnu [        PK       \Z\cq  q              5 irb/ext/math-mode.rbnu [        PK       \Z\                5 irb/ext/workspaces.rbnu [        PK       ]Z\G                5 irb/ext/change-ws.rbnu [        PK       `Z\I|S  S              5 irb/ext/use-loader.rbnu [        PK       bZ\>                35 irb/ext/tracer.rbnu [        PK       dZ\+                  6 irb/ext/multi-irb.rbnu [        PK       eZ\.    
            ^6 irb/xmp.rbnu [        PK       fZ\sh  h              6 irb/completion.rbnu [        PK       gZ\S0
  0
              ..6 irb/workspace.rbnu [        PK       hZ\1I                86 irb/ws-for-case-2.rbnu [        PK       iZ\(_;  ;              96 irb/input-method.rbnu [        PK       jZ\&F  F              bA6 irb/help.rbnu [        PK       jZ\V                C6 irb/context.rbnu [        PK       jZ\DmU  U              0\6 irb/ruby-lex.rbnu [        PK       kZ\6|  |              6 irb/locale.rbnu [        PK       kZ\-  -              6 irb/output-method.rbnu [        PK       lZ\~W                 6 irb/extend-command.rbnu [        PK       mZ\L(E  E              6 irb/slex.rbnu [        PK       nZ\.  .              w6 irb/lc/help-messagenu [        PK       nZ\                 7 irb/lc/ja/help-messagenu [        PK       oZ\*O.  .              7 irb/lc/ja/error.rbnu [        PK       oZ\nX                ,7 irb/lc/error.rbnu [        PK       qZ\z/  /              	7 irb/version.rbnu [        PK       rZ\B                v7 irb/frame.rbnu [        PK       rZ\fC U
  
              7 irb/notifier.rbnu [        PK       sZ\4q                !7 shellwords.rbnu [        PK       sZ\KC̼
  
  
            27 weakref.rbnu [        PK       tZ\{aC  C              	=7 readbytes.rbnu [        PK       tZ\}y4
  
  	            @7 tracer.rbnu [        PK       uZ\u-  -              K7 racc/parser.rbnu [        PK       uZ\>,  ,  	            y7 pstore.rbnu [        PK       vZ\-q                7 Env.rbnu [        PK       wZ\Րk                  ӧ7 drb.rbnu [        PK       wZ\ln[3  [3  
            7 complex.rbnu [        PK       xZ\+                7 dl/struct.rbnu [        PK       xZ\b                l7 dl/types.rbnu [        PK       xZ\nI  I              8 dl/win32.rbnu [        PK       yZ\Y'C                /8 dl/import.rbnu [        PK       zZ\"g0  0              H8 jcode.rbnu [        PK       {Z\2Vi  i              )8 test/unit/collector.rbnu [        PK       |Z\=!n  n              _-8 test/unit/collector/dir.rbnu [        PK       }Z\+  +  "            :8 test/unit/collector/objectspace.rbnu [        PK       }Z\2>  >              =8 test/unit/ui/gtk2/testrunner.rbnu [        PK       Z\` Dc"  c"              |8 test/unit/ui/tk/testrunner.rbnu [        PK       Z\00  0  "            M8 test/unit/ui/testrunnermediator.rbnu [        PK       Z\\~!  ~!              ϧ8 test/unit/ui/fox/testrunner.rbnu [        PK       Z\K    #            8 test/unit/ui/testrunnerutilities.rbnu [        PK       Z\o/    "            m8 test/unit/ui/console/testrunner.rbnu [        PK       Z\997  7              K8 test/unit/ui/gtk/testrunner.rbnu [        PK       Z\aAmV  V              .9 test/unit/autorunner.rbnu [        PK       Z\K4                /9 test/unit/testresult.rbnu [        PK       Z\ J)  )  !            089 test/unit/assertionfailederror.rbnu [        PK       Z\&  &              99 test/unit/failure.rbnu [        PK       Z\ݮ?3G  3G              ?9 test/unit/assertions.rbnu [        PK       Z\    !            9 test/unit/util/backtracefilter.rbnu [        PK       Z\}hU  U              9 test/unit/util/procwrapper.rbnu [        PK       Z\y3  3              9 test/unit/util/observable.rbnu [        PK       Z\x                9 test/unit/testcase.rbnu [        PK       Z\Fӥ                '9 test/unit/testsuite.rbnu [        PK       Z\                9 test/unit/error.rbnu [        PK       Z\$q+  q+              9 test/unit.rbnu [        PK       Z\`	                9 xmlrpc/create.rbnu [        PK       Z\J  J              9 xmlrpc/client.rbnu [        PK       Z\s                J: xmlrpc/httpserver.rbnu [        PK       Z\_t  t              Z: xmlrpc/datetime.rbnu [        PK       Z\j?;  ;              ji: xmlrpc/marshal.rbnu [        PK       Z\`%                o: xmlrpc/utils.rbnu [        PK       Z\K;%HW  HW              }: xmlrpc/server.rbnu [        PK       Z\$                : xmlrpc/config.rbnu [        PK       Z\                : xmlrpc/base64.rbnu [        PK       Z\XWH  H              : xmlrpc/parser.rbnu [        PK       Z\!{  {  	            ); base64.rbnu [        PK       Z\3d  d  
            7; English.rbnu [        PK       Z\Z>!                BN; shell/filter.rbnu [        PK       Z\Pʷ;  ;              \U; shell/command-processor.rbnu [        PK       Z\n  n              ]; shell/system-command.rbnu [        PK       Z\Ro	  	              ; shell/builtin-command.rbnu [        PK       Z\i  i              1; shell/process-controller.rbnu [        PK       Z\_                ; shell/error.rbnu [        PK       Z\DN_:  :              ; shell/version.rbnu [        PK       Z\!  !              ; rdoc/rdoc.rbnu [        PK       Z\%#H  #H              ; rdoc/code_objects.rbnu [        PK       Z\sp-  -  $            \,< rdoc/markup/simple_markup/to_html.rbnu [        PK       Z\)    &            H< rdoc/markup/simple_markup/fragments.rbnu [        PK       Z\ "   "  #            .f< rdoc/markup/simple_markup/inline.rbnu [        PK       Z\Vڹ    '            < rdoc/markup/simple_markup/preprocess.rbnu [        PK       Z\k    "            < rdoc/markup/simple_markup/lines.rbnu [        PK       Z\8a U~  ~  $            < rdoc/markup/simple_markup/to_flow.rbnu [        PK       Z\7^!  !  %            Э< rdoc/markup/simple_markup/to_latex.rbnu [        PK       Z\8TR8  R8              ?< rdoc/markup/simple_markup.rbnu [        PK       Z\^                 = rdoc/markup/sample/rdoc2latex.rbnu [        PK       Z\v?  ?              	= rdoc/markup/sample/sample.rbnu [        PK       Z\=                  J= rdoc/markup/test/TestInline.rbnu [        PK       Z\w4,  ,              "= rdoc/markup/test/TestParse.rbnu [        PK       Z\Z	/   /               O= rdoc/markup/test/AllTests.rbnu [        PK       Z\;gD  D              LP= rdoc/options.rbnu [        PK       Z\G                = rdoc/parsers/parse_f95.rbnu [        PK       Z\R|Ka  a              ف> rdoc/parsers/parse_c.rbnu [        PK       Z\8Ye\'  '              +> rdoc/parsers/parse_simple.rbnu [        PK       Z\ kU
  
              > rdoc/parsers/parserfactory.rbnu [        PK       Z\T?  ?              }> rdoc/parsers/parse_rb.rbnu [        PK       Z\%l@  @              ? rdoc/template.rbnu [        PK       Z\9O9  9              ? rdoc/ri/ri_formatter.rbnu [        PK       Z\<*                ]/@ rdoc/ri/ri_reader.rbnu [        PK       Z\sb  b              ^8@ rdoc/ri/ri_util.rbnu [        PK       Z\`\l                A@ rdoc/ri/ri_display.rbnu [        PK       Z\|Qi"  i"              [@ rdoc/ri/ri_options.rbnu [        PK       Z\98  8              {~@ rdoc/ri/ri_cache.rbnu [        PK       Z\/                @ rdoc/ri/ri_writer.rbnu [        PK       Z\                ?@ rdoc/ri/ri_descriptions.rbnu [        PK       Z\O7                `@ rdoc/ri/ri_driver.rbnu [        PK       Z\>ꞗ                h@ rdoc/ri/ri_paths.rbnu [        PK       Z\@K{  {              B@ rdoc/dot/dot.rbnu [        PK       Z\M)Mę  ę  !            @ rdoc/generators/html_generator.rbnu [        PK       Z\>4_  _              sA rdoc/generators/ri_generator.rbnu [        PK       Z\&5L  L               A rdoc/generators/chm_generator.rbnu [        PK       Z\%6w  w  #            [A rdoc/generators/template/xml/xml.rbnu [        PK       Z\Og	  	  #            %A rdoc/generators/template/xml/rdf.rbnu [        PK       Z\    #            A rdoc/generators/template/chm/chm.rbnu [        PK       Z\aV"  "  &            δA rdoc/generators/template/html/hefss.rbnu [        PK       Z\(g%O#  O#  '            A rdoc/generators/template/html/kilmer.rbnu [        PK       Z\d8f?  f?  %            A rdoc/generators/template/html/html.rbnu [        PK       Z\%`C  C  )            [;B rdoc/generators/template/html/old_html.rbnu [        PK       Z\.S͇    .            B rdoc/generators/template/html/one_page_html.rbnu [        PK       Z\^.s                 B rdoc/generators/xml_generator.rbnu [        PK       Z\\                B rdoc/usage.rbnu [        PK       Z\Lف/  /              B rdoc/diagram.rbnu [        PK       Z\%Ȅ                B rdoc/tokenstream.rbnu [        PK       Z\VC                B mathn.rbnu [        PK       Z\qc                B finalize.rbnu [        PK       Z\uSɂ;  ;              WC getoptlong.rbnu [        PK       Z\BD  D  	            AC thwait.rbnu [        PK       Z\P-wu  u              RC pathname.rbnu [        PK       Z\$+j                YC irb.rbnu [        PK       Z\U                GC uri/https.rbnu [        PK       Z\?                uC uri/ldaps.rbnu [        PK       Z\(p0Z
  Z
              C uri/http.rbnu [        PK       Z\OKi                dC uri/ldap.rbnu [        PK       Z\͇MX^  X^              D uri/generic.rbnu [        PK       Z\/[D  D              C`D uri/common.rbnu [        PK       Z\UT    
             D uri/ftp.rbnu [        PK       Z\5#                 ޹D uri/mailto.rbnu [        PK       Z\8`X  X              7D sync.rbnu [        PK       Z\;E  E              D optparse/date.rbnu [        PK       Z\Zvvy   y               KD optparse/shellwords.rbnu [        PK       Z\[hzd   d               
D optparse/uri.rbnu [        PK       Z\?߅                D optparse/version.rbnu [        PK       Z\7&                  D optparse/time.rbnu [        PK       Z\{7N  N              D importenv.rbnu [        PK       Z\"a
  
  	            fD abbrev.rbnu [        PK       Z\U                E sha1.rbnu [        PK       Z\W                {E soap/netHttpClient.rbnu [        PK       Z\u                E soap/generator.rbnu [        PK       Z\Ꞙ                3E soap/httpconfigloader.rbnu [        PK       Z\!-  -              @E soap/header/handlerset.rbnu [        PK       Z\T                EE soap/header/handler.rbnu [        PK       Z\Nܣ                JE soap/header/simplehandler.rbnu [        PK       Z\$r}  }              NE soap/processor.rbnu [        PK       Z\X'                TE soap/mimemessage.rbnu [        PK       Z\2 CB  B              hE soap/baseData.rbnu [        PK       Z\ j                ߫E soap/soap.rbnu [        PK       Z\Ԫ[:                E soap/marshal.rbnu [        PK       Z\0c+F  F              \E soap/rpc/router.rbnu [        PK       Z\l                yF soap/rpc/cgistub.rbnu [        PK       Z\x                @F soap/rpc/httpserver.rbnu [        PK       Z\R&  &              w*F soap/rpc/rpc.rbnu [        PK       Z\W*:  :              ,F soap/rpc/proxy.rbnu [        PK       Z\ p                gF soap/rpc/soaplet.rbnu [        PK       Z\$                #wF soap/rpc/standaloneServer.rbnu [        PK       Z\mT׋                {F soap/rpc/element.rbnu [        PK       Z\|@K  K              PF soap/rpc/driver.rbnu [        PK       Z\ҍɜ    &            ݱF soap/encodingstyle/aspDotNetHandler.rbnu [        PK       Z\s3  3  $            F soap/encodingstyle/literalHandler.rbnu [        PK       Z\dS9  S9  !            9F soap/encodingstyle/soapHandler.rbnu [        PK       Z\b,X?  ?              G soap/encodingstyle/handler.rbnu [        PK       Z\C`pp  p              iG soap/streamHandler.rbnu [        PK       Z\/~α                3G soap/property.rbnu [        PK       Z\&mBW
@  
@              OG soap/mapping/registry.rbnu [        PK       Z\ʻ$oB<  B<              aG soap/mapping/rubytypeFactory.rbnu [        PK       Z\P|-  |-  #            G soap/mapping/wsdlliteralregistry.rbnu [        PK       Z\\#  #              G soap/mapping/factory.rbnu [        PK       Z\.C-                H soap/mapping/typeMap.rbnu [        PK       Z\X&+  +              Y$H soap/mapping/mapping.rbnu [        PK       Z\ue,  ,  #            :PH soap/mapping/wsdlencodedregistry.rbnu [        PK       Z\.4!  !              oH soap/parser.rbnu [        PK       Z\^?  ?              H soap/wsdlDriver.rbnu [        PK       Z\U}  }              _H soap/mapping.rbnu [        PK       Z\                H soap/element.rbnu [        PK       Z\Y                H soap/attachment.rbnu [        PK       Z\ʜay  y  	            (H digest.rbnu [        PK       Z\>O1                H uri.rbnu [        PK       Z\?JJ  J  
            H mutex_m.rbnu [        PK       Z\OGR~  R~              ZH time.rbnu [        PK       Z\zU  U              uI erb.rbnu [        PK       Z\|  |              I optparse.rbnu [        PK       Z\O                UJ