------art_22039_33231460.1173638741779
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

It doesn't get any faster
at least I got it shorter

649/150 > cat torus.rb
# vim: sw sts nu twexpandtab nowrap:
#
#

ICE  lass.new
VAPOR  lass.new
VACUUM  lass.new


###############################################################
#
# a small reference to Python ;)
#
###############################################################
def Torus( rows, cols, vapors, start  il )
  Torus_.new( rows.to_i, cols.to_i, vapors.to_f, start )
end

class Torus_

  ###############################################################
  #
  #    Torus_
  #
  ###############################################################
  attr_reader :lines, :columns
  attr_reader :generation
  attr_accessor :formatter, :name
  def initialize rows, cols, vapors, start
    @lines  ows
    @columns  ols
    @vapors  apors
    @generation  
    if start then
      @start  tart.split("@").map{|e| e.to_i}
    else
      @start ||  rows/2, cols /2 ]
    end
    @nhoods  ]  # we will store neighborhoods identified by
    # their upper left corner index, odd is for even generations
    # and even is for odd generations, which might seem odd.
    reset_values
    set_vapors
  end

  def [] line, coll
    return @values[line] unless col
    @values[line][col]
  end # def [](line, coll)
  def [] ine, col, val
    @values[line][col]  al
  end

  def each_line
    @values.each{ |line| yield line }
  end

  def each_nbh
    r    generation % 2
    loop do
      yield @nhoods[ r * @lines + c ] ||Neighborhood.new( self, r, r.succ % @lines, c, c.succ % @columns )
      c + 
      r +  unless c < @columns
      return unless r < @lines
      c % columns
      r % lines
    end
  end

  def start_sim
    until no_more_vapor? do
      tick
      write
    end
  end # def start_sim

  def tick
    puts "Simulation #{@name} generation #{@generation}:"
    @generation + 
    each_nbh do
      | nbh |
      nbh.recalc
    end
  end

  private

  def no_more_vapor?
    ! @values.any?{ |line|
      line.any?{ |v| v VAPOR }
    }
  end

  def reset_values
    @values  rray.new(@lines){
      Array.new(@columns){
        VACUUM
      }
    }
  end
  def set_vapors
    total  lines * @columns
    v   @vapors *  (total-1) ).to_i
    x  *0..total-2]
    at  ]
    v.times do
      at << x.delete_at( rand(x.size) )
    end
    at.each do
      | index |
      @values[index/@lines][index% / lines]  APOR
    end
    @values[@lines-1][@columns-1]  values[@start.first][@start.last]
    @values[@start.first][@start.last]  CE
  end # def set_vapors

  def write
    @formatter.to_file self, "output/#{@name}.%08d" % @generation
  end # def write

end # class Torus_

###############################################################
#
#    Neighborhood is implementing a 2x2 window to any object
#    that responds to #[]n,m and #[]m,value
#    It implements the operation of rotation.
#
###############################################################
class Neighborhood
  include Enumerable

  # Neighborhood gives us the following indexed view to the underlying
  # torus
  #     +---+---+     +-----------+-----------+
  #     | 0 | 1 |     | @top,@lft | @top,@rgt |
  #     +---+---+     +-----------+-----------+
  #     | 3 | 2 |     | @bot,@lft | @bot,@rgt |
  #     +---+---+     +-----------+-----------+
  #

  def initialize *args
    @torus, @top, @bottom, @left, @right  args
    @names   [@top, @left], [@top, @right], [@bottom, @right],
[@bottom, @left] ]
  end

  def [] n
    @torus[ *@names[n%4]  ]
  end
  def [] , val
    @torus[ *@names[n%4] ]  al
  end

  def each
    4.times do
      | idx |
      yield self[idx]
    end
  end

  def recalc
    if any?{|v| v ICE} then
      4.times do
        | idx |
        self[ idx ]  CE if self[ idx ] VAPOR
      end
    else
      rotate( rand(2) )
    end
  end

  def rotate dir
    x  elf[0]
    3.times do
      | n |
      self[ n + 2*dir*n ]  elf[ n + 1 + dir*2*n.succ ]
    end # 3.times do
    self[ 3 + 2 * dir ]  
  end # def rotate dir

end # class Neighborhood
650/151 > cat ppm.rb
# vim: sw sts nu twexpandtab nowrap:


class Formatter

  @@default   ICE "255/255/255",
                VAPOR "255/0/255",
                VACUUM "0/0/0"
  }

  def initialize colors
    @colors  }
    colors.each do
      | element, color |
      color || @default[element]
      @colors[ element ]   " << color.gsub("/", " ") << " "
    end # colors.each do
  end # def initialize colors

  def to_file( source, file, comment  il )
    comment || ile
    File.open( "#{file}.ppm", "w" ) do
      | f |
      f.puts "P3 #{source.columns} #{source.lines} 255"
      f.puts "#"
      f.puts "# #{comment}"
      f.puts "#"
      source.each_line{
        |line|
        count  
        line.each do
          | cell |
          s  colors[cell]
          if count + s.size > 70 then
            f.puts
            count  
          end
          count + .size
          f.print s
        end
        f.puts unless count.zero?
      }
    end
  end

end
651/152 > cat run.rb
# vim: sw sts nu twexpandtab:
#
require 'fileutils'
require 'torus'

def usage msg  il
  $stderr.puts msg if msg
  $stderr.puts <<-EOS
  usage:
  #{$0} [options] height width vapor_probability

  options and their defaults
  -s|--start <height>/2@<width>/2      where to put the initial freezer
                                       please use Smalltalk syntax here
  -n|--name   run-<height>-<width>     name of the output file
  -v|--vapor  255/0/255                rgb value for PPM
              O                        use strings for ASCII
  -0|--vacuum 0/0/0                    idem
              <space>
  -i|--ice    255/255/255              idem
              *
  -f|--format ppm                      ppm or ascii are supported
                                       write your own plugins ;)

  have fun
  EOS
  exit -1
end

@start  name  il
@vapor  il
@vacuum  il
@ice     il
@format  ppm"
options   /^-f|^--format/ :format,
            /^-s|^--start/  :start,
            /^-n|^--name/   :name,
            /^-v|^--vapor/  :vapor,
            /^-0|^--vacuum/ :vacuum,
            /^-i|^--ice/    :ice }
loop do
  break if ARGV.empty?
  break if ARGV.first "--"
  break unless /^-/  ARGV.first
  illegal_option  rue
  options.each do
    | opt_reg, opt_sym |
    if opt_reg  ARGV.first then
      usage "Missing argument for option #{ARGV}" if ARGV.length < 2
      instance_variable_set( "@#{opt_sym}", ARGV[1] )
      ARGV.slice!( 0, 2 )
      illegal_option  alse
    end
  end
  usage ARGV.first if illegal_option
end
usage ARGV.join(", ") unless ARGV.size 3

require @format rescue usage

begin
  mkdir( "output" ) unless File.directory?( "output" )
rescue
  $stderr.puts 'Cannot create output directory "output"'
  usage
end

t  orus( *(ARGV << @start) )
t.name  name || "run-#{ARGV[0..1].join("-")}"
t.formatter  ormatter.new( ICE @ice, VAPOR @vapor, VACUUM @vacuum )
t.start_sim

------art_22039_33231460.1173638741779
Content-Type: application/x-ruby; name="ppm.rb"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="ppm.rb"
X-Attachment-Id: f_ez5srj0f

IyB2aW06IHN3PTIgc3RzPTIgbnUgdHc9MCBleHBhbmR0YWIgbm93cmFwOgoKCmNsYXNzIEZvcm1h
dHRlcgoKICBAQGRlZmF1bHQgPSB7IElDRSA9PiAiMjU1LzI1NS8yNTUiLAogICAgICAgICAgICAg
ICAgVkFQT1IgPT4gIjI1NS8wLzI1NSIsCiAgICAgICAgICAgICAgICBWQUNVVU0gPT4gIjAvMC8w
IiAKICB9CgogIGRlZiBpbml0aWFsaXplIGNvbG9ycz17fQogICAgQGNvbG9ycyA9IHt9CiAgICBj
b2xvcnMuZWFjaCBkbwogICAgICB8IGVsZW1lbnQsIGNvbG9yIHwKICAgICAgY29sb3IgfHw9IEBA
ZGVmYXVsdFtlbGVtZW50XQogICAgICBAY29sb3JzWyBlbGVtZW50IF0gPSAiICIgPDwgY29sb3Iu
Z3N1YigiLyIsICIgIikgPDwgIiAiCiAgICBlbmQgIyBjb2xvcnMuZWFjaCBkbwogIGVuZCAjIGRl
ZiBpbml0aWFsaXplIGNvbG9ycz17fQoKICBkZWYgdG9fZmlsZSggc291cmNlLCBmaWxlLCBjb21t
ZW50ID0gbmlsICkKICAgIGNvbW1lbnQgfHw9IGZpbGUKICAgIEZpbGUub3BlbiggIiN7ZmlsZX0u
cHBtIiwgInciICkgZG8KICAgICAgfCBmIHwKICAgICAgZi5wdXRzICJQMyAje3NvdXJjZS5jb2x1
bW5zfSAje3NvdXJjZS5saW5lc30gMjU1IgogICAgICBmLnB1dHMgIiMiCiAgICAgIGYucHV0cyAi
IyAje2NvbW1lbnR9IgogICAgICBmLnB1dHMgIiMiCiAgICAgIHNvdXJjZS5lYWNoX2xpbmV7CiAg
ICAgICAgfGxpbmV8CiAgICAgICAgY291bnQgPSAwCiAgICAgICAgbGluZS5lYWNoIGRvCiAgICAg
ICAgICB8IGNlbGwgfAogICAgICAgICAgcyA9IEBjb2xvcnNbY2VsbF0KICAgICAgICAgIGlmIGNv
dW50ICsgcy5zaXplID4gNzAgdGhlbgogICAgICAgICAgICBmLnB1dHMgCiAgICAgICAgICAgIGNv
dW50ID0gMAogICAgICAgICAgZW5kCiAgICAgICAgICBjb3VudCArPSBzLnNpemUKICAgICAgICAg
IGYucHJpbnQgcwogICAgICAgIGVuZAogICAgICAgIGYucHV0cyB1bmxlc3MgY291bnQuemVybz8K
ICAgICAgfQogICAgZW5kCiAgZW5kCiAgCmVuZAo------art_22039_33231460.1173638741779
Content-Type: application/x-ruby; name="run.rb"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="run.rb"
X-Attachment-Id: f_ez5srv9r

IyB2aW06IHN3PTIgc3RzPTIgbnUgdHc9MCBleHBhbmR0YWI6DQojDQpyZXF1aXJlICdmaWxldXRp
bHMnDQpyZXF1aXJlICd0b3J1cycNCg0KZGVmIHVzYWdlIG1zZyA9IG5pbA0KICAkc3RkZXJyLnB1
dHMgbXNnIGlmIG1zZw0KICAkc3RkZXJyLnB1dHMgPDwtRU9TDQogIHVzYWdlOg0KICAjeyQwfSBb
b3B0aW9uc10gaGVpZ2h0IHdpZHRoIHZhcG9yX3Byb2JhYmlsaXR5DQoNCiAgb3B0aW9ucyBhbmQg
dGhlaXIgZGVmYXVsdHMNCiAgLXN8LS1zdGFydCA8aGVpZ2h0Pi8yQDx3aWR0aD4vMiAgICAgIHdo
ZXJlIHRvIHB1dCB0aGUgaW5pdGlhbCBmcmVlemVyDQogICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICBwbGVhc2UgdXNlIFNtYWxsdGFsayBzeW50YXggaGVyZQ0KICAtbnwtLW5h
bWUgICBydW4tPGhlaWdodD4tPHdpZHRoPiAgICAgbmFtZSBvZiB0aGUgb3V0cHV0IGZpbGUNCiAg
LXZ8LS12YXBvciAgMjU1LzAvMjU1ICAgICAgICAgICAgICAgIHJnYiB2YWx1ZSBmb3IgUFBNDQog
ICAgICAgICAgICAgIE8gICAgICAgICAgICAgICAgICAgICAgICB1c2Ugc3RyaW5ncyBmb3IgQVND
SUkNCiAgLTB8LS12YWN1dW0gMC8wLzAgICAgICAgICAgICAgICAgICAgIGlkZW0NCiAgICAgICAg
ICAgICAgPHNwYWNlPg0KICAtaXwtLWljZSAgICAyNTUvMjU1LzI1NSAgICAgICAgICAgICAgaWRl
bQ0KICAgICAgICAgICAgICAqDQogIC1mfC0tZm9ybWF0IHBwbSAgICAgICAgICAgICAgICAgICAg
ICBwcG0gb3IgYXNjaWkgYXJlIHN1cHBvcnRlZA0KICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgd3JpdGUgeW91ciBvd24gcGx1Z2lucyA7KQ0KDQogIGhhdmUgZnVuDQogIEVP
Uw0KICBleGl0IC0xDQplbmQNCg0KQHN0YXJ0ID0gQG5hbWUgPSBuaWwNCkB2YXBvciA9IG5pbA0K
QHZhY3V1bSA9IG5pbA0KQGljZSAgICA9IG5pbA0KQGZvcm1hdCA9ICJwcG0iIA0Kb3B0aW9ucyA9
IHsgL14tZnxeLS1mb3JtYXQvID0+IDpmb3JtYXQsDQogICAgICAgICAgICAvXi1zfF4tLXN0YXJ0
LyAgPT4gOnN0YXJ0LA0KICAgICAgICAgICAgL14tbnxeLS1uYW1lLyAgID0+IDpuYW1lLA0KICAg
ICAgICAgICAgL14tdnxeLS12YXBvci8gID0+IDp2YXBvciwNCiAgICAgICAgICAgIC9eLTB8Xi0t
dmFjdXVtLyA9PiA6dmFjdXVtLA0KICAgICAgICAgICAgL14taXxeLS1pY2UvICAgID0+IDppY2Ug
fQ0KbG9vcCBkbw0KICBicmVhayBpZiBBUkdWLmVtcHR5Pw0KICBicmVhayBpZiBBUkdWLmZpcnN0
ID09ICItLSINCiAgYnJlYWsgdW5sZXNzIC9eLS8gPT09IEFSR1YuZmlyc3QNCiAgaWxsZWdhbF9v
cHRpb24gPSB0cnVlDQogIG9wdGlvbnMuZWFjaCBkbw0KICAgIHwgb3B0X3JlZywgb3B0X3N5bSB8
DQogICAgaWYgb3B0X3JlZyA9PT0gQVJHVi5maXJzdCB0aGVuDQogICAgICB1c2FnZSAiTWlzc2lu
ZyBhcmd1bWVudCBmb3Igb3B0aW9uICN7QVJHVn0iIGlmIEFSR1YubGVuZ3RoIDwgMg0KICAgICAg
aW5zdGFuY2VfdmFyaWFibGVfc2V0KCAiQCN7b3B0X3N5bX0iLCBBUkdWWzFdICkNCiAgICAgIEFS
R1Yuc2xpY2UhKCAwLCAyICkNCiAgICAgIGlsbGVnYWxfb3B0aW9uID0gZmFsc2UNCiAgICBlbmQN
CiAgZW5kDQogIHVzYWdlIEFSR1YuZmlyc3QgaWYgaWxsZWdhbF9vcHRpb24gDQplbmQNCnVzYWdl
IEFSR1Yuam9pbigiLCAiKSB1bmxlc3MgQVJHVi5zaXplID09IDMNCg0KcmVxdWlyZSBAZm9ybWF0
IHJlc2N1ZSB1c2FnZQ0KDQpiZWdpbg0KICBta2RpciggIm91dHB1dCIgKSB1bmxlc3MgRmlsZS5k
aXJlY3Rvcnk/KCAib3V0cHV0IiApIA0KcmVzY3VlIA0KICAkc3RkZXJyLnB1dHMgJ0Nhbm5vdCBj
cmVhdGUgb3V0cHV0IGRpcmVjdG9yeSAib3V0cHV0IicNCiAgdXNhZ2UNCmVuZA0KDQp0ID0gVG9y
dXMoICooQVJHViA8PCBAc3RhcnQpICkNCnQubmFtZSA9IEBuYW1lIHx8ICJydW4tI3tBUkdWWzAu
LjFdLmpvaW4oIi0iKX0iDQp0LmZvcm1hdHRlciA9IEZvcm1hdHRlci5uZXcoIElDRSA9PiBAaWNl
LCBWQVBPUiA9PiBAdmFwb3IsIFZBQ1VVTSA9PiBAdmFjdXVtICkNCnQuc3RhcnRfc2ltDQo------art_22039_33231460.1173638741779
Content-Type: application/x-ruby; name="torus.rb"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="torus.rb"
X-Attachment-Id: f_ez5ss9qn

IyB2aW06IHN3PTIgc3RzPTIgbnUgdHc9MCBleHBhbmR0YWIgbm93cmFwOg0KIw0KIw0KDQpJQ0Ug
PSBDbGFzcy5uZXcNClZBUE9SID0gQ2xhc3MubmV3DQpWQUNVVU0gPSBDbGFzcy5uZXcNCg0KDQoj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMNCiMNCiMgYSBzbWFsbCByZWZlcmVuY2UgdG8gUHl0aG9uIDspDQojDQojIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCmRl
ZiBUb3J1cyggcm93cywgY29scywgdmFwb3JzLCBzdGFydCA9IG5pbCApDQogIFRvcnVzXy5uZXco
IHJvd3MudG9faSwgY29scy50b19pLCB2YXBvcnMudG9fZiwgc3RhcnQgKQ0KZW5kDQoNCmNsYXNz
IFRvcnVzXw0KDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjDQogICMgICAgVG9ydXNfDQogICMNCiAgIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQog
IGF0dHJfcmVhZGVyIDpsaW5lcywgOmNvbHVtbnMNCiAgYXR0cl9yZWFkZXIgOmdlbmVyYXRpb24N
CiAgYXR0cl9hY2Nlc3NvciA6Zm9ybWF0dGVyLCA6bmFtZQ0KICBkZWYgaW5pdGlhbGl6ZSByb3dz
LCBjb2xzLCB2YXBvcnMsIHN0YXJ0DQogICAgQGxpbmVzID0gcm93cw0KICAgIEBjb2x1bW5zID0g
Y29scw0KICAgIEB2YXBvcnMgPSB2YXBvcnMNCiAgICBAZ2VuZXJhdGlvbiA9IDANCiAgICBpZiBz
dGFydCB0aGVuDQogICAgICBAc3RhcnQgPSBzdGFydC5zcGxpdCgiQCIpLm1hcHt8ZXwgZS50b19p
fQ0KICAgIGVsc2UNCiAgICAgIEBzdGFydCB8fD0gWyByb3dzLzIsIGNvbHMgLzIgXQ0KICAgIGVu
ZA0KICAgIEBuaG9vZHMgPSBbXSAgIyB3ZSB3aWxsIHN0b3JlIG5laWdoYm9yaG9vZHMgaWRlbnRp
ZmllZCBieQ0KICAgICMgdGhlaXIgdXBwZXIgbGVmdCBjb3JuZXIgaW5kZXgsIG9kZCBpcyBmb3Ig
ZXZlbiBnZW5lcmF0aW9ucw0KICAgICMgYW5kIGV2ZW4gaXMgZm9yIG9kZCBnZW5lcmF0aW9ucywg
d2hpY2ggbWlnaHQgc2VlbSBvZGQuDQogICAgcmVzZXRfdmFsdWVzDQogICAgc2V0X3ZhcG9ycw0K
ICBlbmQNCg0KICBkZWYgW10gbGluZSwgY29sPW5pbA0KICAgIHJldHVybiBAdmFsdWVzW2xpbmVd
IHVubGVzcyBjb2wNCiAgICBAdmFsdWVzW2xpbmVdW2NvbF0NCiAgZW5kICMgZGVmIFtdKGxpbmUs
IGNvbD1uaWwpDQogIGRlZiBbXT0gbGluZSwgY29sLCB2YWwNCiAgICBAdmFsdWVzW2xpbmVdW2Nv
bF0gPSB2YWwNCiAgZW5kDQoNCiAgZGVmIGVhY2hfbGluZQ0KICAgIEB2YWx1ZXMuZWFjaHsgfGxp
bmV8IHlpZWxkIGxpbmUgfQ0KICBlbmQNCg0KICBkZWYgZWFjaF9uYmgNCiAgICByID0gYyA9IEBn
ZW5lcmF0aW9uICUgMg0KICAgIGxvb3AgZG8NCiAgICAgIHlpZWxkIEBuaG9vZHNbIHIgKiBAbGlu
ZXMgKyBjIF0gfHw9IA0KICAgICAgICAgIE5laWdoYm9yaG9vZC5uZXcoIHNlbGYsIHIsIHIuc3Vj
YyAlIEBsaW5lcywgYywgYy5zdWNjICUgQGNvbHVtbnMgKQ0KICAgICAgYyArPSAyDQogICAgICBy
ICs9IDIgdW5sZXNzIGMgPCBAY29sdW1ucw0KICAgICAgcmV0dXJuIHVubGVzcyByIDwgQGxpbmVz
DQogICAgICBjICU9IEBjb2x1bW5zDQogICAgICByICU9IEBsaW5lcw0KICAgIGVuZA0KICBlbmQN
Cg0KICBkZWYgc3RhcnRfc2ltDQogICAgdW50aWwgbm9fbW9yZV92YXBvcj8gZG8NCiAgICAgIHRp
Y2sNCiAgICAgIHdyaXRlDQogICAgZW5kDQogIGVuZCAjIGRlZiBzdGFydF9zaW0NCg0KICBkZWYg
dGljaw0KICAgIHB1dHMgIlNpbXVsYXRpb24gI3tAbmFtZX0gZ2VuZXJhdGlvbiAje0BnZW5lcmF0
aW9ufToiDQogICAgQGdlbmVyYXRpb24gKz0gMQ0KICAgIGVhY2hfbmJoIGRvDQogICAgICB8IG5i
aCB8DQogICAgICBuYmgucmVjYWxjDQogICAgZW5kIA0KICBlbmQNCg0KICBwcml2YXRlDQoNCiAg
ZGVmIG5vX21vcmVfdmFwb3I/DQogICAgISBAdmFsdWVzLmFueT97IHxsaW5lfA0KICAgICAgbGlu
ZS5hbnk/eyB8dnwgdiA9PSBWQVBPUiB9DQogICAgfQ0KICBlbmQNCg0KICBkZWYgcmVzZXRfdmFs
dWVzDQogICAgQHZhbHVlcyA9IEFycmF5Lm5ldyhAbGluZXMpew0KICAgICAgQXJyYXkubmV3KEBj
b2x1bW5zKXsNCiAgICAgICAgVkFDVVVNDQogICAgICB9DQogICAgfQ0KICBlbmQNCiAgZGVmIHNl
dF92YXBvcnMNCiAgICB0b3RhbCA9IEBsaW5lcyAqIEBjb2x1bW5zDQogICAgdiA9ICggQHZhcG9y
cyAqICAodG90YWwtMSkgKS50b19pDQogICAgeCA9IFsqMC4udG90YWwtMl0NCiAgICBhdCA9IFtd
DQogICAgdi50aW1lcyBkbw0KICAgICAgYXQgPDwgeC5kZWxldGVfYXQoIHJhbmQoeC5zaXplKSAp
DQogICAgZW5kDQogICAgYXQuZWFjaCBkbw0KICAgICAgfCBpbmRleCB8DQogICAgICBAdmFsdWVz
W2luZGV4L0BsaW5lc11baW5kZXglQGxpbmVzXSA9IFZBUE9SDQogICAgZW5kDQogICAgQHZhbHVl
c1tAbGluZXMtMV1bQGNvbHVtbnMtMV0gPSBAdmFsdWVzW0BzdGFydC5maXJzdF1bQHN0YXJ0Lmxh
c3RdDQogICAgQHZhbHVlc1tAc3RhcnQuZmlyc3RdW0BzdGFydC5sYXN0XSA9IElDRQ0KICBlbmQg
IyBkZWYgc2V0X3ZhcG9ycw0KDQogIGRlZiB3cml0ZQ0KICAgIEBmb3JtYXR0ZXIudG9fZmlsZSBz
ZWxmLCAib3V0cHV0LyN7QG5hbWV9LiUwOGQiICUgQGdlbmVyYXRpb24NCiAgZW5kICMgZGVmIHdy
aXRlDQogIA0KZW5kICMgY2xhc3MgVG9ydXNfDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIw0KIyAgICBOZWlnaGJvcmhv
b2QgaXMgaW1wbGVtZW50aW5nIGEgMngyIHdpbmRvdyB0byBhbnkgb2JqZWN0DQojICAgIHRoYXQg
cmVzcG9uZHMgdG8gI1tdbixtIGFuZCAjW109bixtLHZhbHVlDQojICAgIEl0IGltcGxlbWVudHMg
dGhlIG9wZXJhdGlvbiBvZiByb3RhdGlvbi4NCiMNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KY2xhc3MgTmVpZ2hib3Job29k
IA0KICBpbmNsdWRlIEVudW1lcmFibGUNCg0KICAjIE5laWdoYm9yaG9vZCBnaXZlcyB1cyB0aGUg
Zm9sbG93aW5nIGluZGV4ZWQgdmlldyB0byB0aGUgdW5kZXJseWluZw0KICAjIHRvcnVzDQogICMg
ICAgICstLS0rLS0tKyAgICAgKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKw0KICAjICAgICB8IDAg
fCAxIHwgICAgIHwgQHRvcCxAbGZ0IHwgQHRvcCxAcmd0IHwNCiAgIyAgICAgKy0tLSstLS0rICAg
ICArLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0rDQogICMgICAgIHwgMyB8IDIgfCAgICAgfCBAYm90
LEBsZnQgfCBAYm90LEByZ3QgfA0KICAjICAgICArLS0tKy0tLSsgICAgICstLS0tLS0tLS0tLSst
LS0tLS0tLS0tLSsNCiAgIw0KDQogIGRlZiBpbml0aWFsaXplICphcmdzDQogICAgQHRvcnVzLCBA
dG9wLCBAYm90dG9tLCBAbGVmdCwgQHJpZ2h0ID0gKmFyZ3MNCiAgICBAbmFtZXMgPSBbIFtAdG9w
LCBAbGVmdF0sIFtAdG9wLCBAcmlnaHRdLCBbQGJvdHRvbSwgQHJpZ2h0XSwgW0Bib3R0b20sIEBs
ZWZ0XSBdDQogIGVuZA0KDQogIGRlZiBbXSBuDQogICAgQHRvcnVzWyAqQG5hbWVzW24lNF0gIF0N
CiAgZW5kDQogIGRlZiBbXT0gbiwgdmFsDQogICAgQHRvcnVzWyAqQG5hbWVzW24lNF0gXSA9IHZh
bA0KICBlbmQNCg0KICBkZWYgZWFjaA0KICAgIDQudGltZXMgZG8NCiAgICAgIHwgaWR4IHwNCiAg
ICAgIHlpZWxkIHNlbGZbaWR4XQ0KICAgIGVuZA0KICBlbmQNCg0KICBkZWYgcmVjYWxjDQogICAg
aWYgYW55P3t8dnwgdiA9PSBJQ0V9IHRoZW4NCiAgICAgIDQudGltZXMgZG8NCiAgICAgICAgfCBp
ZHggfA0KICAgICAgICBzZWxmWyBpZHggXSA9IElDRSBpZiBzZWxmWyBpZHggXSA9PSBWQVBPUg0K
ICAgICAgZW5kDQogICAgZWxzZQ0KICAgICAgcm90YXRlKCByYW5kKDIpICkNCiAgICBlbmQNCiAg
ZW5kDQoNCiAgZGVmIHJvdGF0ZSBkaXINCiAgICB4ID0gc2VsZlswXQ0KICAgIDMudGltZXMgZG8N
CiAgICAgIHwgbiB8DQogICAgICBzZWxmWyBuICsgMipkaXIqbiBdID0gc2VsZlsgbiArIDEgKyBk
aXIqMipuLnN1Y2MgXQ0KICAgIGVuZCAjIDMudGltZXMgZG8NCiAgICBzZWxmWyAzICsgMiAqIGRp
ciBdID0geA0KICBlbmQgIyBkZWYgcm90YXRlIGRpcg0KDQplbmQgIyBjbGFzcyBOZWlnaGJvcmhv
b2QNCg0K
------art_22039_33231460.1173638741779--