Skip to content

Instantly share code, notes, and snippets.

@psd
Created May 28, 2010 14:22
Show Gist options
  • Save psd/417203 to your computer and use it in GitHub Desktop.
Save psd/417203 to your computer and use it in GitHub Desktop.
confusedviz
index.html
content/
report/
.DS_Store
TiddlySaver.jar
An experimental visualization of JP's blog "Confused of Calcutta" using TiddlySpace combined with doodles.
bin - scripts used to knife and fork the blog into the visualization
cache - a mirror of http://confusedofcalclutta.com collected using wget -r
corpus - output of the text parsing as TiddlyWeb .tid files
reports - various experimental text reports
a Makefile is needed here ..
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
#!/bin/sh
#
# hack to take word list and generate frequency count
#
sort | uniq -c | sort -n
exit
all:: icons
all:: content
all:: index.html
#all:: report/freq.txt
#
# frequency count of wordle words
#
report/freq.txt: report/words.txt
bin/freq.sh < report/words.txt > $@
#
# wordle words
#
report/words.txt:
bin/words.sh > $@
#
#
# n-grams
#
report/ngrams.txt:
bin/ngrams.pl > $@
#
# download site into cache directory
#
acquire:
mkdir cache
cd cache
wget -r http://confusedofcalcutta.com/
#
# parse the cached site into content tiddlers
#
content::
mkdir -p content
bin/parse.pl
#
# convert SVG into tiddlers
#
icons::
cd icons ; make
#
# bake a TiddlyWiki from the content
#
index.html::
cook
#
# clear back to source
# .. except for the cache directory ..
#
clean::; rm -f *.jar index.html report/*
clean::; cd icons ; make clean
#clean::; cd content ; make clean
#!/bin/sh
# hack to generate TiddlyWiki cook recipe from a directory
cd content
ls | sed -e 's/^/tiddler: /' > split.recipe
#!/usr/bin/env perl
#
# find common phrases in content
#
use Text::Ngrams;
my $ng3 = Text::Ngrams->new(type=>'word');
my @files = <content/*.tid>;
$ng3->process_files(@files);
print $ng3->to_string;
#!/usr/bin/env perl
#
# parses a cached copy of http://confusedofcalcutta.com into TiddlyWeb .tid files
#
use strict;
use File::Slurp;
use File::Basename;
use File::Find;
use List::MoreUtils qw(uniq);
use HTML::Scrubber;
use Data::Dumper;
my $outdir = "content";
my $debake = 1;
my @dirs = qw(
cache/confusedofcalcutta.com/2006
cache/confusedofcalcutta.com/2007
cache/confusedofcalcutta.com/2008
cache/confusedofcalcutta.com/2009
cache/confusedofcalcutta.com/2010
);
#@dirs = qw( cache/confusedofcalcutta.com/2010/ );
my @ngrams = (
"ashtag",
"drm",
"bankrupt",
"control",
"collective",
"fish",
"Calcutta",
"Facebook",
"Generation M",
"Open Source",
"ragu",
"stewardship",
"global",
"golf",
"cricket",
"conversation",
"cooking",
"pasta",
"stewardship",
"software",
"wisdom",
"fulfilment",
"Facebook",
"Twitter",
"search",
"syndication",
"Four Pilars",
"The Because Effect",
"Twitter",
"Hugh McCloud",
"Kevin Marks",
"Doc Searls",
"Yogi Bera",
);
my %post;
my %link;
#
# initialise
#
my $scrubber = scrubber();
my $wc = new HTML::WikiConverter(dialect => 'TiddlyWiki',
base_uri => 'http://confusedofcalcutta.com/',
);
find_posts(@dirs);
write_recipe();
write_tiddlers();
exit 0;
#
# slurp files into memory
#
sub find_posts
{
find({
wanted => \&parse_html,
no_chdir => 1
}, @_);
}
#
# dump posts out as tiddlers
#
sub write_tiddlers
{
foreach my $title (keys %post) {
my $tid = $post{$title};
# convert to wikitext
$tid->{text} = $wc->html2wiki($tid->{text});
$tid->{text} =~ s/^\s*//s;
$tid->{text} =~ s/\s*$//s;
$tid->{text} =~ s/\n\n\n*/\n\n/gs;
$tid->{text} =~ s/\n*<<</\n<<</gs;
# fixup image inside a link ..
$tid->{text} =~ s/\[\[\[img\[([^\])]*)\]\]\|([^\]]*)\]\]/[img[$1][$2]]/gs;
# tag text using the ngrams
$tid->{tags} = join($tid->{tags}, find_ngrams($tid->{title} . " " . $tid->{text}));
write_tid($tid->{path}, $tid);
}
}
#
# write recipe
#
sub write_recipe
{
local (*FILE);
open FILE, "> $outdir/split.recipe" or die $!;
foreach my $title (keys %post) {
print FILE "tiddler: " . basename($post{$title}->{path}) . "\n";
}
close FILE;
}
sub get_wiki_page
{
my ($uri) = @_;
return $link{$uri};
}
#
# parse found file
#
sub parse_html
{
my $path = $_;
-f $path or return;
$path =~ /feed\/index.html$/ and return;
$path =~ /[0-9]+\/index.html$/ and return;
$path =~ /index.html$/ or return;
#
# read cached article
#
print "reading $path\n";
my $text = read_file($path);
$text = $scrubber->scrub($text);
$text =~ /<div class="entry-content full-content">/ or return;
# fixup mojibake
$text =~ s/…/ /gs;
$text =~ s/’/\&#8217;/gs;
$text =~ s/“/\&#8220;/gs;
$text =~ s/”/\&#8221;/gs;
# remove nice glyphs for simplicity
# .. may reintroduce once sanity prevails ..
if ($debake) {
$text =~ s/\&#8216;/'/gs;
$text =~ s/\&#8217;/'/gs;
$text =~ s/\&#8220;/"/gs;
$text =~ s/\&#8221;/"/gs;
$text =~ s/\&#8230;/.../gs;
}
#
# grok title, url and text
# .. The Cthulhu Way
#
my $title = $text;
$title =~ s/^.*<h1//s;
$title =~ s/<\/a><\/h1>.*$/$1/s;
my $url = $title;
$url =~ s/^.*href=["']([^"']*)["'].*$/$1/s;
$title =~ s/^.*>\s*(.*)\s*/$1/s;
my $posted = $text;
$posted =~ s/^.*<abbr//s;
$posted =~ s/^.*title=['"]([^"']*)["'].*$/$1/s;
$posted =~ s/[^0-9]//g;
my $popularity = $text;
$popularity =~ s/^.*Popularity:\s*([0-9]+)%.*$/$1/s;
#
# prune back to text
#
$text =~ s/^.*<div class="entry-content full-content">//s;
$text =~ s/<p class="akpc_pop">.*$//s;
#
# create tiddler object
#
my $tpath = $path;
$tpath =~ s/\/index.html$//;
$tpath =~ s/^.*\///;
$tpath = "$outdir/$tpath.tid";
my $tid = {
title => $title,
url => $url,
text => $text,
posted => $posted,
path => $tpath,
popularity => $popularity,
};
$post{$title} = $tid;
$link{$tid->{url}} = $title;
}
#
# write a tiddler
#
sub write_tid
{
my ($path, $tid) = @_;
local (*FILE);
print "writing $path\n";
# bail on duplicate title
#-f $path and die "$path exists";
open FILE, "> $path" or die $!;
#binmode(FILE, ":utf8");
foreach my $key (keys %{$tid}) {
next if ($key eq "text" || $key eq "tpath" || $key eq "tags");
print FILE "$key: " . $tid->{$key} . "\n";
}
if ($tid->{tags}) {
print FILE "tags: [[" , join("]] [[", uniq($tid->{tags})) , "]]\n";
}
print FILE "\n";
print FILE $tid->{text};
close FILE;
}
#
# create a HTML scrubber
#
sub scrubber
{
#
# scrub
#
my @allow = qw[ h1 div p blockquote br hr b a ol ul li dl dt dd abbr];
my @rules = (
script => 0,
abbr => {
'*' => 0,
title => 1,
},
img => {
'*' => 0,
src => 1,
alt => 1,
},
);
my @default = (
0 => # default rule, deny all tags
{
'*' => 0,
'href' => 1,
'name' => 1,
'id' => 1,
'class' => 1,
}
);
return HTML::Scrubber->new(
allow => \@allow,
rules => \@rules,
default => \@default,
comment => 0,
process => 0,
);
}
#
# find ngrams in a block of text
#
sub find_ngrams
{
my ($text) = @_;
my @found;
foreach my $tag (@ngrams) {
push(@found, $tag) if ($text =~ /\b$tag\b/si);
}
return @found;
}
#
# convert HTML content to TiddlyWiki wikitext
# .. hacked MediaWiki converter
# .. to be turned into a CPAN package ..
#
package HTML::WikiConverter::TiddlyWiki;
use base 'HTML::WikiConverter';
#use warnings;
use strict;
use URI;
use File::Basename;
use HTML::Tagset;
our $VERSION = '0.59';
my @common_attrs = qw/ id class lang dir title style /;
my @block_attrs = ( @common_attrs, 'align' );
my @tablealign_attrs = qw/ align char charoff valign /;
my @tablecell_attrs = qw(
abbr axis headers scope rowspan
colspan nowrap width height bgcolor
);
my $pre_prefix = '[jsmckaoqkjgbhazkfpwijhkixh]';
sub rules {
my $self = shift;
my %rules = (
hr => { replace => "\n----\n" },
#br => { preserve => 1, empty => 1, attributes => [ qw/id class title style clear/ ] },
br => { end => "\n", line_format => 'single' },
p => { block => 1, trim => 'both', line_format => 'single' },
em => { start => "//", end => "//", line_format => 'single' },
strong => { start => "''", end => "''", line_format => 'single' },
blockquote => { start => "<<<", end => "<<<", line_format => 'blocks' },
i => { alias => 'em' },
b => { alias => 'strong' },
pre => { line_prefix => $pre_prefix, block => 1 },
table => { start => \&_table_start, end => "|}", block => 1, line_format => 'blocks' },
tr => { start => \&_tr_start },
td => { start => \&_td_start, end => "\n", trim => 'both', line_format => 'blocks' },
th => { start => \&_td_start, end => "\n", trim => 'both', line_format => 'single' },
caption => { start => \&_caption_start, end => "\n", line_format => 'single' },
img => { replace => \&_image },
a => { replace => \&_link },
ul => { line_format => 'multi', block => 1 },
ol => { alias => 'ul' },
dl => { alias => 'ul' },
li => { start => \&_li_start, trim => 'leading' },
dt => { alias => 'li' },
dd => { alias => 'li' },
# Preserved elements, from MediaWiki's Sanitizer.php (http://tinyurl.com/dzj6o)
#div => { preserve => 1, attributes => \@block_attrs },
#span => { preserve => 1, attributes => \@block_attrs },
#blockquote => { preserve => 1, attributes => [ @common_attrs, qw/ cite / ] },
del => { preserve => 1, attributes => [ @common_attrs, qw/ cite datetime / ] },
ins => { preserve => 1, attributes => [ @common_attrs, qw/ cite datetime / ] },
font => { preserve => 1, attributes => [ @common_attrs, qw/ size color face / ] },
# Headings (h1-h6)
h1 => { start => \&_hr_start, end => \&_hr_end, block => 1, trim => 'both', line_format => 'single' },
h2 => { start => \&_hr_start, end => \&_hr_end, block => 1, trim => 'both', line_format => 'single' },
h3 => { start => \&_hr_start, end => \&_hr_end, block => 1, trim => 'both', line_format => 'single' },
h4 => { start => \&_hr_start, end => \&_hr_end, block => 1, trim => 'both', line_format => 'single' },
h5 => { start => \&_hr_start, end => \&_hr_end, block => 1, trim => 'both', line_format => 'single' },
h6 => { start => \&_hr_start, end => \&_hr_end, block => 1, trim => 'both', line_format => 'single' },
);
my @preserved = qw/ center cite code var sup sub tt big small strike s u ruby rb rt rp /;
push @preserved, 'i' if $self->preserve_italic;
push @preserved, 'b' if $self->preserve_bold;
push @preserved, 'nowiki' if $self->preserve_nowiki;
$rules{$_} = { preserve => 1, attributes => \@common_attrs } foreach @preserved;
return \%rules;
}
sub attributes { {
preserve_italic => { default => 0 },
preserve_bold => { default => 0 },
strip_tags => { default => [ qw/ head style script ~comment title meta link object / ] },
pad_headings => { default => 0 },
preserve_templates => { default => 0 },
preserve_nowiki => { default => 0 },
# see bug #28402
# xxx passthrough_naked_tags => { default => [ qw/ tbody thead font / ] },
passthrough_naked_tags => { default => [ qw/ tbody thead font span / ] },
} }
sub _hr_start {
my( $wc, $node, $subrules ) = @_;
( my $level = $node->tag ) =~ s/\D//g;
my $affix = ('=') x $level;
return $wc->pad_headings ? "$affix " : $affix;
}
sub _hr_end {
my( $wc, $node, $subrules ) = @_;
( my $level = $node->tag ) =~ s/\D//g;
my $affix = ('=') x $level;
return $wc->pad_headings ? " $affix" : $affix;
}
sub postprocess_output {
my( $self, $outref ) = @_;
$$outref =~ s/\Q$pre_prefix\E/ /g;
}
# Calculates the prefix that will be placed before each list item.
# Handles ordered, unordered, and definition list items.
sub _li_start {
my( $self, $node, $rules ) = @_;
my @parent_lists = $node->look_up( _tag => qr/ul|ol|dl/ );
my $prefix = '';
foreach my $parent ( @parent_lists ) {
my $bullet = '';
$bullet = '*' if $parent->tag eq 'ul';
$bullet = '#' if $parent->tag eq 'ol';
$bullet = ':' if $parent->tag eq 'dl';
$bullet = ';' if $parent->tag eq 'dl' and $node->tag eq 'dt';
$prefix = $bullet.$prefix;
}
return "\n$prefix ";
}
sub _link {
my( $self, $node, $rules ) = @_;
my $url = defined $node->attr('href') ? $node->attr('href') : '';
my $text = $self->get_elem_contents($node);
# Handle internal links
if( my $title = &main::get_wiki_page( $url ) ) {
$title =~ s/_/ /g;
return "[[$title]]" if $text eq $title; # no difference between link text and page title
return "[[$text]]" if $text eq lcfirst $title; # differ by 1st char. capitalization
return "[[$text|$title]]"; # completely different
}
# Treat them as external links
return $url if $url eq $text;
return "[[$text|$url]]";
}
sub _image {
my( $self, $node, $rules ) = @_;
my $img = $node->attr('src');
return '' unless $img;
return sprintf '[img[%s]]', $img;
#my $alt = $node->attr('alt') || '';
#my $img = basename( URI->new($node->attr('src'))->path );
#my $width = $node->attr('width') || '';
#return sprintf '[[Image:%s|%spx|%s]]', $img, $width, $alt if $alt and $width;
#return sprintf '[[Image:%s|%s]]', $img, $alt if $alt;
#return sprintf '[[Image:%s]]', $img;
}
sub _table_start {
my( $self, $node, $rules ) = @_;
my $prefix = '{|';
my @table_attrs = (
@common_attrs,
qw/ summary width border frame rules cellspacing
cellpadding align bgcolor frame rules /
);
my $attrs = $self->get_attr_str( $node, @table_attrs );
$prefix .= ' '.$attrs if $attrs;
return $prefix."\n";
}
sub _tr_start {
my( $self, $node, $rules ) = @_;
my $prefix = '|-';
my @tr_attrs = ( @common_attrs, 'bgcolor', @tablealign_attrs );
my $attrs = $self->get_attr_str( $node, @tr_attrs );
$prefix .= ' '.$attrs if $attrs;
return '' unless $node->left or $attrs;
return $prefix."\n";
}
# List of tags (and pseudo-tags, in the case of '~text') that are
# considered phrasal elements. Any table cells that contain only these
# elements will be placed on a single line.
my @td_phrasals = qw/ i em b strong u tt code span font sup sub br ~text s strike del ins /;
my %td_phrasals = map { $_ => 1 } @td_phrasals;
sub _td_start {
my( $self, $node, $rules ) = @_;
my $prefix = $node->tag eq 'th' ? '!' : '|';
my @td_attrs = ( @common_attrs, @tablecell_attrs, @tablealign_attrs );
my $attrs = $self->get_attr_str( $node, @td_attrs );
$prefix .= ' '.$attrs.' |' if $attrs;
# If there are any non-text elements inside the cell, then the
# cell's content should start on its own line
my @non_text = grep !$td_phrasals{$_->tag}, $node->content_list;
my $space = @non_text ? "\n" : ' ';
return $prefix.$space;
}
sub _caption_start {
my( $self, $node, $rules ) = @_;
my $prefix = '|+ ';
my @caption_attrs = ( @common_attrs, 'align' );
my $attrs = $self->get_attr_str( $node, @caption_attrs );
$prefix .= $attrs.' |' if $attrs;
return $prefix;
}
sub preprocess_node {
my( $self, $node ) = @_;
my $tag = defined $node->tag ? $node->tag : '';
$self->strip_aname($node) if $tag eq 'a';
$self->_strip_extra($node);
$self->_nowiki_text($node) if $tag eq '~text';
# # XXX font-to-span convers
# $node->tag('span') if $tag eq 'font';
}
my $URL_PROTOCOLS = 'http|https|ftp|irc|gopher|news|mailto';
my $EXT_LINK_URL_CLASS = '[^]<>"\\x00-\\x20\\x7F]';
my $EXT_LINK_TEXT_CLASS = '[^\]\\x00-\\x1F\\x7F]';
# Text nodes matching one or more of these patterns will be enveloped
# in <nowiki> and </nowiki>
sub _wikitext_patterns {
my $self = shift;
# the caret in "qr/^/" seems redundant with "start_of_line" but both
# are necessary
my %wikitext_patterns = (
misc => { pattern => qr/^(?:\*|\#|\;|\:|\=|\!|\|)/m, location => 'start_of_line' },
italic => { pattern => qr/''/, location => 'anywhere' },
rule => { pattern => qr/^----/m, location => 'start_of_line' },
table => { pattern => qr/^\{\|/m, location => 'start_of_line' },
link => { pattern => qr/\[\[/m, location => 'anywhere' },
template => { pattern => qr/{{/m, location => 'anywhere' },
);
delete $wikitext_patterns{template} if $self->preserve_templates;
return \%wikitext_patterns;
}
sub _nowiki_text {
my( $self, $node ) = @_;
my $text = defined $node->attr('text') ? $node->attr('text') : '';
return unless $text;
my $wikitext_patterns = $self->_wikitext_patterns;
my $found_nowiki_text = 0;
ANYWHERE: {
my @anywhere_patterns =
map { $_->{pattern} } grep { $_->{location} eq 'anywhere' } values %$wikitext_patterns;
$found_nowiki_text++ if $self->_match( $text, \@anywhere_patterns );
};
START_OF_LINE: {
last if $found_nowiki_text;
my @sol_patterns =
map { $_->{pattern} } grep { $_->{location} eq 'start_of_line' } values %$wikitext_patterns;
# find closest parent that is a block-level node
my $nearest_parent_block = $self->elem_search_lineage( $node, { block => 1 } );
if( $nearest_parent_block ) {
my $leftmostish_text_node = $self->_get_leftmostish_text_node( $nearest_parent_block );
if( $leftmostish_text_node and $node == $leftmostish_text_node ) {
# I'm the first child in this block element, so let's apply start_of_line nowiki fixes
$found_nowiki_text++ if $self->_match( $text, \@sol_patterns );
}
}
};
if( $found_nowiki_text ) {
$text = "<nowiki>$text</nowiki>";
} else {
#$text =~ s~(\[\b(?:$URL_PROTOCOLS):$EXT_LINK_URL_CLASS+ *$EXT_LINK_TEXT_CLASS*?\])~<nowiki>$1</nowiki>~go;
}
$node->attr( text => $text );
}
sub _get_leftmostish_text_node {
my( $self, $node ) = @_;
return unless $node;
return $node if $node->tag eq '~text';
return $self->_get_leftmostish_text_node( ($node->content_list)[0] )
}
sub _match {
my( $self, $text, $patterns ) = @_;
$text =~ $_ && return 1 for @$patterns;
return 0;
}
my %extra = (
id => qr/catlinks/,
class => qr/urlexpansion|printfooter|editsection/
);
# Delete <span class="urlexpansion">...</span> et al
sub _strip_extra {
my( $self, $node ) = @_;
my $tag = defined $node->tag ? $node->tag : '';
foreach my $att_name ( keys %extra ) {
my $att_value = defined $node->attr($att_name) ? $node->attr($att_name) : '';
if( $att_value =~ $extra{$att_name} ) {
$node->detach();
$node->delete();
return;
}
}
}
1;
#!/bin/sh
title=$(echo $1 | sed -e 's/.*\///' -e 's/-/ /g' -e 's/\..*$//')
case "$title" in
ragu|cooking) tags="food";;
Four*Pilars) tags="search syndication conversation fulfilment";;
search|syndication|conversation|fulfilment) tags="[[Four Pilars]]";;
esac
cat <<-!
title: $title
tags: concept $tags
theme: imageTiddler
!
xsltproc - "$1" <<-!
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="svg:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
</xsl:template>
<xsl:template match="svg:metadata | svg:defs">
</xsl:template>
<xsl:template match="@id">
</xsl:template>
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
<xsl:template match="@sodipodi:*"/>
<xsl:template match="@inkscape:*"/>
</xsl:stylesheet>
!
#!/bin/sh
#
# hack to take the tid files and generate a word list for wordle, etc
#
perl -e '
use HTML::Scrubber;
use File::Slurp;
my @allow = qw[ ];
my @rules = ( script => 0,);
my @default = (
0 => # default rule, deny all tags
{ '*' => 0, }
);
my $s = HTML::Scrubber->new(
allow => \@allow,
rules => \@rules,
default => \@default,
comment => 0,
process => 0,
);
my @files = <content/*>;
for (@files) {
my $text = read_file($_);
print $s->scrub($text);
}
' |
sed -e '/^url:/d' |
perl -pe 's/\&#\d*;/'\''/g;' \
-e 's/[^A-Za-z'\'']/ /g;' \
-e 's/\bthe\b/ /ig;' \
-e 's/\band\b/ /ig;' \
-e 's/\bthe\b/ /ig;' \
-e 's/\bthis\b/ /ig;' \
-e 's/\bthat\b/ /ig;' \
-e 's/\bthere\b/ /ig;' \
-e 's/\bdon'\''t\b/ /ig;' \
-e 's/\bI\b/ /g;' \
-e 's/\bI'\''m\b/ /g;' \
-e 's/\bmy\b/ /ig;' \
-e 's/\band\b/ /ig;' \
-e 's/\bor\b/ /ig;' \
-e 's/\bof\b/ /ig;' \
-e 's/\bfor\b/ /ig;' \
-e 's/\bto\b/ /ig;' \
-e 's/\bin\b/ /ig;' \
-e 's/\bwith\b/ /ig;' \
-e 's/\bwhy\b/ /ig;' \
-e 's/\btitle\b/ /ig;' \
-e 's/\bby\b/ /ig;' \
-e 's/\bon\b/ /ig;' \
-e 's/\s\s*/\n/g;' |
sed '/^[ ]*$/d'
exit
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment