[Initial import of nukumi2 Christian Neukirchen **20041124200421] < > { adddir ./data adddir ./data/nukumi2 adddir ./data/nukumi2/templates adddir ./data/nukumi2/templates/atom addfile ./data/nukumi2/templates/atom/page addfile ./data/nukumi2/templates/atom/content-type adddir ./data/nukumi2/templates/html addfile ./data/nukumi2/templates/html/sidebar addfile ./data/nukumi2/templates/html/page addfile ./data/nukumi2/templates/html/entry addfile ./data/nukumi2/templates/html/subtopic addfile ./data/nukumi2/templates/html/content-type addfile ./data/nukumi2/templates/html/footer adddir ./data/nukumi2/templates/rss addfile ./data/nukumi2/templates/rss/page addfile ./data/nukumi2/templates/rss/content-type adddir ./lib adddir ./lib/nukumi2 addfile ./lib/nukumi2/entry.rb addfile ./lib/nukumi2/bricklet.rb addfile ./lib/nukumi2/filebackend.rb addfile ./lib/nukumi2/view.rb addfile ./lib/nukumi2/page.rb addfile ./lib/nukumi2/rewritelinks.rb addfile ./lib/nukumi2/plugin.rb addfile ./lib/nukumi2/default-registry.rb addfile ./lib/nukumi2/config-parser.rb adddir ./lib/nukumi2/plugins addfile ./lib/nukumi2/plugins/nicehr.rb addfile ./lib/nukumi2/plugins/blogroll.rb addfile ./lib/nukumi2/xhtmlwebrick.rb addfile ./lib/nukumi2.rb addfile ./render-static.rb addfile ./run-webrick.rb adddir ./sample addfile ./sample/config.rb adddir ./sample/data addfile ./sample/data/nukumi2.png addfile ./sample/data/style.css adddir ./sample/entries addfile ./sample/entries/nukumi addfile ./sample/entries/nukumi-0.5 addfile ./sample/entries/nukumi-2 addfile ./sample/entries/nukumi-2-spike addfile ./sample/entries/nukumi-2-update addfile ./sample/entries/nukumi-el addfile ./sample/entries/nukumi-pages addfile ./sample/entries/nukumi-progress addfile ./sample/entries/nukumi_2 adddir ./sample/graphics addfile ./sample/graphics/nukumi-el.png hunk ./data/nukumi2/templates/atom/content-type 1 +application/atom+xml hunk ./data/nukumi2/templates/atom/page 1 + + + ,,blog.config.title,,(path != "/"){: ,,title} + + + ,,blog.config.author + ,,blog.config.site + ,,blog.config.mail + + ,,blog.config.tagline + ,,blog.config.taguri-feed + Nukumi2 + +,,blog.config.copyright + ,,last_change.xmlschema + ,,:(config=blog.config),,entries{ + + ,,title + + ,,(config.author) + ,,(config.site) + ,,(config.mail) + + + ,,(config.taguri)-,,anchor + ,,change_time.xmlschema + ,,time.xmlschema + ,,time.xmlschema + + +,,!(RewriteLinks.new(to_html).relative_to(config.baseuri.first)) + + + } + hunk ./data/nukumi2/templates/html/content-type 1 +text/html; charset=utf-8 hunk ./data/nukumi2/templates/html/entry 1 +
+

,,title

+

,,time

+,,# If the entry is not valid, the page is fucked. :/ +,,!(RewriteLinks.new(to_html).relative_to(root)) +
+ hunk ./data/nukumi2/templates/html/footer 1 +
+ RSS 2.0 + Atom 0.3 + +
+ Check: + XHTML | + CSS | + 508 | + RSS | + Atom +
+
+ Powered by Nukumi2 ,,version. + + +
+
+ Copyright © 2004 Christian Neukirchen
+ Verbatim copying is permitted as long as this message is preserved. +
+
+ hunk ./data/nukumi2/templates/html/page 1 + + + + + ,,blog.config.title: ,,title + + + + + + + + + + + + ,,:(root=to_root),,# +
+

+ + ,,blog.config.title + +

+
+ ,,breadcumbs{ + →,,title + } +
+ + + +
+ ,,(blog.topictree.description(path)){ +
+ ,,to_s +
+ } + ,,(Nukumi2::View::Subtopic === view){ + ,,@subtopic + } + ,,entries{ + ,,@entry + } +
+ + +
+ + hunk ./data/nukumi2/templates/html/sidebar 1 +

Topics

+
+,,!topictree +
+ +,,(entries.size > 1){ +

Table of Contents

+ +} hunk ./data/nukumi2/templates/html/subtopic 1 +

Subtopics of ",,title"

+ +Please choose one of the following: + + hunk ./data/nukumi2/templates/rss/content-type 1 +text/xml hunk ./data/nukumi2/templates/rss/page 1 + + + + ,,blog.config.title,,(path != "/"){: ,,title} + ,,blog.config.baseuri + ,,blog.config.tagline + ,,blog.config.copyright + ,,blog.config.mail (,,blog.config.author) + ,,blog.config.mail (,,blog.config.author) + ,,last_change.rfc2822 + Nukumi2 ,,version + http://blogs.law.harvard.edu/tech/rss + 240 + +,,:(config=blog.config;root=to_root),,entries{ + + ,,title + ,,(config.baseuri),,(permalink).html + ,,(config.taguri)-,,anchor + ,,(RewriteLinks.new(to_html).relative_to(config.baseuri.first)) + ,,time.rfc2822 + ,,(config.mail) (,,(config.author)) + +} + + hunk ./lib/nukumi2/bricklet.rb 1 +module Nukumi2 + class Bricklet < WEBrick::HTTPServlet::AbstractServlet + def initialize(blog) + @blog = blog + end + + def get_instance(config) + self + end + + def do_GET(req, res) + begin + time = Time.now + page = @blog.fetch(req.path) + res.body = page.render + res['Content-Type'] = page.content_type + res.body << "Took #{Time.now-time}s" + rescue Nukumi2::Blog::NotFound + raise WEBrick::HTTPStatus::NotFound, $!.message || "Page not found." + end + end + end +end hunk ./lib/nukumi2/config-parser.rb 1 +require 'pp' + +class ConfigParser + class Blog + attr_inject :registry + + def topics(&block) + @topics = [] + @topictree = Topic.new(self, "") + @topictree.instance_eval &block + + @topics.each { |path, object| + p [path, object.title] + } + end + + def register(&block) + @registry.define! &block + end + + def self.attr_set(a) + define_method(a) { |*arg| + if arg.size == 1 + instance_variable_set "@#{a}", arg.first + end + instance_variable_get "@#{a}" + } + end + + attr_reader :topictree + + def [](key) + instance_variable_get "@#{key}" + end + + def method_missing(name, *value) + if value.size == 1 + instance_variable_set "@#{name}", value + else + instance_variable_get "@#{name}" + end + end + + def define(path, obj) + @topics << [path, obj] + end + + def get_topics + @topics + end + end + + class TopicContext + def initialize(parent) + @parent = parent + end + + def method_missing(name, &block) + t = @parent.topics[name.to_s] = Topic.new(@parent, name.to_s) + t.instance_eval &block + end + end + + + class Topic + def initialize(parent, name) + @parent = parent + @topic = ::ConfigParser::TopicContext.new(self) + @topics = {} + @name = name + + if @name.empty? + @parent.define "/", self + else + @parent.define(@name, self) + end + end + + attr_reader :topics + + def register + end + + def define(name, obj) + @parent.define(@name + "/" + name, obj) + end + + def on_definition(&block) + @on_def = block + end + + def self.attr_set(a) + define_method(a) { |*arg| + if arg.size == 1 + instance_variable_set "@#{a}", arg.first + end + instance_variable_get "@#{a}" + } + end + + attr_set :title + attr_set :description + attr_set :view + attr_set :hidden + attr_set :save + + def any(&block) + t = Topic.new(self, "*") + t.instance_eval &block + end + + def all(&block) + t = Topic.new(self, "**") + t.instance_eval &block + end + + attr_reader :topic, :topics + end + + attr_inject :blogconfig + + def blog(&block) + @blogconfig.instance_eval &block + @blogconfig + end + + def initialize(file) + @file = file + end + + def load + self.instance_eval File.read(@file), @file + end +end + + + + hunk ./lib/nukumi2/default-registry.rb 1 +require 'needle' +# require 'needle/extras' + +Nukumi2::DefaultRegistry = Needle::Registry.new { |r| + r.require 'needle/extras/multicast', 'Needle::Extras::Multicast' + + r.define.page(:model => :multiton) { |c, p, view, format| + Nukumi2::Page.new(view, format).inject_attributes(r) + } + + # Make this a :prototype if you want dynamic template loading. + # (no cache!) + r.define.engine(:model => :multiton) { |c, p, format| + Tangerine::XML.new(",,@page", Nukumi2::FormatTagLib.new(format)) + } + + r.define! { + blog { + Nukumi2::Blog.new.inject_attributes(this_container) + } + + backends { + Kernel.raise "No backends given! (Replace with a namespace)" + } + + all_backends { + this_container.multicast *backends.keys.map { |k| backends.get k } + } + + configparser { + begin + ConfigParser.new("config.rb").inject_attributes(this_container) + rescue + Kernel.abort "No config file found. #{$!.inspect}" + end + } + + blogconfig { + ConfigParser::Blog.new.inject_attributes(this_container) + } + + config { + configparser.load + } + + topictree { Topical::TopicTree.new } + + registry { this_container } + } +} + +PluginLoader.new(File.join(File.dirname(__FILE__), "plugins")).load! +PluginLoader.new("plugins").load! hunk ./lib/nukumi2/entry.rb 1 + +$: << '../clothesline' +$: << '../rubypants' +require 'clothesline' + +class Entry + DEFAULT_ENCODING = "BlueCloth RubyPants" + + attr_accessor :title + attr_accessor :time + attr_accessor :gmtime + attr_accessor :change_time + attr_accessor :encoding + + attr_accessor :content + attr_accessor :summary + + attr_reader :fields + attr_reader :categories + + def initialize(title="", content="", time=Time.now, change_time=nil) + self.title = title + self.time = time + self.change_time = change_time || self.time + + @fields = {} + @categories = [] + + self.encoding = DEFAULT_ENCODING + self.content = self.summary = content + + @cache = nil + end + + def to_html + @cache ||= ClothesLine.parse(encoding).new(content).to_html + @cache + end + + def summary_html + ClothesLine.parse(encoding).new(summary).to_html + end + + def anchor + # Ick. + time.dup.gmtime.strftime "x-%Y%m%d-%H%M%S" + end + + # This is used to create the filename. + def basename + title.downcase.strip.gsub(/[^a-z0-9]/, '-'). + squeeze('-').gsub(/^-*/, '').gsub(/-*$/, '') + end + + def permalink + time.strftime "/archive/%Y/%m/#{basename}" + end +end hunk ./lib/nukumi2/filebackend.rb 1 +require 'time' + +require 'nukumi2/entry' + +class FileBackend + class Parser + def self.parse(io) + entry = Entry.new + + fields = {} + + while line = io.gets + line.chomp! + break if line.empty? + + if line =~ /^(\w\S+?):\s*(.*)/ + field = $1.downcase + fields[field] = $2 + elsif field + fields[field] << " " << line.lstrip + end + end + + fields.each { |field, value| + case field + when "category" + entry.categories.concat value.split.map { |c| c.strip } + when "date" + entry.time = Time.parse value + when "subject" + entry.title = value + when "encoding" + if value == "OldCloth" + entry.encoding = value + else + # XXX IGNORE! + end + else + if entry.respond_to? field + "=" + entry.send field + "=", value + else + entry.fields[field] = value + end + end + } + + entry.content = io.read + + entry + end + end + + def initialize(dir) + @dir = File.expand_path dir + end + + def get + Dir[File.join(@dir, "**/*")].map { |file| + if File.file? file and File.readable? file + if file =~ /~$/ # Backup file? + nil + else + File.open(file) { |handle| + entry = Parser.parse handle + entry.change_time = handle.mtime + entry + } + end + end + }.compact.uniq + end +end hunk ./lib/nukumi2/page.rb 1 +require 'tangerine' +require 'nukumi2/rewritelinks' + +class Tangerine + def content_type + @taglib.resolve("content-type").strip + end +end + +module Nukumi2 + class Page + def initialize(view, format) + @view = view + @blog = view.blog + @path = view.path + @entries = view.entries + @format = format + end + + attr_reader :entries + attr_reader :blog + attr_reader :path + attr_reader :format + + attr_reader :view + attr_inject_method :engine + + def content_type + # 'text/html; charset=utf-8' + engine(format).content_type rescue 'text/plain' + end + + def render + engine(format).expand(self) + end + + # DONT TOUCH THIS. BRITTLE. + def to_root + if path.count('/') < 2 + '.' + else + (['..'] * (path.count('/') - 1)).join('/') + end + end + + def title + blog.topictree.name(path) || path + end + + def breadcumbs + a = [] + path.split('/').each { |e| + a << a.last.to_s + e + '/' + } + + a = ["/"] if a.empty? + + r = a.map { |path| + title = (blog.topictree.name(path) rescue path) || path.split('/').last + linkpath = path.gsub(/\/$/, '') + Struct.new(:link, :title, :to_root, :page).new( + linkpath, title, to_root, path) + } + + r + end + + def topictree + topics '/' + end + + def topics(root, depth=1) + return "" if blog.topictree.subtopics(root).empty? + + output = " 2 ? " class='compact'" : ''}>\n" + + blog.topictree.subtopics(root).sort_by { |t| + (blog.topictree.name(File.join(root, t)) || t) rescue t + }.each { |s| + sub = (root + '/' + s).squeeze('/') + output << "
" + output << (blog.topictree.name(sub + "/") || s) + output << "" + output << "
" + + unless blog.hidden.any? { |t| sub =~ Topical::TopicTree.path2regexp(t) } + output << "
" << topics(sub, depth+1) << "
" + end + } + + output << "\n" + output + end + + def last_change + unless view.entries.empty? + view.entries.map { |e| e.change_time }.max + else # XXX Empty page? + if view.respond_to? :subtopics + view.subtopics.map { |topic, name| + blog.topictree[topic] + }.flatten.map { |e| e.change_time }.max || Time.now + else + Time.now + end + end + end + + def version + Nukumi2::VERSION + end + end + + class FormatTagLib + def initialize(format) + @format = format + end + + def roots + ["templates", + File.join(File.dirname(__FILE__), "../../data/nukumi2/templates")] + end + + def resolve(tag) + roots.each { |root| + if File.readable? File.join(root, @format, tag) + return File.read(File.join(root, @format, tag)) + end + } + raise Blog::NotFound.new("Unknown format #{@format.inspect}") + end + end +end + +# ["templates", File.join(File.dirname(__FILE__), "../../data/nukumi2/templates") ] hunk ./lib/nukumi2/plugin.rb 1 +class PluginLoader + def initialize(path) + @path = File.expand_path path + end + + def load! + Dir[File.join(@path, "**", "*.rb")].each { |file| + require file if File.file? file + } + end +end hunk ./lib/nukumi2/plugins/blogroll.rb 1 +require 'yaml' + +class BlogRoll + class Blog + attr_reader :name, :title, :url + + def initialize(name, title, url) + if name.nil? || url.nil? + raise "Invalid blogroll entry, #{name}/#{title}/#{url}" + end + + @name, @title, @url = name, title||name, url + end + end + + def self.load(filename) + new YAML.load(File.read(filename)) + end + + def initialize(entries) + @entries = {} + entries.each { |cat, blogs| + @entries[cat] = blogs.map { |k, v| + Blog.new k, v['title'] || k, v['url'] + } + } + end + + def entries(category=nil) + (category ? @entries[category] : @entries.values.flatten).sort_by { |e| + e.name.downcase + } + end +end + + +class Nukumi2::Page + attr_inject :blogroll + attr_reader :blogroll +end + +# By default, no blogroll. +Nukumi2::DefaultRegistry.define.blogroll { nil } hunk ./lib/nukumi2/plugins/nicehr.rb 1 +require 'rexml/document' + +class NiceHR + def initialize(html) + @doc = REXML::Document.new("
" + html + "
") + end + + def to_html + @doc.elements.each("*/hr") { |element| + element.name = "div" + element.attributes["class"] = "seperator" + element << REXML::Element.new("hr") + element << REXML::Text.new("* * *") + } + @doc.root[0..-1].to_s # Drop
+ end +end hunk ./lib/nukumi2/rewritelinks.rb 1 +class RewriteLinks +=begin + def initialize(html) + @doc = REXML::Document.new("
" + html + "
") + end + + def relative_to(url) + @doc.elements.each("//img") { |element| + if element.attributes["src"] !~ %r{\A\w+://} + element.attributes["src"] = url + "/" + element.attributes["src"] + end + } + @doc.elements.each("//a") { |element| + if element.attributes["href"] !~ %r{\A\w+://} + element.attributes["href"] = url + "/" + element.attributes["href"] + end + } + @doc.root[0..-1].to_s # Drop
+ end +=end + + def initialize(html) + @html = html + end + + def relative_to(url) + @html.gsub(/(<(img|a)\b[^>]*(src|href)=)(["'])(.*?)\4/) { + md = $~ + + if md[5] !~ %r{\A\w+://} && md[5][0] != ?/ # relative link? + md[1] + md[4] + url + "/" + md[5] + md[4] + else + md.to_s + end + } + end +end hunk ./lib/nukumi2/view.rb 1 +module Nukumi2 + module View + class Abstract + attr_reader :blog, :path + + def initialize(blog, path) + @blog = blog + @path = path + end + + def entries + [] + end + end + + class Empty < Abstract + end + + class Full < Abstract + def initialize(blog, path) + super + @entries = blog.topictree[path] + end + + def entries + @entries.sort_by { |e| e.time }.reverse + end + end + + class Single < Full + end + + class Last < Full + LAST = 15 + + def entries + super.first(LAST) + end + end + + class Subtopic < Empty + attr_reader :subtopics + def initialize(blog, path) + super + @subtopics = blog.topictree.subtopics(path).map { |sub| + subtopic = File.join(path, sub) + [subtopic, blog.topictree.name(subtopic) || sub] + }.sort + end + end + end +end hunk ./lib/nukumi2/xhtmlwebrick.rb 1 +# Various extensions and modifications to Webrick. + +# A nice, XHTML 1.1 valid error page +module WEBrick + class HTTPResponse + 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" + + 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_ + + + + + #{HTMLUtils::escape(@reason_phrase)} + + + +

#{self.status} #{HTMLUtils::escape(@reason_phrase)}

+
#{HTMLUtils::escape(ex.message)}
+
+ _end_of_html_ + + if backtrace && $DEBUG + @body << "backtrace of `#{HTMLUtils::escape(ex.class.to_s)}' " + @body << "#{HTMLUtils::escape(ex.message)}" + @body << "
"
+        ex.backtrace.each{|line| @body << "\t#{line}\n"}
+        @body << "
\n
" + end + + @body << <<-_end_of_html_ +
+ #{HTMLUtils::escape(@config[:ServerSoftware])} at + #{host}:#{port} +
+ + + _end_of_html_ + end + end +end hunk ./lib/nukumi2.rb 1 + +require 'needle/extras/attr-inject' # XXX + +class Class + # For parametrized services w/o ugly .call + def attr_inject_method(name) + attr_inject :registry + define_method(name) { |*args| + raise "No registry injected!" if @registry.nil? + @registry[name, *args] + } + end +end + + +require 'topical' +require 'yaml' +require 'ostruct' + +require 'nukumi2/view' +require 'nukumi2/page' +require 'nukumi2/filebackend' +require 'nukumi2/entry' + +require 'nukumi2/config-parser' +require 'nukumi2/plugin' + +require 'nukumi2/default-registry' + + +module Nukumi2 + +VERSION = "0.1" + +class Blog + attr_reader :categories + attr_reader :hidden + + attr_inject :all_backends + attr_inject :topictree + attr_inject :config + attr_inject_method :page + + attr_inject :config + attr_inject :topictree + + attr_reader :config + attr_accessor :topictree + + def initialize + end + + def get_entries +# @entries = @backends.keys.collect { |backend| +# @backends[backend].get +# }.flatten.uniq + + @entries = @all_backends.get.flatten.uniq + end + + def get_config + @categories = @config.get_topics +# @topictree = @config.topictree + end + + def get_categories + @publishable = [] + @hidden = [] + + @config.get_topics.each { |topic, options| + if options.title && topic !~ /\*/ + topictree.create(topic, options.title, options.description) + end + + if options.view + @publishable << [topic, View.const_get(options.view)] + end + + @hidden << topic if options.hidden == true + } + end + + def load! + get_config + get_categories + get_entries + insert_entries + end + + def reload! + topictree.clear! + load! + end + + def insert_entries + @entries.each { |entry| + topictree.create entry.permalink, entry.title + topictree.add entry.permalink, entry + + entry.categories.each { |category| + topictree.add "/category/**/" + category.downcase, entry + } + + if entry.fields["page"] + path = "/static/" + entry.fields["page"].gsub(/\/index$/, '') + + unless topictree.name(path) + topictree.create path, entry.title + end + + topictree.add path, entry + end + } + end + + def fetch(path) + format = "html" + + path = path.gsub(/\.(.*?)$/) { format = $1; '' } + + view = find_view(path).new(self, path) + page(view, format) + end + + def find_view(path) + path = path + "/" if path[-1] != ?/ + + # XXX monster :-) + # Assume the path with least '*' is the most fitting one... + view = @publishable.find_all { |(topic, view)| + path =~ Topical::TopicTree.path2regexp(topic, false) + }.min { |a, b| a.first.count('*') <=> b.first.count('*') } + + raise NotFound unless view + view[1] + end + + class NotFound < StandardError; end +end + + +end hunk ./render-static.rb 1 +$: << File.join(File.dirname(__FILE__), "lib") +$: << '/home/chris/projects/topical' +$: << '/home/chris/projects/clothesline' +$: << '/home/chris/projects/rubypants' + +require 'nukumi2' +require 'fileutils' + +# Preload configuration +Nukumi2::DefaultRegistry.config + +blog = Nukumi2::DefaultRegistry.blog +blog.load! + +output_dir = "blog" + +blog.categories.each { |topic, options| + if options.save + blog.topictree.each_path(topic, false) { |path| + options.save.to_a.each { |format| + if path == "/" + filepath = "index" + else + filepath = path[1..-2] + end + + filename = File.join(output_dir, filepath + "." + format) + + page = blog.fetch((path == "/" ? "/" : path.gsub(/\/$/, '')) + "." + format) + + if File.exist?(filename) && File.mtime(filename) > page.last_change + next + else + puts filename + + FileUtils.mkdir_p File.dirname(filename) + + File.open(filename, "w") { |file| + file.write page.render + } + end + } + } + end +} + +["data", "graphics"].each { |dir| + FileUtils.mkdir_p File.join(output_dir, dir) + Dir[File.join(dir, "**/*")].each { |f| + FileUtils.install f, File.join(output_dir, dir) + } +} hunk ./run-webrick.rb 1 +$: << File.join(File.dirname(__FILE__), "lib") +$: << '/home/chris/projects/topical' +$: << '/home/chris/projects/clothesline' +$: << '/home/chris/projects/rubypants' + +#set_trace_func lambda { |event, file, line, id, binding, klass| +# p event, file, line, id, binding, klass +# puts file, line if id == :inspect +#} + +require 'webrick' + +require 'nukumi2' +require 'nukumi2/bricklet' +require 'nukumi2/xhtmlwebrick' + +# Preload configuration +Nukumi2::DefaultRegistry.config + +blog = Nukumi2::DefaultRegistry.blog +blog.load! + +module WEBrick + class HTTPServer < ::WEBrick::GenericServer + def mount(dir, servlet, *options) +# @logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir)) + @mount_tab[dir] = [ servlet, options ] + end + end +end + +p + +s = WEBrick::HTTPServer.new(:Port => 2000) + +s.mount("/data", WEBrick::HTTPServlet::FileHandler, + File.expand_path("data"), {:FancyIndexing => true}) + +s.mount("/graphics", WEBrick::HTTPServlet::FileHandler, + File.expand_path("graphics"), {:FancyIndexing => true}) + +s.mount("/", Nukumi2::Bricklet.new(blog)) + +trap("INT"){ Thread.new{sleep 1; p "killed"; exit}; s.shutdown } + +trap("USR1") { blog.reload! } + +s.start hunk ./sample/config.rb 1 +blog { + title 'sample blog' + tagline 'sample blog -- the canonical example blog' + author 'J. Random Author' + mail 'jr@example.com' + css '/data/style.css' + site 'http://example.org/nukumi2/' + baseuri 'http://example.org/nukumi2/' + taguri 'tag:chneukirchen@gmail.com,2004-11:nukumi2-example-blog' + copyright \ + "Copyright © 2004 J. Random Author, jr@example.com\n" + + "Verbatim copying is permitted as long as this message is preserved." + + register { + namespace_define!(:backends) { + exampleblog { FileBackend.new("entries") } + } + +# blogroll { BlogRoll.load("blogroll.yaml") } + } + + topics { + title 'Front Page' + view 'Last' + save 'html' + + topic.static { + title 'Also on this site' + view 'Subtopic' + save 'html' + + all { view 'Full'; save 'html' } + + topic.about { title 'About' } + } + + topic.category { + title 'By Category' + view 'Subtopic' + save 'html' + + any { + all { + view 'Last' + save 'html' + } + } + + topic.documentation { + title 'Nukumi2 Documentation' + } + topic.nukumi { title 'Nukumi2 stuff' } + topic.ruby { hidden true; title 'hey' } + topic.emacs { hidden true; title 'hey' } + + } + + topic.archive { + title 'By Date' + view 'Subtopic' + save 'html' + + any { + view 'Subtopic' + save 'html' + + all { + view 'Last' + hidden true + } + + any { + view 'Full' + save 'html' + + any { + view 'Single' + hidden true + save 'html' + } + } + } + } + } +} + binary ./sample/data/nukumi2.png oldhex * newhex *89504e470d0a1a0a0000000d4948445200000062000000150806000000bd823b7700000006624b *474400ff00930021801b6a04000000097048597300000b1200000b1201d2dd7efc000000077449 *4d4507d40b1213180524aa2b630000098749444154789cedd979905dc57507e0afef7bb368b40d *124862b1a063168760033613f6c5020146d8a002392944125c60610c4a625249ca15b013db1053 *5e28d5906235c2801d0c84014c6c81cc22090bc1402802312001b7488240086d48339266e6ddce *1fefeaa19134205158a94a7caadebc3b7d96df397dfa9e3edd2ff81d6d17a5eed8825db13474e4 *69bb741e8cedda7d49e134f448e6ea736738215fbea56cf611fbfb7f992e44376e48ddf1b00f12 *4ef7c59146ba4ee6fbaa4e527586269d86b9373d12f7d8527ea7242275c62c75c62fa4ebe2d13b *03efb744e350e070c40f941eef144da62193bc29790741e62823dd96ba63dbe6e23beb8d68c74f *f5bb3575c5d69d84f951d3e5f80cfe3074e4777da074e1309be6b7d757d59ca4f054c9fdac0197 *6c2ebeb312d18f77b097371cbc93303f520a1d790a1df9b2d0916fd82e854cd1786ed21e8ecc9f *c379925ef537e3a2f4789cf09ef8cea0317af11f6896fcde4ec1fcdfa68abbd003aafe2acd8bfb *5aea6535b782cc442d1aa53a4b8be2716961bc292d8a9fd834981e89fba4f9f180d415ab1fc687 *34278e488fc5c9e9d1781084e9790dbd20f8f8fbeade18c7a61fc7111f0af7d63826dd184f4fb3 *e33e1f467f90ad5fc5d1a93b8e4f0fc7f6d415b7b960d3fc3832cd8b87a40762d396bcd0913fab *e632856582364d3e16a6e685c22f5143a6e6f39be433c13735395f7019a47971bce16ed7ea497b *b832757f88648c768ae11e30c223a93b9e528ebe51f77edb1b5dea8cbba76be2a53678c25ad7a4 *9b62f30ee3ae31c306f759e7a1745dfcf40eeb232d8cfba727e36c232cc073869b6f9caf6eb928 *d39c5851d1a9cd534699be4d633daeb1c6e19639341c953f0a9ae5580f0a8dd25495990832a352 *57ccb4f8bacc5108828bf5fa099edbcae1ee18f49ba4c95eb875506fddef21c92d9a7c59cddfa6 *3971be255696dc3d1b363a6393aa3f30e01ccc908cc480e4452dc6e0adad707f129bad31454d0a *33f37bb760df88e3f039fd2e4c5df1227b9a253806a7868e7c597a308ed7ee1c9995f897d091af *2be3a96206be8176c9b30acfa8f8acccf78cd783d90da4b182e4d368d2ec04dcb2a5afe1c47c00 *af0f1aac69535129ff6b9c273285b50da15d9da8e27c8472a44d9b6f6d09501a3c4293fbd55cbc *9503c7e56b71b5a447c5a1c61a29f342c9de3ddd16774b9df1747419f034fe5afd759dadc95926 *f862f8937cab248035a6abb90b676c853b335f8159a5ad23f56a57f80c0ed6ef8b694e1c61b459 *323f549fb89fa5b9715419cfc598a5f036a6088e0e87e75314ae10b4aafa6e9a1f776f80fdb742 *6149398b9fda81323e19c3506872f7a6c14ccdeaf2f9602dbe85110a4b14eed8a49816c693b632 *37e06cb4c92cdce6497399c5829568b7d1a7542cc6bbf884d57e8d2e9c8cd7f00fda1c6e2f33c2 *57f207c2b47ce39061d49c890a166d933fdacbe8c3fed61b21f30c82aa49c6f88e8a697805ab70 *aad1be9216c6293257e10deb9d1d3af28743475eef7a36ba5e618960374d1af310a6e6854a5929 *92d1da8c1dd2e792d2a2b89be0025078dd064f6ce265eaab07260a8e40a1e6bb7a5c29598e619a *cc4add71f420ab414bf9bdd236284ccd0bf5cc53b58b76cbb016cdd80fafcb9ca3dd616166fef7 *e1fcfc9552e783a8b5b4b97608fe30f537ba4566ac9a054882298299ea8be10cfc1d12fe46d5b5 *78d780b3c209f9e241711c97bf23f3947a324f188434e0dfcb39186594e1dbe1fb15327b97cfbf *0ec7e66f6f6264aa8d9251a7c26facd365a417d4fca874f6405c9ee6c4ca6692b5f2efef6f0b31 *2d8cc76324faf57b25fc71be1cffb999c8ee0a975ae3cfd33fc513d28db1653b02790f776088d3 *ed3ac7a827fb1d3d5e53f31b490f9a901970335eb2debd92370463051fc34bdef2ec1088f58358 *a1233d5a9632a8cab141b0abcc6e43399ce6c4616951fcba8af34a3bcf2beacdd126ca044b0769 *15ae0d27e7ab42479ef49a25959b4df217da9dd590ab58507e1f9116c4f183801f8fadaabe8656 *85a71bb53498578aacc5061c29f9b6c2a336989b3ae3a5e986b8cf500195369e2c9f4e49b7c791 *8370af8f63d4cc2ce37ad018eb2cb798b2fc261bd41b8b221c97bf29f86543b9e6ee21dfc86491 *64bdcc815abcb74facf3b6e4ed52669b5d5aea8e6d46f94715df565f0c1b64be118ecc076de299 *7e9bdf04aed1e7fe46cc27e66f09ce976c1454557c2f3d1e0f013de69581eda3c52d69511c97ba *6296ba63a6ea12c11414829bc2f1f5ce44f24c69fa657c52e68fb040bd5c1c8b1fd8e8a9d4191f *4ad7c43f4db3e3bea9738b2b91aab9ea773ec758edfb69761c03e9e6d8a4cf153808bd2a6e0ed3 *f35a989af7297497da035659d7b0d5a76b33bb5b75860d7ac7122c4545b27f637cb5659489c81c *0069416c490be281a93b9e9ebae3b9f8852697d0e894aa0a17a585f1faf4649c9ee6c5435277cc *aa0acf9513314acdcb0dc39b6885797671ade02f31518babd3fdf1b47062be3c2d8a57a9b84c70 *aae0797b988be12a3e87aae4e7def4b386ad36af95c7ba7d4db02a4ccbefc49de9a638de46e72a *4c55bf549b2c996c9d3ebc923ae31c154fa95aa1c56306dc21394732c33aa7a4ce38578f8849ea *d7073798e0f1066ec5af3055d01f4ecb5f6d8cafd56dac5a39491387ca43f87cbe2a75c727f171 *cd0ec5cfa9ef83a93bbe8ac3140e4b73638b66b7cb9c3d6452eb478693cb3b8d19da0c287c2dd3 *6295fa5d10c952eb1b9b77dd8953f39acc6578ba1c3ade04b7a527e22e2aaec40fd127334e663a *ce44155d822f8533f29e86b15e4bd4cbd270abedd7c0b8205f162ece7f8049aa8ec63771a77af7 *b31f2e5573878da6853fcb070c3713f760007be3029c887e996b8d7079989af735703796e52c69 *4a0fc5f7ae58c65a5dee21abf47bed7d268f7e3f2acbec6383c6fbca836ac5019aed8243b6d24d *fa242bf042f959acdeb93dafdf557a3d16d2c3b1d53033057b5aefba30297f695b7ea405713f2d *7e21d817145e5573850deed36277cdcec5de6a5609ba2c357fd06420dd185b6c700f2668f585f0 *e5fc8df78b3dfd731c678d7d0c98243908778599f97d903a63d0ec587da6612cfe0b77879979f7 *5676bae3183c27794b7072e8c85735788fc6b1063487c9f99befe7cb903e2e8813b5badc460f58 *658e71be833304ad92e5927bf4b9df4a4bc399f98aa1ec84a11843801eacd56df8643954485e32 *a04b937fd3eb552bbdb8650206d9b8218e9654c285f936dbdedf16a5ee385e9f221cbdf5af631f *39d6bc384693663d7ac3e4fcddedd1d9a14440fad7b89b31ae563159306e30d30ac9b1e1f0fcc5 *1db5fbff9d76381190ba62d5047ba938cf80a3548d5658ace63e6fbb673b0f66bfa3cde87f00ad *d88d280f5470d30000000049454e44ae426082 hunk ./sample/data/style.css 1 +body { + font-family: Verdana, sans-serif; + font-size: 10px; + width: 65em; + margin: 1em auto; +} + +h1 { + text-align: right; + font-size: 500%; + margin: 0px; +} + +h1 a { + text-decoration: none; + color: #000; +} + +#breadcumbs { + background-color: #eee; + padding: 0.3em; +} + +#sidebar { + width: 25em; + float: left; +} + +#sidebar h2 { + margin-top: 1em; + clear: both; +} + +#sidebar ul { + list-style-type: none; + padding-left: 0px; +} + +#topictree a, #breadcumbs a, #sidebar a { + text-decoration: none; +} + +#topictree a:hover, #breadcumbs a:hover, #sidebar a:hover { + text-decoration: underline; +} + +#topictree dd { + margin-left: 3ex; +} + +#topictree dl { + clear: left; +} + +#topictree dt { + clear: both; +} + +#topictree dl[compact] dt { + float: left; + clear: none; + margin-right: 0.5em; +} + +.content { + width: 40em; + float: left; +} + +.seperator { + text-align: center; +} + +.seperator hr { + display: none; +} + +.entry { + margin-bottom: 4em; +} + +.entry h3 { + background-color: #eee; + padding: 0.2em; +} + +.entry h4 { + text-align: right; + position: relative; + top: -1.45em; + margin-bottom: -1.4em; +} + +.entry h4 a { + color: black; + text-decoration: none; + font-size: 10px; +} + +#nukumi2logo { + float: right; +} + +.footer { + clear: both; + background-color: #eee; + padding: 0.5em; +} hunk ./sample/entries/nukumi 1 +Subject: Nukumi +Date: Fri, 28 May 2004 14:16:28 +0200 +Encoding: BlueCloth +Category: Nukumi + +During the last two days, I've been writing Nukumi, my new weblog +system. + +So far, "chris blogs" has been generated by a bunch of ruby scripts, +Makefiles and XSLT stylesheets. This was by no means bad; it was very +effective and just worked. But it also was very brainless. I had no +way to do "real" permalinks, and the archive support I added recently +was a kludge. + +Therefore, I have been dropping the Makefile stuff and replaced it +with some clever script. The pages are still generated with XSLT, +because it's the easiest way to get multiple output formats (so far, +XHTML, RSS and Atom) from a single source. + +However, the new system is much more flexible at this. While the only +script, dubbed `xml2entries.rb` as you may notice, just outputted the +last 15 entries (or all of them, if supplied the `--archive` +parameter), into `xsltproc`, the new one supports *multiple views* of +the same entry base. + +My configuration code so far is: + + # Extension Stylesheet Views + n.flavor "html", "xml2xhtml.xsl", :ALL + n.flavor "rss", "xml2rss.xsl", :front + n.flavor "atom", "xml2atom.xsl", :front + +First, we define several flavors (term stolen from Blosxom) for the +different output formats. + +The second part is more interesting, however: + + # Name Prefix Hashfunc + n.view :archive, "archive-", proc { |e,i| e.time.strftime("%Y-%m") } + n.view :daily, "entry-", proc { |e,i| + e.time.strftime("%Y-%m-%d-") + \ + e.header["Subject"].downcase. + gsub(/[^a-z]/, '_').squeeze('_') + } + n.view :front, "index", proc { |e,i| + i < FRONT_LENGTH ? "" : nil + } + +The Hashfunc maps every entry onto a string which they get grouped by. +The first entry just generates archives for each different month, that +is `2004-05`, `2004-04` etc. + +The second one generates a permalink file for each entry of the form +`2004-03-27-kurt_cobain_jokes`, providing some context to the person +coming from an external page. + +Finally, it generates the `index` page (inclusive feeds in RSS and Atom) +for all entries appearing before `FRONT_LENGTH`. + +All these views get generated in each defined flavor into a file which +has the flavor extension appended. + +Note that all this is very efficient: Only the files which are new +or would get changed (i.e. modification time of any entry in the file +is newer than the entry itself) get generated anew. + +Nukumi, which has its name from the japanese word for "warmth" (which +was missing to the Makefile approach... :-)), works already very nicely, +though I spend only about 5 hours coding it. I'll relase it when I'm +back from holidays. + +**I'll be away for the next week till Sunday, and not be able to blog during that period.** + +NP: Beatsteaks---Big Attack hunk ./sample/entries/nukumi-0.5 1 +Subject: Nukumi 0.5 released +Date: Sun, 8 Aug 2004 19:54:19 +0200 +Encoding: BlueCloth +Category: Nukumi + +After a long time without releases, I release Nukumi 0.5 today. + +New features since the last release include: + +* New Formatters +* External Formatters +* Fixed URLs +* Hiding pages +* Multiple keys +* Support for Categories +* Support for Actions +* Emacs support +* Improved feeds + +See the `README` for more information. + +Download: [nukumi-0.5-patch-57.tar.gz](/chris/data/nukumi-0.5-patch-57.tar.gz) + +NP: Neil Young & Pearl Jam---I Shall Be Released hunk ./sample/entries/nukumi-2 1 +Subject: Nukumi2 Roadmap +Date: Mon, 18 Oct 2004 18:12:15 +0200 +Encoding: BlueCloth +Category: Nukumi Ruby + +In the last few weeks, I have been writing some Ruby libraries that +will ultimately empower Nukumi2, my next-generation blogware. In particular, +these, and their current state, are: + +* bungee: The application container that will hold Nukumi2 (and other + software, I hope). It will allow to use Nukumi2 using CGI or as a + Webrick servlet, but can also do static page generation. bungee is + currently early beta, but the design works. + +* topical: A dynamic and flexible categorization framework. I only + started that yesterday, but I can tell it works. :-) + +* tangerine: Nukumi2 won't make use of XSLT (at least, not by + default). tangerine will be used to define the page templates. It + already works really nicely, but hasn't been used a lot yet. + +* dana: Later versions of Nukumi2 will use possibly dana, a + pre-alpha, so-far proof-of-concept object database, mainly for + caching purposes. + +These are other Ruby libraries, not written by me, that I am likely to +use: + +* [needle](http://needle.rubyforge.org) is a rubyish + dependency-injection framework. I will almost surely want to use it + (at least 33% of the Nukumi1 code would have been superfluous if I + had known about dependency-injection back then...). + +* [WEBrick](http://www.webrick.org): This Ruby-based webserver will be + the preferred way to access Nukumi2, however, CGI and static pages + will be supported too. + +* [BlueCloth](http://bluecloth.rubyforge.org): BlueCloth has been + proven to be very useful and will continue to stay the default + markup language. Other Clothes will stay to be easy to add, though. + +Now, why do we (or I, at least) need Nukumi2 at all? + +* I'm really dissatisfied with the current code base. Every feature I + want to add---and that should be easy---is harder than the one + before. I don't understand the main processing loop anymore (shame + on me). Besides, I hope (nah, I'm sure...) that my coding qualities + have improved, and that refactoring won't cut it in *this* case. + +* There is much more Ruby blogware around now that inspires me. When I + started coding Nukumi, all I knew of was an early Hobix, and various + blosxom ports. Now, I have looked at recent Hobix versions, + Blogtari!, Rublog, etc. etc. Nukumi2 won't be without reason a new + major version. + +* There are various features that I'd like to have: dynamic page + generation (this will change a lot), better categorization + features... + +* It sounds like fun. :-) + +I'll start writing a spike this week; I estimate about 2 weeks for it. +(I shouldn't estimate in my blog entries, I know.) Then, I'll redo it +using test-driven development. I hope to get a 0.1 out this year. + +NP: Green Day---American Idiot +(American voters, it will depend on you whether I have to play that +song again on November 2nd.) hunk ./sample/entries/nukumi-2-spike 1 +Subject: Nukumi2 news +Date: Fri, 29 Oct 2004 18:33:25 +0200 +Encoding: BlueCloth +Category: Nukumi + +Ok, I've got a fairly good working spike of +[Nukumi2](2004/10/18-nukumi2-roadmap.html#x-20041018-161215). +However, I won't release any code as it's really ugly and I don't +anyone want to see it. (*lots* of globals and complicated regexen +around...) + +However, I'm now confident that I can start writing Nukumi2 the +*Right Way*. The design is correct, the navigation works. Static rendering +too. + +NP: Bob Dylan---Shooting Star hunk ./sample/entries/nukumi-2-update 1 +Subject: News on Nukumi2 +Date: Wed, 20 Oct 2004 21:28:37 +0200 +Encoding: BlueCloth +Category: Nukumi + +I've starting to spike Nukumi2 and doing quite good process. I'm now +sure that my categorization code (dubbed Topical, to be described +later) will work and provide the main navigation. Unfortunately, I +did a rather stupid thing defining the Topical "query" syntax that +turns out to end up in invalid URIs (WEBrick has problems with `//`). +Oh well, gotta change that and update all the unit tests... + +Also, my application container will need a rewrite of some parts; just +that kind of stuff that happens when you write libraries without +having an application in mind. ;-) + +NP: Velvet Revolver---Headspace hunk ./sample/entries/nukumi-el 1 +Subject: nukumi.el +Date: Sun, 20 Jun 2004 14:36:11 +0200 +Encoding: BlueCloth +Category: Nukumi Emacs + +I finished `nukumi.el` today, which includes a major mode for +writing nukumi blog entries. It works very nicely now as it + + * highlights header lines, + * displays leading and trailing space, + * generates new blog entries with partly filled fields + (that is, `Date`, `Encoding`, `Now-Playing`.) + * and calls nukumi on `C-c C-c`. + +See it in action: +![Screenshot of nukumi.el](graphics/nukumi-el.png) + +NP: Die toten Hosen---The Passenger hunk ./sample/entries/nukumi-pages 1 +Subject: Nukumi as a CMS +Date: Sat, 7 Aug 2004 16:30:29 +0200 +Encoding: BlueCloth +Category: Nukumi + +Using a small plugin, I have been able to make Nukumi generate static +pages with a fixed URL. This can be used to empower a whole site +using Nukumi, even the parts that don't relate to the blog. + +Therefore, I've also moved the more useful parts of my [personal +page](/chris/index_old.html) to Nukumi. + +There is now a intro page at to +provide a menu for accessing the subpages. + +NP: Johnny Cash---25 Minutes to Go hunk ./sample/entries/nukumi-progress 1 +Subject: Progress of Nukumi2 +Date: Sun, 7 Nov 2004 20:00:26 +0100 +Encoding: BlueCloth +Category: + +Nukumi2 is doing very well, I'm actually writing on code that will be +in the first public release 0.1 codename "godspeed". :-) I hope I'll +publish this release this month, but I can't promise it. + +Not mentioned new features include: + +* Clotheslines: You can now chain multiple clothes together, + respective any code that follows the StarCloth API (which is + `StarCloth.new(text).to_html`). My sample blog runs currently on + this clothesline: + + BlueCloth RubyPants NiceHR + + Which is essentially the same as: + + result = NiceHR.new(RubyPants.new( + BlueCloth.new(text).to_html).to_html).to_html + +* [RubyPants](/chris/blog/2004/11/03-rubypants.html) will be there, a + proper standalone release will appear this week. (John Gruber + already linked to it, thanks a lot ;-)) + +* NiceHR, a sample cloth that will wrap `
` into a `
` + for better taming with CSS. It's primarily an example on how to use REXML + for tasks that were done with XSLT in Nukumi1. + +NP: Bob Dylan---I Want You (At Budokan) hunk ./sample/entries/nukumi_2 1 +Subject: Nukumi reloaded +Date: Sun, 6 Jun 2004 15:53:31 +0200 +Encoding: BlueCloth +Category: Nukumi + +After being back from holidays (more about that soon), I did some more +hacking on Nukumi, and will be going to convert this blog to it, +probably this week (though I still have some quite important tests I +should learn for...). + +I have been object-orientifying big parts of Nukumi; it's very rubyish +now. I also put it under control of GNU Arch and really have to say +that `xtla` kicks ass. + +I also added a new layout, *mono*. It will probably be the default +layout for Nukumi (with a different image). Have fun. + +Pre-release code (only for developers): +. + +NP: Animals---House of the Rising Sun binary ./sample/graphics/nukumi-el.png oldhex * newhex *89504e470d0a1a0a0000000d494844520000019e000001f7080200000004e5aeca000000037342 *4954080808dbe14fe000002000494441547801edbd21bb24c991252aed2730506041c1010f083c *5040a0c18206030406082c105830e001418105820be7270c5820b040e00181010d163458d0a041 *c3060304040a0c6830404060edb6555b59db3177b7f0f0888ccc38f5dd2fbf0873b363c78ebb5b *7a66debcf5d3dffffef75f7cf1c54f56fdfbd92aa09ffcddcffe6e33d663b377e86e2736537e8b *c0f6ec2da41956ebb20bab1902ad62b6137b6cf6561d33b26caf7d65f60ed67662ad49f9e9fbf7 *efbffbeebb4e2e1bfaecb3cf52b7bffeedafa97daff16f7b015af14711967cc770de46f80a1c5a *d2a7f62d84b74991a64b8d5b38a4002d2309ab32bff8c52f5a12edb4a7adedc3bf7ff8d8247ff3 *9bdfbccdc1df7e923e7ef3f537925e9ae037dfbc5d847f29f482196df5efc356612cec49ef53dd *768b96ceb228b460a2b7e8dca291626ce0968a26a0c7e8b681585ad8b319fffa1f1f4f3fefffdf *f76987d1cef3d7bfbeb9edf7d159fb38a592efdb6fbffdd8da7e98512561673ae96b7ffecb9f13 *55774f7f8279fa9e4939bc198fa9ae992e1b3870273cbaba2fbffaf2b35fbebd1af8eaebaff422 *1360836d12e7301d0e9cbbba2a875557a4a03d4b9cfb7de6efff9fbf5fe2a327c41f9eada478ab *fffb0bed6b9eba9cda8a957c0caf7b6ff2dc3d4f07aeb6dddc522516102e13fbe39ffee839fce6 *d7bf492999713fb777fff99da0fdfa57bfd68b7ebacaa8e1ece776d013db658989bc0bb87526a9 *d067de34ffdb4ffef0c73f041859219f2c3ff8fce6bffe46e74868ffe95fffe47d3e9dda3e96f4 *e3be26462b95a7b6ce941d37f4c5973ffa90e7f3fff2b9e4faf2ff7c8919d3a10dc6cfde90e5df *e73f5cc891eac3870f6fe9befa513a75181ac56de823e0f2b6883cda694b2e94863eda990e8d66 *092106d809f1436fd7e5d61f0347f7c7768a51f68fe3875557ccef4f6dc33ee37b8ec7f776bd96 *bef6c7ffff8ff2ec2bb7dad7bccf8fdf6380bee6a1796a1b4fe4316be8eda9e9fb7f3291efdebd *9d71e49f1adfa6f6fb511b32e7e8efce5f76aef1873243960b39bbe9d0a7743f84cb901ad54157 *aa2cac9fffe79f2bb15fffe3c76757b1d8b50ca53e62343276e19f7bd1f8a72f3e85684679b410 *3ffaab7ff8953a7cf1bfbff8f9cf3fd2b390d2c53113baa0df1d434c3459c06da86cb7cf58b4f6 *2c7dd691694d50fff613f1d1d719b20002f31f4e6df2069ecba740bffafcfb95f183883cb525e2 *9e6292b66579f41825b7ad8b70a0fbe4f6fde128fcf32f3fedb0a6213a84592c7538917df7efdf *29b85dc86dc5470f596fb03f30f4ebd8de80f346f3b472bcc5aea5a399c3e0d7009eba53c45985 *fbc3aa834cb9e1d3a9edfb3e13def49098b756f303c937e7b4f78931f5f93ee75b5fd3d11f7c7e *746afb34fc0343df08796acbe7cd5b8f5943fe20e6cf569a192de9290fdfc9f247363b8b09a600 *da1082ab83a6fef8bcfae313991ddfd4c70e6efed4e67dc2a9cd1fd9fc112c3dca99f6be3abbb6 *539bb8f1d4e6d769e7fa8c53db0fa76ccd25cf4079526b70dfd3451fb1d8eb500191fee87d3e7d *8c607d4d2ef4bca67ef2a89fb8f3d4d65910870ef9539bbe7726e9f03c6596f494f7a3035af686 *dda770f749821de57c78ea999eda84a72c3e13c77cbc319cdad237cede70dc4b12fc50353dd3f9 *53dbe0e3d7639e93d20d79e852c9c10fab2e4f07563bb5c9c14abb0abec0fcd495ca3ed6d70456 *5a96bc2b2dbbc3703efecaee67ffe5b33fffdb9f3fcdc40fe812f3dd7f7ca7adedb7bffd6dfa7b *6d50c89bc1b7cfd461deb87b9eaecc2d956501e17da2495ff3473c4ff2e1dc52c5d478596e9725 *76d0ce95df6b7bffcbb7dfaf90b373a7cfe8ebc2fd3ef23426cf971f4f6d1ffef241df8cf828ba *3b0a0aadbffbf9df092d9eda3abbe8d0a1053ba1c5afdcf2eca4d6429ab61f585d9d5359873aa4 *7abe76754535ecd4d6ef338ab6ca67c317ad3eff87cfb5e316eba9bb9d3dfdafb18e0faba23e71 *e2b960ee2e50c8822a36a9b6bbe4b309b7aaab1522ad4d5e17b63076dad32fa8c8a9eda7f21bc0 *f635889d391687fff8f7521683ef804ba5dc81d708bd64f927d5de90a4673e45ae9b97dfd33f1b *3b49ae6cea071f88676c69a30254800a3c81023ffdddef7ef7043449910a50012ab04581b7c3dc *975f7eb92584be54800a50814b2bf0edbf7dfb9f2e4d90e4a80015a002530ab0b54dc9c6202a40 *05aead005bdbb5e787eca80015985280ad6d4a360651012a706d05d8daae3d3f644705a8c09402 *c9afbbf9af2e0ba6ff935b3e85bab5463b64faf86f5f79fde10f7e7540fa4396623f543f517dd4 *57dd6785c2a2a59eb7efd99f8b4eec34253fbf9db99ec6ef70e6d0ad14c84f6db2f7ecc7e498de *0628688a8f6e2163b8457fb5e886d1149d90742835b6126db26b3babb00a3e56ce11dc34971462 *17c5a2b49ca2f384dbd1f8139418f25c0ae4ad2dade1fcd576878ca9d462c4dad1d28aa59d0a50 *81e405692a8a1e19fabbcb8e157db70ebe1f0a19f5b64203f1fd7947b9a568081e2a925b094f89 *49d2ad552b9ab2f5d7c83f580e6525b9027e6a419218853e2dcb30d61c0461abceada4b4bfb602 *796bc3a5665bba25c7a68d9a6e4e45f6436141fb142d1a2dbbed0705d172c2260935a61599512f *529f1607b16b45adcda9a3de27b5845a14568d73ac3c61ac082d5860c5c7a2b4287f8b15618a8a *0f46d1725b05f2d6d6da7b7d99c292ed38cfe177004f1b0acce5d63a51a528df8090b3a2791cb4 *4814ea6c217ab1951532d96ad994d1d85a2158d15602f4a7024181bcb5cdc9e4f7e41cc2334669 *d5fed8727415159d1fc56a4e874a4547ab4afc175360c3c708f5ca8f7e129ec09710fdc15d3481 *665258ac1d5bea2a21c8d6d816f325ac36915995b1559190e9cce026aa74be8902d5539bae3979 *0caf26cce2f736b68fa0a65fc1e29cf605cc686e7dfc940986205ac898e284422a3e1a62e072ab *643c012f487fe55532567c5a5930162d123ba1553d23e29b682d10daa94050e0edefb5bdfc1f35 *f21d992be01915e00c3ee3ac3d9033ffa8d103c5676a2a40050e54e090f7da0ee43b05ad2f00a7 *42197409053883979886a722718bd6f6543342b254800a2c5080ad6d818884a00254e06a0ab0b5 *5d6d46c8870a5081050abcfdf2877c9ab000891054800a50012a4005a80015a002c729f0d3f7ef *df1f874e642a4005a8c04314787b41daff5578fddcfdc3870f2d7ebff8c52f5a43b453012a4005 *162af0edb7cd77cfdebd7be7137dfca255ebf786fa5d6f21634251012a4005162af0e93ba4d8c5 *5afd0ed3ffe17ffdc18cfff4dffea9e5b07508718eb3680929c361d28958536c2ee390121da8c0 *cd1558f0cb1fb6b17597fa367784b8828f2952e311d95761b2a3ad529238542055a0fa973fd260 *344eecd8899090d73a9d5cec47c3a2869687241db2a20315b8b3028b5b9b4a69e738b90d272c3f *e447f1c4975a7c179370f591c7001b66d446f1a2c3b05385e207869d06e745e8b8dd7921b2762a *b05681052f486d87cb06f67b1889ca68a71d582bf1800222b766b1be6046eb32c39681d953869a *1187d0e27b1f8e9a05ebea3873880a5081250aac39b5595be977b761f791925acdb112db57a488 *5074ebe7c2d1565de8490b15a002fb1558d3daf6f33004df59eaeda07880aaf0b4c35dc5b9ee73 *50c7ac13a02715b895020b5e90764e6aa137d55b15ce0166318bc14ee087106d40fb69235bac88 *162a40058e5360416bb376a01d416ecd128e2a726b3eb8f93d8eb949e5e6a90ebefb788b788674 *1dd55a0c0d4492b67cc4ee13591f6c5d188e2f199d3b6c394405a8c05605debe43aa7f783efd95 *5dfb9bf4cbbf6865cdcb77b1adec2febff92455d566d12bb8f029bbf68b5471a3b804c801c7178 *a99fdd26081743aec0a148956e54e0251558f03102b7f14bae0c1645059e5a8105efb53d75fd24 *4f05a8c04b2ab0e0d4165e901e7d88f3e9d6e64a912bef9aa5815b974b0a82d9d1228952a32790 *3aa4468df264d4621f86f8dbb44684454b1a188c21ca53b2794764b45472d1e7f51458706ab375 *16563fae54dc3028a8f874dc6ce1f67321ecd092221b930e254116323b9b6c317b910f2a3f2c5f *1cbcf25a51a82b90544c1fa52073d95b519af4507d2ae2d0e7e91458d0da16d6bc69ebee6f287d *e6e976ea872c1cc5ec68d174265a9abd351aec2de52da95df82c210a73a125252946f10c6836bf *2988f1b12739b4b472d17e070516bc204d65f2cb51161fae5a5dcd16ab0bd43cf536450e465bd0 *08e8878650f58c7da8393ed3d9d36def19dacef7468c4a951f0a18a230175afaeab546a7f56901 *d2fef20a1c756a93b5a83fa2a0ec105b9ade2843e1d65b52e96dab0826ee4f1f6249fb6e9865b8 *9f31a46229f299c83eb7ed31cae642cb31ddbc8072ad3f567288aa48117c3c600047b4097d1084 *963b2870c6a9ada3a3df361d373f647bb2bf0d70eb56f08fdb39153e5bb34fa8272214a35a3a8b *5d95af5454d15c717ced2d865bf5a964a7cfab2a70486bab2c531514b7c70397ef03535bc74141 *862bcf1a815cd4c331aa523ee257a28625541c4e4b5421439feb2b70486bb3b26dff782152a33a *e07e0b0a76d677073680e3fe140744b6e3898617a3fab5877282b34f9166179256a67746f2ad44 *62b7401f15942f0286a84ed2e150bf76e4b3499f61763abc9e020bbe43fad5d75f795d748dda5a *4cf78ff7d1d874bfa572db7692d1349707c4ec7e0b797c0fdb4258cb672e3b6e72c1498d8adfaa *0ba302484b672f4e00c15ca8584b7ff4c4b9f33e61ea6da82305a6a0e5e914a87f8774416b7b8a *ff87942bfee9163109530154a0deda16bc20ad3c5723c58aa5fe0c3f445b0835cc45072a40051e *aec082d6c6aef1f05924012a4005820247fd5e1b85a60254800a3c508105a7367c41baff1c876f *21efc7f42a07cefe3d6971db94cb434de3f0adc007ee01a67e4905969dda6457dbcf1594926681 *3dd78859f3f2cd68534753286b495b71faf4ae2020395081a75660c1a9ede8faa73b8e10930e32 *113e57d16989e6e8318a0adc4a81435a9b9d65fceb2c7f86f2671c95bb75eab1a8e0d0421634f1 *941fef3037a398c2603de70a78a8dd6e91245a2af8f4a102542028b0ec05a9ec49fdb104726bfd *c8766cc5121a01ce598aac6e8a2fd7dae030365836b512ac62882f0e18d522e9ebaa20d3870a50 *819602cb5a9bb612dbb492cf5ffbf4c3a6d30a3490a143ab5ab42b946fa6e8132ce2bcc97f0878 *445df5a4f4a4022fa9c0212f48cf544a7a93f51adff2361dc73611c62c9bc2e94c05a8c0090a3c *a0b50d8f3c4307af4bdac20c412ef61ff18a7c5226c3292c820f71e84005a8805760d90b52d9a2 *f68312dbeb3edbff1d4b7a2c6ab5008f633e86d0ea6be6e9fb51cb18d07c995885d4dec2f1b92c *50fc5b2451465aa80015282af0f45f8fc7dec44e519c7bba5181a753e045be1e5fd7dd0e4a12e2 *af1581cdaeae243da9c06b28b0e0bdb65fffe3af5f430b564105a8c0cb28b0ecbdb69751848550 *012af0020ab0b5bdc024b2042a4005a2026c6d5111de53012af0020ab0b5bdc024b2042a4005a2 *026c6d5111de53012af0020ab0b5bdc024b2042a4005a2026c6d5111de53012af0020ab0b5bdc0 *24b2042a4005a2026c6d5111de53012af0020ab0b5bdc024b2042a4005a2026c6d5111de53012a *f0020ab0b5bdc024b2042a4005a2026c6d5111de53012af0020ab0b5fd6812fff4af7f7aba497d *46ce4f2732093f9d026b5a9bec2efde9d75ff1e923e0e8d68dddf7973fd0d4770804363923f9ad *9654c0ad9cfb498fae680e7f2eaa5fa98da6aab6620f65d24a7a11fbd6da3709bbbcc635ad4dff *645bff0fb7499de210f66145ac8acf425dfa552c4c3451578b5bcbae6c27122d2cb308b58ae404 *4e5fbd22ff87b84d147b1acf74bf9f965d12ad696d9b18fb95545955159f4d042ee2fcaa75cdc9 *bb4a8d553873559c1cf514c53e8ae482bfb23b3d9dfa9c63956b9b47a3e07b75ec990a8d1e4a59 *a1a5ce16f9a84511fcb558ec167daca23014ea426269a5e8d6b728887130f27ad1d12764c7bafa *792d51985f4f2064c7091567347a4be080658a331a43ed08829c4d0d73c6d9410b4a34f431b641 *70e4dcaf4bc3830f56aa0af77319e74eed58295a42ed15860852b79cd4dab4aa20b42d3b2f99ae *2ad33af8843908ce2656589a21aaae8e057a040cef8f8abf56618f66412894422c43fc0e8e4faa *6ea861aa4fd0b09362eb10aa3a31cb69d280e3a5d3a4587b8a138ca80fe2a02545aea89aae169c *3b5f6c9a1d75464a2117e2546a47588952f1e5514b466475c051449bb39cd4da4cc13e4b9bf896 *9b4da75c983346a9b22d90ba1d9131d6cf198eeeb1acaa628ec3c2ec41a28aaac6b933cb95ba3a *b93a4315e4a08fa0a9452e3ac873aace45ed94ae23c2908faad1d141c18f6328f827b5b68e4c5b *87548eb05b02c850d3ad493bfec559ec20b486ceac2270f0f286753c5cd6ad725ecc8eb3335c99 *1d553be2cc457500f70f61edfb3197233ce063843d35d8bed28632843a681f06d894cc44ea5648 *cb3e2c3f384ce004c1e5362c6bb14cc0d6991f073e441e3a6815ea1684ea175844de3f7d7d1afb *47e70ad99fb782b0e6d466b3bba99d57a2828f6f22ad5ce893b69e8a3ac1c77010502df2d8f209 *6cb1f64aa51855a9c253127f4f5e59b5ca499d316328cd3b28b23d62ac5a2ab5b762bd7da80fd6 *2ee1adec5e37f5b15c88831624dc010cce5e528c1232de41622bd9918f5ad25c8a1990cddfd408 *345a297632ecc0768616fceff1efdebdeb24e0505d015cb2f5d8a33d3d37bbbe32e1a3057920fe *9df5fff0e1434bf9d088d69cda5ac968dfa440fd397013ec12e7f45c7065c24baabe26883fc75d *93e11558b1b55d61169e83031bd975e68973319c8b27fb1861580f1da80015a002a2c04d5b5b78 *5778e1524891c598da17e6bd0894567a42b127a47894a4f7592d872a7c6a6b0bcb315d9da9f150 *09b6824f303cf3e543915ed16dab385aa9aff7a0445b893dca7fa2fc3357cb42592abb7b61ba21 *d4a9adad3267159f6155873a5c9f61a5fcd7a8a252e9637deea3f3d52a5dd0da7cb7d66b7b0c43 *a9e79c4fe7c910b3635e5bee36843e623128efdf49ad6e1ad877431fb4e09e0c3e46cf72552c02 *ab381e1fb3a305f90c2dc807438cbc124b35ece084702c2d9469b716182ac55c29c35008466939 *3ed62cfb39d7b3fb32b1f68033c7102b4dd5c05c875a8efa84546ad32e6e1772eb67546f43a70f *3e2a99c731343f84026176f4e923a8bf916c5591c25a519eadf7c42ad082c8a94fa8345515d508 *3a23325a904fc592f21906a6d9b18a308369d4c25c752863729ace5e0acd3ea786e084d55bc409 *95cecdfb50e14d0ecb5a9b97c00b644a6da265ce73e195a840788edec951c23964ac546a3e1de7 *806c2b552e3a510bcb1f4e0756814b4eabd8cab9a3eaa6dae79c31fb9caac5ec439d1fbe12e6ca *c7a865ad0da12f6ed1dd5b5c1017a9e538b688ac96e14e78a032388343ce16e2ebc2da5b45ad6a *431effb1d943a55e162b76a86a4baec7da17bcd7b6bf80fa8ad1a529fef5104f2f44291aceeefe *8ab6226cadab527ec507796a945fd61e670e53b3ec89459e6af133d8e2dc8a457b8ba1cd4ebd0d *2178b0602eb4f81a657461f63abde3541d72d8e9b0e0d4a6136f8f2d42aa919f215b973667e883 *68c1191dd0e213850564b45b3e964e612b0cfd6a48a32c978c1afeb0ae34aa5f2c8e16f9a4b9ea *b5f76739b0b229b0a8347bab160b2f4699bf02d6a35a043af6a018e6428ba0a1cee2d6c9920e21 *b215ee67279d0b315a38e2a4e952ce6a9c209fa6d86a7cb2afc7fb59e9ccd056151eeeff2c75bd *92e6f5497fecec3c367b5da5733c5ff6ebf1c5e79073545e98e559ea7ad433f042a927a01e3b3b *8fcd3e21d7454216bc203db99257dd5daf5ad7c9cbe3a0748f9d9dc7663f48d2a3612ff131c2d1 *45129f0a5081bb29c0d676b71967bd54e0160ab0b5dd629a592415b89b026c6d779b71d64b056e *a1005bdb2da699455281bb29c0d676b71967bd54e0160ab0b5dd629a592415b89b026c6d779b71 *d64b056ea1005bdb2da699455281bb29c0d676b71967bd54e0160ab0b5dd629a592415b89b026c *6d779b71d64b056ea1005bdb2da699455281bb29c0d676b71967bd54e0160a5ca8b5e9dfe4dcaa *7a1a25c6d4de01dfeadf82da8fb31361a2f6562db45381e755e0d4d636b76927a2d2bf6f358133 *11f2f0a5b0aaf68717420254608f0227b536df23b6f68b74af4ed4bc0a6722f5c343ee5cfbc3c5 *2781872870de5fd9d58e36ec6bea605b31dc8a4686e0b72bba0535d16188e309073e02de6f1669 *153e0ab39bc598071fb995a458c870dd2019c4e9f0e9573acc4e072af010054e6a6db697fa4d41 *77aff8d8850ff4767f8d5128e5048e86f88d6d890293902ef049a30c564783cf9e4a87b5a374c8 *102d084b0b15b8b20227b536d92aa682df36419ab903c25c14ceca10c7faa35c749c71c897af79 *d1827cd0c790310586772c181e72152beda4e0101578ac0227b5362952778bed99c7963d9d5d9b *42a73ba7c8a1958433511aa28ab58696dbb1d9cd55ba9c1801a9c09c02277d8ce0770eeea23a75 *ed8cd21af044530711cfad389ace926af8a68cea1c6817ab28ba4df0c1907ea5fb95c78cb45081 *231438efd426ec279a9aed348bb58bce86c728b45470ac85a9b3ef68f55a30cac32a31efa3d38c *51c5e9c74ad112a030175a2ca45e789130dda8c0110adcf47f8f97dd6e5bd45f1f21f1cb6052a8 *9799cae72d84ff7bfc60ee3aa79241e48d87795ebbf1e43f5fe9a7be205d22cfaa0db60a674951 *04a1025460ad02277d8cb09634d1a80015a0027d052edadaf49def3ef5cea884ef446881ef443e *88558b6db09f907da73ec542e84605860a9cdadae6b6d644d4712f3617224fd4359cce69876932 *2130d5671a7cba1c065281935a9b5fdc5b177aba5b5e60e65ea3ae4a15159f17985096702905ce *fb18413b5abfafe1a85afcde301f35fa90ce16c2287396a100d5c1c1c90bc8e2d0b15878a84b39 *a051fd3b7cd2ba5a38485e2deaefa38a7c42a2141fc94839689ca8d4d2f9a90c38411f19454b4a *9bc66757e0a4d666ab59f46a6d54dd4e2aa85f7f76adeb125b125a7056863e217b8b64404ea342 *ae4a5dbe34f54f912b7559608a83083a233e9d4d81166243a8a1586434c53423faf419a6caa76a *a47c3c798c424b9f3c479f5781935a9bdf00b88beaf2d93e918b740fb4a0ea3b703ff230574a72 *53398680b9e6709092e1f80e826e1396098612a295f66707d5307acbab98289c21672a70526b93 *927475da1a9d2e52d7e8a6fee89dc3eaf7b713c85a97afa5936bbae456e0abe64aeb1dce4e510d *eb7169161a5f4681933e46f0eb69cfdab24ee45ba418f567881cc2d3cde091374db3816b54b8dd *0425ce4a43eb1ac6eecce5f18750438721dbe050a9344c9c29acfa84794f19a2d15b14672b73fa *5f5981f34e6da242bff5a43d45d79f3c6aacf73134846d45a5e13a3d9d213f7f2d64abce70f0a2 *83932e11ab0bb765e0ecc907a8ce90f7f46c5b649486070c6a4860c582f8f54a25d69ceda2a586 *a7aace683132010d49d2f25c0a3cd9d7e3515ceb7a38d4b1f8a839840ef892a1eb335c52a680cc *55ba70d61642add284382d055ef6ebf1ad82b7da3bcfde5ba10ef2bf3ec355853fbc529ed7564d *e5a5704e7d417a44e5d3eb723af0882a52cceb334c694f18272a9d089920c61054e0fd2fdfa331 *58bef9fa9ba1cfd10e277d8c707419c4a70254800a7805d8da2eb11ef4ddf740458ca9fd128ccf *2571b20ed3ca0f03d1012d1d69fb3a6c82d22c9d907eae0ec98b0c9ddada2e25d6a5c8a4abe1cc *d75c45358a6e69397d63403e2e11d2c05c73ca0b8e04ca8f070ce0888c166458b154b223ceaaec *88fc70cb49adad33d90f978004ea0a1cb7138e43ae57b7cad3d7727e5d8fcdbe4ac3fd38e77d8c *a0dd0d9f217d0d366ad3132cfad4a4c69d3e92b78f630e72d15aa0753e5aa6faa7d386b5a31bfa *a06518859c15c4ab813e2857aacf908f2207357c6a830dc694802fd6528bb1be36b0f654400fd8 *5a0c69a027830ea90535f4a5a521a9b125609f12e6423e69baab194f6a6db21a86028943584068 *11f9cca817151f3f97eaaf7cfc1a451cb4a49357e1930606e370f3201fb460a2d4277046355067 *d550022d0522a305f9a416bf3c2c51e82081730b47ede68caa566a4fc1fb4655461f2d69a8ab8f *1098cbad520daaa62095ec0127c89b66370e389ad2b894f1a4d6a6d24f08e403351ca7a4e3e357 *f650f78063eb522e30a9a1e110f2094b64c864ad03f241ce98d17c3ace738acda9d1a181e4cdd2 *a97d0eb0954bd024d7124ce4dc4a6af662f66964492429965437ac6595c349ad4da5d1b9dfa46f *45cda18f5f739dec88a396ad4b167156cdd61cce717c10794eb1b9ba8651c5791fe2984367f1d4 *41869ea8ea30a4e830877ca9392d562a6e277d8ce0356de92b76593afa83055456d5d0277540a3 *5accaec490d2d082c8c3904d0e7dc510aac2a7e2d342deaf580b19eda94508e84f5863c5a25a6e *a6736be9a664f61b5b7cce443e624ef7f3af209c776a1336c395610e2aa8ef29add84d3ec1d9b2 *28373f8ba9a52228f2518b3db640427671538b3c6aed88ec256d6d83340a39989be642870a9f4a *ae548d50a917bfc3074906675f544b9f3457ca07d30d2d8833b4a086de32cce81d2aeba7e3a350 *c8671387073a5fe8ebf1a2b22d4d7ffd40752e9e9a8a859dbca90fd627973a7bad1efb45aba7fc *7afcf33e3fd437c95a4f2ab656cf161a756e297365fb8217a4952e5e9140be527bd0b36e25fb93 *fa50319bb843a53814fcb9d6de15befa5e51eca48f112a54cc475fff6f0a79acf37184e790e7a2 *ced4708ee15cd49975cde51ad6357498cbfbda51976b6d328b9d67c86bceb17fc1220ced67ffd2 *f1c875b4169f55eaedc759529709b2874f3a5f6aac0bbed373a8c6d0612781970cbf5c6b0b2acf *adda6254d1ad32f1d68ef5421efbcbb19eda902b34ccc74729197ddc045271ae1712d0f6d7359d *1a9984f99ae326b0d394a63356e6e89e3ed76a6db232ce9ce33373bdeaf2a2867e668f534390a7 *fbe6abaebd7e5d0b3e46e827d833aa73a98f7ed1048b4db9fab4a2029316acb82d5fa01586c167 *8f6efd584964fbc42ac5ec1d8be1070d8bc87d7af551ad021786cda0f251407f5d4f112aed233f *568d89a25e3be4d2ad0dd7ae4c86ad51bbf0fb53aed3289c45dbdeb8f4776e833497cf820c176e *42ccae5b4eec41281313b30f2d9a256868801d64a4b7ca829c11d9a430fe4ad5df629458503a74 *bb941a48ef6e964bb7b674326c91d96858af69d4d068eb522e30c530bcef506158f1e967698d62 *3968b1d8ce500bdfdb77865752847443dd7ccbb7e4e40b00002000494441544be9a5c6c0649825 *655e414e0369dcafc0f3b5365c73b680e6d69f012a8edf09fbf515040fd861c86db044ed23403a *33d899d0239810b3aec0b53e4690eddd5a2b2dbb959a3aa4c6541df30c1cc45e074991b732eca7 *5bc82765dbcf9e86748c2a668573c5274d74e65342582472bb29fb263542b15b73a55addca78f5 *539b359ad61af20e61e5c944b6a264489d6dc5180e46754070ad18ace1541876b2638a4d7cac52 *c54963317bdf6294828648d58b69b393ba79cf9643dfdee2acf6b4f016606b6d600a8fb04a8d0a *4e8b39eda6c082afc7ffea1f7fb54450fb0287b59b25b07b40aec344abb81a9fa1b69e70877c67 *6898e2210ec5ba02b77a5410e4e9f4396e529ef2ebf126c7a627d8e34414e4eb30d132afc66728 *7eff9873c1191f56641321ed66eba414d5c085f774f35e94f150b7052f489fe5ebb287ea48f096 *02afba2de7ea9a8b6a694b7b47816b7d8cd021caa1b50ad8a1632dec34dad5f84c17c2c08b28f0 *c4ad6de76690f08080962593b493e7120e08e25f1cc9a8d6be9fea344ee0838469a1029b1438b5 *b5eddf399b6aeb3be34b03b4f4114e183d5431ab57b2c8b5feecc9b813e782fa9f30c54c719002 *27b536bf61f66c9e8354b82cecf9bb7d55c65538979d1a12bbb80227b53651413b5abfafc9a8fe *a86a16123aa3f749f50d389a7d18855088137c9061a0eafd6d087d8c5b18f2b7480feb423e69d4 *9c51490e290dc157e10c13d1e1ce0a2cf884b4229f3c87db96e83c9fdb9038eb75b8b05bddd569 *eae0a338889cc67a638a835148157d946da770715089ecd12c299a1a5386453e1d5865eb1d3cab *4a2d162b6496e0f4d972940aa00227b536bfc4fd860c84c24e90d17e3bc07a82c577b4a133c62a *1f01e9d0e80c1960a7e4adac86fe153e3b41ea29fa9efdd121493a50818e02e7bd20d575dc59cd *baffc5a1e3d3a9a433348dac64b0e17672a54382b31f2445a6910a50815481935a9bef56c3ceb5 *b00b04a84dc8e63cd79842ae1464139f74fe961b2b94cef1a964595e3e015f4681935e90aa5efd *a6669b3fed0286305cf13e5c33a6c88a238fc62a5810a732eb692e4f5e1c5a3ec644fd91612030 *c710aba8e09ce9230c87b56315b45001afc082afc7bf7bf78e9a5281e50af8679de5e0047c5205 *ea5f8f3fe905e993ea48da0f54209c611fc884a99f5101b6b6679c3572a6025460a0005bdb4020 *0e53012af08c0ab0b53de3ac913315a0020305d8da060271980a5081675480aded19678d9ca900 *151828c0d6361088c354800a3ca3026c6dcf386be44c05a8c04001b6b681401ca60254e0191560 *6b7bc65923672a4005060ab0b50d04e23015a002cfa8005bdb33ce1a3953012a305080ad6d2010 *87a90015784605d8da9e71d6c8990a50818102a7febdb60197db0cbfffe5fb61addf7cfdcdd087 *0e54800ab414e0a9ada50ced54800a3cb1026b4e6df6976ff937b69e782d903a15782105169cda *f4afa1fabf8bbd471feb920a126e5bc845b75678cb9ec2a6c61602ed54800a3c448105adcdf3de *7f6a9b43988b9a537c2e171be29cda8ca202730aac79418ab9f1252a5a5a51d63b34441f3b0d25 *38c8ad3817a38443486796343bc286bad2ec06d5a902d5a0850a5081690516b436eb23be29f87e *a10ec19232f6508aa69d227536638812bb4575c2870c036d4d1772797c4c6a9614aa5f1447a900 *15d8a3c082d626e9b16de939c53343cb1edefd58e3d371ebf0a9847790d3f0d4d801e11015a002 *7b1458d3da9001ee64b460d4699670da3a2d2f1351012a708e020b3e46e81c7fa4061c454ba5d4 *b9a821720a8b46b40c9183c37e84ad19e94f05eeacc082539bbe91a422ead1ac624945d7fd2f8f *76c433a8cea10fa352706ff4b01a8e9cc51fb3875c6914669f608820b450012a505780ff7b7c5d *ab5d9ebe5ff38b56bba464f08d15e0ff1e7fb9c9ef9c3a2fc79584a8c0f32bb0e005297e91bb72 *2a797ee9e62b40c5e6b1184905a840a6c0828f1132d8b74f0ff4271da5f16a0ab4e64bdf25bc1a *5bf2e1bc0cd7c0b2d68627357909e65f85b536cf90e27e87a3d7c1fe267e34c3a021120e93a5fe *e2b6fc75f41195d631eb9efb579d20a0ce4b6005c47f7eb50af3c57096b5b6be2eba4974ff9cbc *bcfac4fce81c312b6d2ebc4eafe539917779c36a71abdb27aaa8832ff19c6078419d9748f11420 *27b536afc5abcef7a3ea3a28afb6ecd316f17415a7f19c66789086c267a2db1e44e682b00f686d *a6824c8cfea845e7c95bc41e7cd0528cb2c04dd971c2900ffa040b32548bafdab3427b4008e1fe *362533c1b98283754954c865b781a4da7dd5a983370eab403e21dc176543e863dc307b2a4ba8c2 *47f5fdbd5c818f715004bddd843c4cfdf20e0b3e21ad68e49f61f4d94fe6c99e06ed3a5ca00f5a *747d78cc391f65d87f6646645d6dfad889c50253d13c7eea6024cdd30b9b8620e7d46d684c71b0 *2e9c53b4a451aaa1d2c05c68414f5c09ada23c5aea33d4d9b31584b07886f83ee9509f56ed2973 *1a4d81935a9b4ebf66c589b7d9c58bb08604012d16a5f8bace342302ae9dfbb0a65be08161ea86 *b2a46e1346546c02240d41792bb92a6a583a754ee71415ab2063545a5adf9826aad4de87d5d114 *bc12481fafc079ad6d4e779c66b420b2fa2c59c4087e9045776fa5baad048ec04c3978c157ed73 *4bb46a4e5f40e7547c1a8302cbde6bebff1a6a7fa1f7479531faa02578ea229e98f216f204543f *24244a094f906985b4ec29c940466f05a102e27d34441ee73aac4219a0b1da041838afd239d54d *8c7d89c2e8509f96f29b1468517d61fbb2539bfc5e5ba7bbf9c5a44b1c2da832faa0a51255f431 *7065588c42b7a1c5274a779d38b47c02370df7ab3c5852c5306ac8591c2c75e06cb129e796983e *e390735ac59073ca47a374481e5b3e81f650b1942146a1a5a28ff9b4941f4a714387055f8ffff0 *970f4138697336079599bba1ee87962ce26f95bd355f06e531ebf875cf4305b914f8562553ffdb *0a5bff7afcb2535b583d5bb7d6a516dfb3939910bf156276b968b5bf6797eb64fe2da95b3452e5 *b782b4c05fd8bea0b5e157ac5e58af3b9736b19d26426ea570519fa2dbada41b16bbec63846126 *3a50012a40054e5380aded34a999880a5081f314606b3b4f6b66a20254e03405d8da4e939a89a8 *0015384f01b6b6f3b466262a40054e5380aded34a999880a5081f314606b3b4f6b66a20254e034 *05d8da4e939a89a80015384f01b6b6f3b466262a40054e5380aded34a999880a5081f314606b3b *4f6b66a20254e03405d8da4e939a89a80015384f81055f8ffff9cf7f7e1e5f66a20254e0c60a74 *fea8515085a7b61b2f13964e055e578105a7b63ffcaf3f883efff4dffe491ef53ac8a543430d43 *ac4579fc21c8c90e587bb1d88378a6fadbecd493b6e6a28e404f2af05805969dda7053c9260ffd *4e7cd0cdeab7a6d0e99245b1fa8914a4e2534c771d37d35c28f9eb3986388373388ca202e72bb0 *acb50da95b53eb74b71464ff164d6169a40254e0851558f082d4d4e9f72ce950ea60a7b38aac86 *69513e4b0a157aa8fa84a8bacf046d6438b4983276511167938f47463e15288c9ab0a4957a1c61 *629a2b2b3f05c7e95351803e4fa4c082fff6e5abafbfea179c36a034a4b3ee7d87c2eb80163680 *bf4d534838fa1866a7bb853de9430c538d69870d3e721b7675a86b788bca18c3808c9e1e3cd4a5 *cee6e0472b75a10f566af4fc45479f4069a80c1d5e43816fbffdb655c8bb77effcd0b2535bd839 *ba765b2476da5b0d6527ac842372650ba55bd7c8a832d83afbb92a79ebf5221a6647b41085fd4e *2cbe2e15706ba598572dc850f9602d2d04daefacc0b2d65611316c834a48ea73dce2f6c8b8b552 *3215a3c26a23b01407e5aaf0119fad1a62c332105fd744a512a20881d563f529ca48b7cb2ab0f2 *6384fe6eb14eb1b0650c65b53dd3f1acf874c2874361df9e59fe90db84839f47bdf6ed2c582af8 *16d25f3f1528fa50015360656bebcb6a0bb7b582fd9e1128db300adbda4569521f2bd77eef1972 *c7674ff7c15c7dcb9e5c69ed43a3e753cf6e517ae12728f426b94d2dad5cc8072dc3a2e8400582 *020b3e46f8c52f7e4159a9c0b402e149cb9ae63420035f5881533f46683d1bf7f5b527ffbe1b47 *5f5e01590976d0635f7bf9e93eadc0051f23f0bfb63e6db65e351197d0abceec03eb3aefbdb607 *16c9d454800adc4d01b6b6bbcd38eba502b75080aded16d3cc22a9c0dd14606bbbdb8cb35e2a70 *0b05d8da6e31cd2c920adc4d01b6b6bbcd38eba502b75080aded16d3cc22a9c0dd14606bbbdb8c *b35e2a700b05d8da6e31cd2c920adc4d01b6b6bbcd38eba502b75080aded16d3cc22a9c0dd1460 *6bbbdb8cb35e2a700b05d8da6e31cd2c920adc4d01b6b6bbcd38eba502b75080aded16d3cc22a9 *c0dd14606bbbdb8cb35e2a700b05d8da6e31cd2c920adc4d01b6b6bbcd38eba502b75080aded16 *d3cc22a9c0dd14606bbbdb8cb35e2a700b05d8da6e31cd2c920adc4d01b6b6bbcd38eba502b750 *80aded16d3cc22a9c0dd14f8f4ff90f2ff82bcdbdcb35e2af0c20a7c6c6d7ffad73fbd70912c8d *0a5081bb2930fedfe3d9f5eeb626582f15784605c2ebce8fadeddb6fbf7dc662c8f91915f8d53f *fcea8bfffdc5f9cc1f95f7fc4a6f98f18b7f8d2bea693e469075293f73733611ab21d319e778fa *a8901a4b404b48da22efed56e6106d7f458a2089acaf0526698a5615a973df287917a255d4eea4 *eb28df89320dfb95a29ba5ab04be86cfd3b4b693e57ec8b1c26ad4fdef9738f2414b4522dc3682 *633f1584b53ec86721fea1e09ee75ca239e5716d0c15d3104d37477598e2820e9b5bdb334aa393 *7a41f5534aba10654868af55db90d3bc27184f2680dd7fb9a4225aab289c3bb4a0e67d9ffadae8 *e360ded7b3345b9b97c6aef562b96a0268c8e142974e20d3f2511c7bd4d90ab7e914fac0d4e135 *8cb8d5bd440fa931f49a30d19e920da18f4e9f2e150b31e3d175a5aa4af66057da9ebc120ee5a4 *685b4b08d997606ee5f070ff8f1f2304c55b5ae842b4518c424bbd429d0f790c201e41875af442 *2e0554ce36d402574ccd5ec4af9776654f554918dac505d90eb9d9ca34cf30ef58545809e85fb4 *20726a31867e29daaa3b67c9f9b9f6248b95ae52ec209cf7efdffba23eb6b6bab2de13a3d0924e *736a2cc616ddd21462c470153ac8dd0a3fc77e1a1954e39c027d16e1d0afd736e45a6e58fb9c05 *59b5087b7cccd58a42fcbea585e3ed98fdd92df209e9975f7ee99519ff5e5b5fc7f3475b33b793 *094eed4ec03de146a6bfe7f7a478a25851e3a0493f4e049bb84dcce7a2b00ac4d94403019fd1d2 *7cafcd8a09bbebe4cd16d2e99e7f2ca5679ce616e79367539b1492c1e7159c77a48a16440e1609 *c15cc3a8ad0e92427f24d0a7f384917c2bca67370143211e0d71cea97aab4a47fb375b9b8a982a *88b3b29ca52e88744ac210fad8aa5256c6b645db00c5019d5b51cb4bee032a0d4f062d88a01559 *5d7861b32c43aa03829c6949579d12d021b96ef904fe157d969486aaa6b081cfb4f21ae88bad54 *1a5642caf0c58c3f95f7dee4ab54f56f235c640fbcd834dcaa9c472da147e5b5c93d8ec071c8cf *b232f1bdb6b7d6f6f9e79f3f4b01e44905a800154815483e46f8dd7fff5deaaa46fdd2e9870f1f *5a3e1ffe1287defff2479fc2b60269a70254800a6c52a0d388debd7be7a13e7e42dafa636dc53f *fbe17bd9375f7fb3892b9da90015a002cb15f8f4318274b1f0b32459a539aa4fc5732ba51666cb *be15dffb1f81b9870fc6b618b6ec88d0b7a438624ced7da8cee85ab44ea2e2d0d5f814691fedb6 *7cde3de1afbefeca7e5a85343f216d05dccd7ef2c2dd9a6eabffcee99b48d77a41b0934931bc48 *b8e8564cbadc4de94d909c0899261f7255e63da5971a3baca4c7a5a38f6f6d52494585947ddfb8 *04b9c86d492e29a798ae5f783aba84e171f452ce685c5205c24ed775101f64b8d5e21bc4d666b1 *3597fa4f6b18d255703efbe567f623e169775bf36d04d3ce684daba98188a3161bf54b0ab3e3dc *a43e3e9702a6d9bdd6298e4f670e6234ce7291229b8f220c7d4276bd1d469da9c6501f21833e15 *cbb00a01093aa33ee8637cfab38c0c91cf41165f85f22f26f281ad10ac2b58f45685f57b50014d *34736b25329de5c2e38440c441868220bd4c5a9b5eb432ae696dbec2bfffc9df0b9b50732bbdf7 *d4e2ad6cafa61f32bbc6865c3e6fffda023b179acbc85772d9cc61396669e1f874e883962091cf *b8f5ba23820d55d448353701535658175a1461680f55a03ee9a40ceb1ae6f5052ebfb62a3c8d90 *4586bc45427c513a29e88375a145609100ce72d030152144196c60ee79a67cd43f3da979a835ad *cd10dfd87f9dd6951871aaacf8c4bb6d0a73268e88fc2386dfdf602eb3e09086dbfcc985f97472 *5592b6cbfa74ba419f550c3b2577863a6a20d5094b51679cf7962c9ec3b02e710ec8453e139556 *42948c3da635a2d197a04b147d52592a94e67c70bee670304a4f70c1beb8b561d6132cfd395b4b *407355dad9febc73759dcff008352a55cce953991744aef0a9204ff8486a5578abce3e7022efda *104f7e6d8f4bfb9a905ffc31429df4d679aa08add9fbc8758698d16275d188439a4b8cfa833b04 *312b16e4dcb214195a52c4a9f0511fcc558ff59e2aa62ad64296d18e98952a2a3ec85fa3b0d23e *1fc439dfe2e5ea4867c436e9a3933527429a283516456bbd325d736af3732f2f486de717c9b5dc *3c4e6baa5a3e1eb3e29372d0ba6c0a8b38c3958438b84ad0072dc2d98c9a34f509a5557ca6d5f8 *d14af81ea5a2a129a6ce1586151fd467aeae62ae147c89d126772b9a099b06625d68d1c08083b0 *61963bf31e52d88c6ba2ca6a11cfd649cd97f9f1ebf13e9f0dab51cbe87cbf41be6815be8d70e7 *2f5a61934a5755305ad45c7825c5657d7cc9372cffb2f3d222f6d839ea34a2fc8b56ad328a767e *b9aa2854cbcd9e5af0f9b015f232f6f034fe3275b190c72ab0e005e99dcf683879d3bd693a1039 *3c9de5ceb573b20e5260f1c70807b1242c15a002546093029b4f6dfef388ca9b799bd8d0990a50 *012ab044816da7b6d6e7ac452afaf147d1996e54800a50816905369cdab4afcd9dd4f829d8f40c *31900a50810905b69dda24811ddcec42cf62f2d83f9499db044b8650012a40053629b0e1d466b8 *f8b2d40e657a117a9c7cfe851ff0a3cf26de74a60254800a7414d8d0dae4a5283635850e1fdee3 *67f9be9169fb439f0e4b0e51012a40053629b0ed05e9dc1b6dbefdb1a36d9a1e3a53012a30a7c0 *b6d6d63ab50d73fb8ec6ee36948b0e54800aec5460c30b52c9b4e7d426e16c6a3b678be154800a *1415d8766a4b4179224b65a1910a5081072ab0a0b53d903d5353012a40055205d8da525968a402 *54e0b915606bbbf4fcf57f0bfad2d4498e0a3c548105ad4db69fff796839e3e4cfd52ce47dcc94 *f0afffe79752aa3e8e6bdee2d1c26cd9b76047df2330638e7df72d862dfbd66c298e1853fb5670 *f35f8b364d23e5932eeffd290461416b1314d981f6d3a2355dc374608b89d997202f01e9507dba *8f954fde485bd36df5ef4c4d656822dd9ffebfcf2bc807f9140917dd0e2259815dd3da2a99a67d *8edbdbc7214f175b09945575d0ea5f825ce4b62497c8554c571136f82c61781cbd62454baac05c *d3751dc407196efbbd368c4f2d7290b15752da3ef468a38fd650ecbc633e21ea6de17eff7fc7fa *90968f77435678b69a4346ce294925d0aa4bf5511f7f8db42b167dfeb4a5664fa76ab151bfa482 *4f9a25f5f1b91430cdeed77d8ae3339ac39b92df1f583ac8e6a3086976ef13b2ebed300a0549ab *f0381dce7d3552e440007d2a966115c859614fabeb6daee57f2e3ee6df9ad61636fcdbdafae17f *57d30bed47be8c747b8728addcc05581e093e204ad828f8e5a8b34e72132e69aae6b7a3675395a *b8ddda32f53d4eafe5d18f7a844dd721d7dbecfc707eb40bcd85f4bc73b8965be45ca94b03c553 *d3612d6831293631441c5f028ab0490dacddb8d5eb4a197a92adeb401ef5492b1dce72854f2873 *f9ed9ad686ad172d483df4ac37117f68e19df0ce10a6d864c1ecc8d00037d140e44dc43e258597 *a2b6313601caca0bfe7e2d86214b81b93a430a627b402eccb993cb520f91d37ab12e04c4ea34aa *c8b043ac33d451232d64abb1a833ea639c3b198775496c402ef2e924dd3fb4a6b5cdf1d8d41de6 *52ec8c3a9a61a775ee64de0faf2ce83e427d547355da591db3e53957d7f90c8f50a352c59c3e2d *b5bd1d912b7c2ac8d33e0ff81801f7335aeaf548f79170fda9476df54486154b2b8b71ded43a8f *d80ffa64db47c6a7fa565d68b75859e89d5c32a43fb84310b36241ce2d4b91a125459c0a1ff5c1 *5cf558efa962aa622d6419ed8859a9a2e283fc350a2bedf3419cfd9635a736bfcf5bdb55f7b330 *5607bb354b5a8c22cb630bd68763bbf938f1d96f870d9191215a34bb426daaab534eaa43d1681d *44fcfdca0ed77ee5a5c82d9cd4d91b6d656bc6224e67132a38e2e056411fb4a82c4ab2ce30c519 *4a210e1535702e2a51a698d582388161b10a73b31458e990613117222fb42cf8dfe3c37fdabc90 *5c05ca77bd7e07aca09de3f38c9c8f53069b54259745cd8557525cd6c7977cb7f2cffedfe31fb8 *08d293d403f954523f23e74a5d67fa540e1767f23933d715ce4467d63b976bcd0bd2b9dcaba20e *7a71b78a5e8af38c9cd342f61b3b2f7cfae0d3817dd8a718bd73edc5097ac0c708456674a30254 *800a4c2b70786b6bbdb52f8c6d087dd0325de14181758675cf83a80e61cf6438976b2e0a0b4f71 *c498da319c962752e0f0d6d6d24216937fcba9e5b6c7be75bd6ef5dfc3ad187b414a81f9d5184e *f0e19b03c5d5f85c6e0f6b6d2a9376b7b0b6b4ebedd7f1b825bb8ae1b0c64a09139b7998b7ee50 *615847dbef79353efb2b22c29c026b5a9bec2efd31126809fc6c0976d6a281d8eed58b4aaea14f *605847f68560945115377fed6fd1c7d886a18080736c0470482d8f6588d95507abb7431b7dbca5 *831c2628e0e8ad86d7b36354b074f8f473b538d0be5381059f90cacc597bd2eb60d944d1c74a60 *40168b39a4b97cc7b42535642851f21352639416d2720bf650757f542b0d1529a5be7a481bfd2d *759f437f749a2166c739ed6885e11d4b50cc5764d713d911072df595891344cb110a2c686d9e96 *ad9b39aec3dda51b4cc137e512e416a5168eed13b9e8ec8756b84f57a9ab456f681f12183a488a *e3185af60a0d2cb613de19b215a2f32e9e73d9914f07b9c3676df6162bdabd028b5bdb65c59d5b *5b1ab57fdb0bce7e9043b5bd3ec3b9f257cd20663f0e1973d132a1c09af7da2c71e7703424976e *7e31eacf5c6fc2a4c8b06531bb6e7b814a19620ab5045803f1fe98ba85d6b1ab3e1d87d6d0410c *9714659cf7a0e10cb6a4e8db75eebcce5b91f754d1e7c6d196020b4e6d7ed36a034ab7718b41df *3eec68985d965188421fb4080d336215431a568507497b8738b47c42160dc77250b13abd50e672 *8615cebe2f602d9ea15ea73ea93164379d3d0e66af4499c2ea9c22074a159fb40a1a972870e9af *c7577635aa605173e1087865cb056bbc20a59d33e82b7abdea768a7372f88dbe1e8fcafa33118e *be9865d379ed9cda2f486967e13c7fed14f021e10b5e901ec77b7a934c071e570b919f5a01aea8 *a79bbec51f233c5dfd244c05a8c04b2ab0a0b5e91babaa8ebff67ab5ecfb354d91c598da8be9e6 *62e7a2faba0d09efac74884f072af0a40a2c686d7b2adfd30e3a7917be7c38886187bc0d55522f *acb442893e54e0591458d3da741356b662d0e5823b53aaf0ac2ec8f059d616795281072ab0e663 *04d9ffda11acbbd945680dbe71a88f3978046f54753a2da695cbcb8a3e68c169d8c4d0c2037228 *7958883a28882760d71e1039d34205a88028b0a6b5a194a161a943d893da107dac39e845b129a4 *b9525831f6917732347c5faf96698fa855104739a4fe45a8560adaa9c07d1458d6daacbfd8460d *2256ce1a01e4e46958c5507002f3b44fa1cfc9f5321d1578610596b536af51386de950657bbf86 *d08f6dd0afa121aba0023b1558f331428b4438bf68776b39a35dfd0504cf41e8bcc982c89523db *a614e26cb4153c54512faaeeb99521fda9c0ab2a70c8a9cd5a18f6327f76d31ddbef297602ea6c *6f1b0ace86ec69984f1db9c3b055a02e174d116898517b9fd1c01566e0de27f8573444645aa8c0 *cb2bf0345f8feff4978949f2686b91eb641e95b7ce909e54e06a0abcc8d7e3fd99a873ba9950ff *38e43a99b515d5f3d2930adc4181435e902e14eeb8fd7f1cf2c2f2094505a8c09c02c77e8c30c7 *895154800a50819d0a2c686dfa4eb6f2f0d79e59cbbe93bd84a7c8624cedc57473b17351454a74 *a302546093020b5adba67cc1f9a076b0f0c5e6410cf788c6582a4005860aac696dbaff27bac0c2 *1e342cb5e8205578561764582c846e54e0ce0aacf918413f70d44755d3da5c680dbe71a88f39e8 *101a15b0d3625ab9fcbca20f5a701d2019abd1d30e810159eb3259d2428ab557386315b450811b *2ab0a6b5a170a161a51bdbb7c2e0605b3dc509e9863ed85cd0b284a18020b296698fa855b17644 *6e41d14e05a8c0b2d6160e2376be3089fdce6ce99e9e685acecbedab1862edc3be26b558ed7aa1 *216a6f59962b40402af0320a2c6b6d5e9170bed0a1caf67e0d59573568c5f162a2e53514631554 *60b9026b3e4668d10ae7173b89b4fc835dfd0504cf414584961b22578e6c2db496dd682b78a8a2 *5f948d9a686869e5a59d0a5081434e6db61bb197a9c54e1f3201fd9ea29eead69a2dbfe7d5472d *86ec6918601db9c3b055a0d2b032f5429dcdd8af1d39a3a52508ed54800af0ebf183de7adc12e9 *74cce39212990a3cb502fc7afc60faae7002d2e3db802887a900159852e09017a4534cf2a0e3f6 *ff71c87925b452012a70a202c77e8c7062214c4505a80015f8a4c082d666efe20baabff632b7ec *fba7224516636a2fa69b8b9d8b2a52a21b15a0029b1458d0da36e50bce07b583852f360f625811 *ed81a92bf4e84305aeacc09ad6a69b70622b2eec41ab54962a3cab0b325c552971a8c00b2bb0e6 *6304fdc0511f552c6b73a135f8c6a13ee6a0436854c04e8b69e5f2d3863e68c169463256a3a71d *0203b2d665b2b40ac1280941025e0d1bf529b00a5aa8c00d1558d3da50b8d0b0d28ded5b6170d0 *bd5a6c0a692e4f0971d0b284a18020b296698fa8955a4215e88fc81258046f25a59d0abcaa02cb *5a9bed4c554a0f145eb5cac922809c2cfa2a86583bf6292c0da3d087162a40058a0a2c6b6dad2e *663bb6b2bd8ba42fee36d1a0c389ece205921e15b8be026b3e4668d5194e22dadd5ace68577f01 *597ea241e4ca910d19f62d465bc14315695175633f3547a9c0cd1538e4d4662d0c87f1698e0000 *1306494441547b993fbbe936eef7143b01a57b5e27cf8682b3217b1ae65347ee306c15a8c43445 *a06146f1418681aa96a6216915026285dc7c29b37c2ae015e0d7e3f9f578ee082af0340af0ebf1 *83a96a9d8006614b8779da5a2a27c1a8c08f1438e405e9428d8fdbffc7212f2c9f5054800acc29 *70ecc708739c184505a80015d8a9c082d6e6dfe06fbdd9dfb2ef642fe129b218537b31dda362fb *f4a659ed54a3cf8aa354e09a0a2c686d7b0a9bdeaefda4177cb17950a515d80baad19f3e8e5281 *fd0aac696dbac12adb2c30bee0ae932a8e607504e6fee9270215785505d67c8c20fb563b827537 *bb085bda370ef531078fe08d2a7da735b472f939431fb4e01c079f3a432c4dc043a59a4e31e5ba *c2c7dc144a437c2ebb36582c8a162a700705d6b43654aabf8dd55f1ba28ff5fb5c47539c906ee8 *e3f7b95ea34531434740e40ac3e023c8586928a1c5a7e5a6fe4122af6a3a14d0784b055e588165 *adcdba808a257bafb52d3b6a06908ee71143a1af490aacc21822d5ce50852de6c2284c8a3eb450 *012a200a2c6b6d5ecd7006d1a1a73b47a4552c593426854fc1b6b5445b8250015560cdc7082d35 *c34944b774cb19edea2f2095130d86772c88ecbb4c082c662fba7558e990c7a963d63d8704e840 *055e4081434e6dd6c2b097f9b39beec64e4f117ded2cd3d9ba36149c0dd9d3309f2172a70a9bf8 *1419970556ea75d032875520ac0fb472bc681a82d953281aa9c02b29c0afc73fecebf19565d4ef *fb1504fa50815752805f8f1fcc66f1b43540397ed89fc58ecfc60c54e0751438e405e942798edb *dbc7212f2c9f5054800acc2970ecc708739c184505a80015d8a9c082d6e6dfe06fbdd9dfb2ef64 *2fe129b218537b319dc52a4e804264b474881907846dd14ef187b5cc4529ec746cab84215b3a50 *81b50a2c686d7b084d6fa17ed2252f36859be0e88ff154a3a78d963e37eb1dfefdbe34578a7390 *6269ae60aca45ea27c850c7da8405f8135ad4d177d65e9073617dc09da6552d56cc8ba125a3430 *95c29c5b511a1b34097c2ea858aa158d54e0b10aac696dbad5fdae930da93fa13cbfe783830ea1 *31c5f1b0ad5c7d9f61d4741311e4e9d8fe6a4071c41f8d7d8b8c5a167f8da93d8e7a068b193196 *162af058058efa84d4f6b6acfef45acad686e8eb3767bde8c4faa816bef9200e5ad4d9dbd3f0e9 *d94a9143ed7a1b9e21fced56c504102b55107b6c5514e622f52f42b552d04e058e5360596bf33b *507754203ddcdbe21f408e2b3b454e19a6c6345c8da97f6a0c20567be8299d5c45c50410730d29 *3d762efa5573940a0c1558d6da7c26bf6d6c5fa54ffb437e8f7518eeff949e953c179e62ee31b2 *49ed518fb14faac09af7da5ac587f38276b79633dad55f40020e7a6eb52032b621b4187f1b4a2d *62d46ea28f151ce48f51e8b3d562322a785035dc76c0eb9e1d100e5181431538e4d4661bde2eac *06b5d89e177b7f0faba7bab584b09d169c0dd9d3309f4dc8925afd3d7fe58396164f6f0f512943 *c4d14a3b8a791c4fcfaee522c8a2750d9155017533e9d4e8795670b02e5aa8c07205f8f5f8416f *5daef865013b1df3b29c49ec6e0af0ebf183192f9e920628af35eccf62af5519abb9a30287bc20 *5d28e471fbed38e485e5138a0a508139058efd18618e13a3a80015a0023b1558d0daf49d63e5e1 *af3db3967d277b094f91c598da8be92c5671021422a3a543cc38206c8bf6563ec5325b4cb6866f *f56f95b99fcf10792b55fa3faf020b5adb9ee2d3a6b007506397bcd8146e82a33fbeb9f8f7e924 *9dba6d2d2444a5b9820ea9cf5cf6fd0a1bc2d6c225706e762a89e69017aa41a8eb28b0a6b5e9b2 *ab2cbe50f905d7a2368b74866cc8ba1b5a343095c29c5b511a1b34d9c427a57da8f182337868bd *047f1605d6b436ddea7e95cb86d49f2084dff3c14187d098e278d856aebecf306a7ad30af2746c *67ddcc61a2aa6ad144fe5a2c768b3e2a97f7d1eb8080fc3570e8d60af43c8d834f3d818cb96879 *3d058efa84d4f6a1acbcf45aa4d486e8353567bde8c4faa816bef9200e5ad4d9dbd3f0e9159022 *87daf5363c436047eb40c9102a63fe9d4089ea8f8a83ce973d9ac50b15b2b774f66ee975e0ec93 *9a3ff249a168bca702cb5a5bd881618f89b8c39d233eb88dcf9c9594616aecb04afd536300b1da *c3ae0e6e7da854c0d4b809b653af1f4a13e14aa8a0a5509540fa50015560596bf382faed672bdb *9e639f48fa7e1f69156225cf85b760c5be1cd0721d373b6c529d09e5d0710aac79afadc52f3c63 *ebfe6939a35dfd0524e0a0e7560b2263d7408bf1b7a1d42246ddcffa58c141fe188516cc8e381d *4b50d5d07cc842e5fb50fdd1832875c4e1d0b32b70c8a9cd3609ee16b5d89e17f970c77a4dd553 *dd5a5adbae08ce86ec6998cf266449adfe9ebff2414b8b67a8cb179e32441cbfff5b7c302a582c *974f1a6a69f9685203543e9d194cebc228b460159e928d6ee583b0b4bcaa02fc7afca0b7beeac4 *5fadae4e7fbc1a55f279a002fc7afc40fcf4343188e1f0910a84f3d791a9887d0b050e7941ba50 *b9e356fc71c80bcb271415a002730a1cfb31c21c274651012a4005762ac0d6b653408653012a70 *4505d8daae382be44405a8c04e05d8da760ac8702a4005aea8005bdb1567859ca80015d8a9005b *db4e01194e05a8c01515606bbbe2ac901315a0023b15606bdb2920c3a90015b8a2026c6d579c15 *72a2025460a7026c6d3b05643815a002575480aded8ab3424e54800aec5480ad6da7800ca70254 *e08a0ab0b55d7156c8890a50819d0ab0b5ed1490e154800a5c5181357fd4e89bafbfb1e2defff2 *fd9e4215ca400c792b6cc099a684042ac87d9ffe2852ddea8f08c1627fad77ff5f765a02958254 *fe3865ea931a55014ba4b7fecff699a5a51ec2a2a5154bfbf90a2c38b5d9c6d3ee63bd60493195 *8e2619d72635e6bea71c9462894a1e24ec5ec4d70d29bb1a37363a0f2dda1cf7b4c8948f1afbb5 *f4475bccb5707d149f70db8a423e6869c5d2fe100516b436cf5b3a51a519754add8fa0e0ab7010 *ad825cf1e98870dad09e96741c49ed1a82df69bee6136860bf434bca3c00fa28e483961493c607 *2ab0e6052916e0cf38b2cfc391c72cfe4240ccadd31f5bc8e909cb70d2a8901dab404b60684937 *6537d8344a4695b61f45266ab11da84d4a6ff5b1deb6fcaed66b7b942c47e3d4f1bd086994a7ed *f5f1058a1df5491d82b13505b45f5381c5a7362dd2f6a4dfa2be7e6b107251dfc68a20fefa23b7 *162ed766d46b4ce7a38c678ba1829b9b11567f0fee69a4cda8a586af1d7dcc62a94352bdb5d753 *7ebbaa31f517a31e85c45f435a6ebab1d5b9e553b1d7718e6825da017d1f443eaa835703a32a95 *d2e7520a1c756a2b1699768a7e6c7fabf763c3683fbb8ca6ad0a5354703c540b362dcd68605eb1 *f4db531a2246dbea9d6ee2db410ba7622fe2749854b2a814692e6fec3b780ea9679109ddaea0c0 *835b9b6ce67e5f081a6183b88288430e5aa390efd7eba548db5c48e4b7e25c8f1b323fc7617f5f *539e26c22ac073ca6796231458fc8254776f9d68fd641430d39dbf357b9de71e4f63650d6e135a *5a694048fb5a6a94c096bd3f849c17e2842392dc2af8a60e2551fa23543da0e7899cd1a2957a3b *f2410bea43cb631558706ad3f6643bd09f50b4b6d0bfc25e4d8f2ae2131a815a2c97614a0a4fa0 *1f15f84c486fe48d2182041f4fcfd88628f4492b0d51b6c1ec421cbc11b97907bd0e21adad8e50 *9828e5838168097dc428f90e15a22c442f5a9e3a2a8fea10844ad51063884af928542b2fd648cb *c90a3cec7f8fd7fdaf9de8e49a99ee560a585fdb54f55cd4a614749e50a0febfc72f7e413ac195 *2154e05005e60e567351871642f04d0a2c7841ba299f39f3bc36a71ba3a80015a828c0535b4525 *fa50012af0640ab0b53dd984912e15a0021505d8da2a2ad1870a5081275380adedc9268c74a900 *15a828c0d65651893e54800a3c99026c6d4f3661a44b05a8404501b6b68a4af4a10254e0c91460 *6b7bb209235d2a40052a0ab0b55554a20f15a0024fa6005bdb934d18e952012a5051e0d317adf8 *a5b98a5ef4a10254e02914f8d8dafc5f95790ade244905a80015e828f0f6478df84df58e401ca2 *0254e02914087f08f2e3a9adf357909ea22a927c6a05fec7f7ff9eba84079237e93a1aa2cf8b69 *feeeddbb3005b7f81821cca2de76d6416b993e763504c248062da19056c92d7b4b87b5f6405b6f *8fa034d4676d5d67a2616941c0d4e10891b5ea1439359abf324c79f6956cc12e686d088d963eb9 *93472bf450e29349867436f166c72ad052e13c1755419ef0b13297e81f4aab549afaa4c689ea2a *21139c11d664c4a1132c737219e74de19d4a37b7369f18afd1529152f9a9a7bfaec4567c56616e *c5595597e16c2530146739e0306370e81090a1ad6808be1341c3e7989c19e5cbacaf968ef8d3ba *b530510db460d2be8faff4b7bffd6d08dff657763593676f16c3450b320e1605b4321021b598bf *ad3f73f3fe013625e3a1e43a847834094f012d2a5cd8ad0f4c393cc468b53c247b31696b3abcd4 *06953ab712a5ce6a4c8714078790898104675b0616a2169f14f12daa55c875ec46de53d262fd10 *eae395319dbd4a5b6bfcd8da022144f454ccd9bb21d780d96186d9ad362dd8670c16830dac949b *3d76b22ba065f4219e98da433a75f0433e6f481a10fa9438ea67245c7b916d0a529fbe8c36bf08 *e827dadcc4e827d1ae5b1701df334c337a70cbe5b3f7cbd9331ab20426a1705f884f5aa76ae55b *b865c4d47375e5ad4d2b49113dfb701d38d529f603358bcf9512f31af51d70b40e8eb1c1829aec *21b62476c8f9b60eabe63dc50946f4118bfebb82fe29bdcedad6218cc25a5a35fa58c46945217e *cbb2f9bdb6b45a64895c5b0cc4aece56cca65884dd1a1eb223e0b465615d2aced6d2a699df21d0 *243d47d593d35d6a06b576dbe9456e735106beb9b5f97580d768a994613568f161a9f9d14d6801 *67189bfa6fcdeeb3f4eb1af2b9834347de743a5a9a284e07ad15a84b0e473765c7f016acb71be7 *343c18eb7c4c84a11a43870ab1a18f2fd357d1ba56c056944fe72bfd977ff997c0e4e3b7118abf *b26b6c3cad616d730e5879b0e8ad7f345142fd76db72367b8ad98ff23321d729c29c029eb6c22a *7ee0e387520542f9296c3f7027ff7eb8f0b712b4c0402614e8fdf53a20f4c3318581f8c09014a3 *cc827c3ace5ba3bcbfd2c3c756f956828504cf3410f1375942527f1b84525873c00b73c0423c25 *85955fd90ddf46d8d6da04d1f3db54f309ce2a415f88136830c55605762eaa9de15bd916fd4f63 *650bbeb3f2d1e7347a2db9d61268b6b656fae7b2ebefb6e0d1f4b9aa20dbad0ac8bc73d2b78af6 *7afec9a96deecf7e7cf6cbcf5aeae0f7b95a9eb453012a4005ea0a74de3a0b6de7e32f7f6cfd63 *6d73ddb05e003da90015a0027b14f8f409a974abe2cf309f6f7c673641cd7544c61666cb3e94a8 *e370046627ddc4508b61cbbe35458a23c6d4be15dcfcd7a24dd398e07332f3e5caefd7aa82b0f9 *973f2aa0d33e27cfd934cf89c0934bdb9a6eabff84023e6422ddd617163b1986f022e1a2db5a6e *9bd026183e56f94dd579e76bb5b6e9322450e6eca03958825ce4b62497a8514c3721f81286c7d1 *2b56b4a40acc355dd7417c163244a88b5bb67d3d7eba189d397dc6b0e9d75bdb877adbf7a913e8 *e3d8a85f52814f9a2bf5f1b91430cdeed77d8ae3339a83d747105264f35184a14fc8aeb7c32814 *24adc2e3c8758b735f8d143910409f8a6558057256d873ea4ab3fb2d1374d35b8db2d9f79a87a1 *b054866aa0c3b3580e6c6d5e5391c36e6df2c284e97ca433e7c35365b7e6d209f64c707168a2a1 *3dd485955a2e633ec4544f5cd0430d2d503c5bfc317b5d798c0d5956a981b59b7af5ba866c052a *f50955a03e3ed09cada1d419a2678a1c6a4fa3d0c7687718faa850a65706c1af6f39b0b585e26d *b1da45451dd177e88673b02985e1632e4436e74e399d210db73d2017e6dcc95549da5109eb42c0 *10be9561a7e4ce50478d4e39f5a16215a88f71eee41ad625b101b9c8a792bdb25a3ae44d79f441 *35d0e7292ce7b5b639392ad33c878c51e7e75ab240b1906099ab4ba3ce647844ae4a1573fa0c65 *170744aef029221f2157cab9c2e7823e17fd18019f3ad0a26a1e31c19aab8fdce25399638b9585 *dec92543fa833ba492057d9073cb526468291007b3b72c98abe5d9b7ab98aa987a22b2583a6256 *aaa8f8204f8ddaca27e084d4b678bcdb1c3d242c96855029fed1c6434e6d2aba3da635f889b1d5 *6646b5a43e295adfd8c2b1bc12def2f1c8159f9489adec4d75797a292cf29144210a7dd0e2cbaf *334c71529ec15851c377010daf4459edea5c6158f1417dd232870c8bb902b845f970f5518b3cb6 *7cc4eed10243ac2265388c429c2b58debe1e8ffb61c84c42f845aba14a7b1c262645d259d45cf8 *1ec20f8ff525dfb0fc87eb7f0e81cd5fb4d2c67c0e3966394e01ffec7d5c966b22a7278e6b5225 *ab1314783bb59d908629a80015a00254800a50012a40057629f0d3dffffef7d300fffccfffbc27 *7c3a2f03a9001578790576b6979f7df71fdffdf9dffe3c21d3877fff2051df7cf3cd442c43a800 *15a0024305f674a79ffdf53ffe2aff86391287bfbdd9266313389aa80015a0023f52604f777a3b *b5cdb5278d9a8be50452012a4005860aece94ef3a7b6bffeededacc7d6369c1e3a50012a30a7c0 *f4a94dbad3cffefc973f7ff7dd771389b5a9e93b6e13e10ca10254800af415d8d39dfe2fa49b55 *9fe1b0c6bf0000000049454e44ae426082 }