update gitignore, add assets and files

This commit is contained in:
Sami Samhuri 2014-02-15 18:19:42 -08:00
parent 7904fddaae
commit eb5f13df19
48 changed files with 2810 additions and 10 deletions

10
.gitignore vendored
View file

@ -1,11 +1 @@
.bundle
_blog
public/js/*.js
public/css/*.css
discussd/discuss.dirty
public/blog
public/proj
node_modules
public/s42/.htaccess
public/images/blog
public/f

179
public/css/blog.css Normal file
View file

@ -0,0 +1,179 @@
body { margin: 0
; padding: 0
}
h1 { margin: 0
; padding: 0.2em
; color: #9ab
}
.center { text-align: center
; font-size: 1.2em
}
.hidden { display: none }
#index { width: 80%
; min-width: 300px
; max-width: 800px
; border: solid 1px #999
; -moz-border-radius: 10px
; -webkit-border-radius: 10px
; border-radius: 10px
; background-color: #eee
; margin: 1em auto
; padding: 1em
; font-size: 1.2em
; line-height: 1.5em
; list-style-type: none
}
.date { float: right }
#article,
article { width: 80%
; min-width: 400px
; max-width: 800px
; margin: 0.6em auto
; font-size: 1.2em
; line-height: 1.4em
; color: #222
}
#article h1,
article h1 { text-align: left
; font-size: 2em
; line-height: 1.2em
; font-weight: normal
; color: #222
; margin: 0
; padding-left: 0
}
#article h1 a,
article h1 a { color: #222
; text-decoration: underline
; border-bottom: none
; text-shadow: #ccc 1px 1px 5px
; -webkit-transition: text-shadow 0.4s ease-in
}
#article h1 a:hover,
article h1 a:hover { text-shadow: 1px 1px 6px #ffc
; color: #000
}
#article h2,
article h2 { font-size: 1.8em
; font-weight: normal
; text-align: left
; margin: 1em 0
; padding: 0
; color: #222
}
#article h3,
article h3 { font-size: 1.6em
; font-weight: normal
}
.time,
time { color: #444
; font-size: 1.2em
}
.permalink { font-size: 1em }
.gist { font-size: 0.8em }
/* show discussion */
#sd-container { margin: 3em 0 }
input[type=submit],
#sd { border: solid 1px #999
; border-right-color: #333
; border-bottom-color: #333
; padding: 0.4em 1em
; color: #444
; background-color: #ececec
; -moz-border-radius: 5px
; -webkit-border-radius: 5px
; border-radius: 5px
; text-decoration: none
; margin: 0 2px 2px 0
}
input[type=submit]:active,
#sd:active { margin: 2px 0 0 2px
; color: #000
; background-color: #ffc
}
#comment-stuff { display: none
; color: #efefef
; margin: 0
; padding: 2em 0
}
#comments-spinner { text-align: center }
#comments { width: 70%
; max-width: 600px
; margin: 0 auto
}
.comment { color: #555
; border-top: solid 2px #ccc
; padding-bottom: 2em
; margin-bottom: 2em
}
.comment big { font-size: 2em
; font-family: Verdana, sans-serif
}
#comment-form { width: 400px
; margin: 2em auto 0
}
input[type=text],
textarea { font-size: 1.4em
; color: #333
; width: 100%
; padding: 0.2em
; border: solid 1px #999
; -moz-border-radius: 5px
; -webkit-border-radius: 5px
; border-radius: 5px
; font-family: verdana, sans-serif
}
input:focus[type=text],
textarea:focus { border: solid 1px #333 }
textarea { height: 100px }
input[type=submit] { font-size: 1.1em
; cursor: pointer
}
pre { background-color: #eeeef3
; margin: 0.5em 1em 1em
; padding: 0.5em
; border: dashed 1px #ccc
}
footer { margin: 0 auto
; padding: 0.2em 0
; border-top: solid 1px #ddd
; clear: both
; width: 80%
}
footer p { margin: 0.5em }
footer a { border-bottom: none
; color: #25c
; font-size: 1.2em
; text-decoration: none
}

7
public/css/ie6.css Normal file
View file

@ -0,0 +1,7 @@
ul { behavior: none
; padding-bottom: 25px
}
img { behavior: url(../js/iepngfix.htc)
; behavior: url(../../js/iepngfix.htc)
}

1
public/css/ie7.css Normal file
View file

@ -0,0 +1 @@
ul#projects li { list-style-type: none }

140
public/css/mobile.css Normal file
View file

@ -0,0 +1,140 @@
/* phones and iPad */
@media only screen and (orientation: portrait) and (min-device-width: 768px) and (max-device-width: 1024px),
only screen and (min-device-width: 320px) and (max-device-width: 480px),
only screen and (max-device-width: 800px)
{
ul.nav { padding: 0.5em
; width: 60%
; max-width: 600px
}
ul.nav li { display: block
; font-size: 1.5em
; line-height: 1.8em
}
ul.nav li:after { content: '' }
}
/* phones */
@media only screen and (min-device-width: 320px) and (max-device-width: 480px),
handheld and (max-device-width: 800px)
{
/* common */
h1 { font-size: 2em
; margin-top: 0.5em
}
h2 { font-size: 1.3em; line-height: 1.2em }
.navbar { font-size: 0.9em }
.navbar { width: 32% }
#breadcrumbs { margin-left: 5px }
#show-posts { margin-top: 1em
; font-size: 0.8em
}
#forkme { display: none }
ul.nav { width: 80% }
ul.nav li { font-size: 1.4em
; line-height: 1.6em
}
td { font-size: 1em
; line-height: 1.1em
}
img { max-width: 100% }
#index { width: 90%
; min-width: 200px
; margin: 0.3em auto 1em
; padding: 0.5em
; font-size: 1em
}
#index li > span.date { display: block
; float: none
; color: #666
; font-size: 0.8em
}
#article h1,
article h1 { font-size: 1.6em
; line-height: 1.2em
; margin-top: 0
}
article h2 { font-size: 1.4em }
#article,
article { min-width: 310px
; margin: 0
; padding: 0.6em 0.4em
; font-size: 0.8em
}
.time,
time { font-size: 1.0em }
pre, .gist { font-size: 0.8em }
#comment-stuff { padding: 0
; margin-top: 2em
}
#comments { width: 100% }
#comment-form { width: 90%
; margin: 0 auto
}
input[type=text],
textarea { font-size: 1.2em
; width: 95%
}
input[type=submit] { font-size: 1em }
/* proj */
#info { width: 70%
; padding: 0 1em
}
#info > div { clear: left
; width: 100%
; max-width: 100%
; padding: 0.5em 0.2em 1em
; border-left: none
; font-size: 1em
}
#stats { font-size: 1em; margin-bottom: 0.5em }
footer { margin: 0
; padding: 0.5em 0
; font-size: 1em
; width: 100%
}
}
/* landscape */
@media only screen and (orientation: landscape) and (min-device-width: 768px) and (max-device-width: 1024px),
only screen and (orientation: landscape) and (min-device-width: 320px) and (max-device-width: 480px),
handheld and (orientation: landscape) and (max-device-width: 800px)
{
body { font-size: 0.8em }
}
/* iPad portrait */
@media only screen and (orientation: portrait) and (min-device-width: 768px) and (max-device-width: 1024px)
{
article > header > h1 { font-size: 1.8em }
}

51
public/css/projects.css Normal file
View file

@ -0,0 +1,51 @@
td { font-size: 1.5em
; line-height: 1.6em
}
td:nth-child(2) { padding: 0 10px }
.highlight { font-size: 1.2em }
#stats a { text-decoration: none }
#info { text-align: center
; margin: 1em auto
; padding: 1em
; border: solid 1px #ccc
; width: 90%
; max-width: 950px
; background-color: #fff
; -moz-border-radius: 20px
; -webkit-border-radius: 20px
; border-radius: 20px
; behavior: url(../js/border-radius.htc)
; behavior: url(../../js/border-radius.htc)
}
h4 { margin: 0.5em 0 0.7em }
#info > div { text-align: center
; font-size: 1.3em
; width: 31%
; max-width: 400px
; float: left
; display: inline
; padding: 0.5em 0.2em
; border-left: dashed 1px #aaa
}
#info > div:first-child { border-left: none }
#info ul { list-style-type: none
; text-align: center
; padding: 0
; margin: 0
}
#info li { padding: 0.2em 0
; margin: 0
}
#info > br.clear { clear: both }
#contributors-box a { line-height: 1.8em }

92
public/css/style.css Normal file
View file

@ -0,0 +1,92 @@
TODO: include mobile.css here, just one set of styles
body { background-color: #f7f7f7
; color: #222
; font-family: 'Helvetica Neue', Verdana, sans-serif
}
h1 { text-align: center
; font-size: 2em
; font-weight: normal
; margin: 0.8em 0 0.4em
; padding: 0
}
h2 { text-align: center
; font-size: 1.7em
; line-height: 1.1em
; font-weight: normal
; margin: 0.2em 0 1em
; padding: 0
}
a { color: #0E539C }
a.img { border: none }
.navbar { display: inline-block
; width: 33%
; font-size: 1.5em
; line-height: 1.8em
; margin: 0
; padding: 0
}
.navbar a { text-shadow: none }
#breadcrumbs a { color: #222 }
#title { text-align: center }
#archive { text-align: right }
#forkme { position: absolute
; top: 0
; right: 0
; border: none
}
ul.nav { text-align: center
; max-width: 400px
; margin: 0 auto
; padding: 1em
; border: solid 1px #ccc
; background-color: #fff
; -moz-border-radius: 20px
; -webkit-border-radius: 20px
; border-radius: 20px
; behavior: url(js/border-radius.htc)
; behavior: url(../js/border-radius.htc)
}
ul.nav li { display: block
; font-size: 1.6em
; line-height: 1.8em
; margin: 0
; padding: 0
}
ul.nav li a { padding: 5px
; text-decoration: none
; border-bottom: solid 1px #fff
; text-shadow: #ccc 2px 2px 3px
}
ul.nav li a:visited { color: #227 }
ul.nav li a:hover,
ul.nav li a:active { text-shadow: #cca 2px 2px 3px
; border-bottom: solid 1px #aaa
}
ul.nav li a:active { text-shadow: none }
footer { text-align: center
; font-size: 1.2em
; margin: 1em
}
footer a { border-bottom: none }
#promote-js { margin-top: 3em
; text-align: center
}
#promote-js img { border: none }

77
public/css/typocode.css Normal file
View file

@ -0,0 +1,77 @@
/* Syntax highlighting */
.typocode_ruby .normal {}
.typocode_ruby .comment { color: #005; font-style: italic; }
.typocode_ruby .keyword { color: #A00; font-weight: bold; }
.typocode_ruby .method { color: #077; }
.typocode_ruby .class { color: #074; }
.typocode_ruby .module { color: #050; }
.typocode_ruby .punct { color: #447; font-weight: bold; }
.typocode_ruby .symbol { color: #099; }
.typocode_ruby .string { color: #944; background: #FFE; }
.typocode_ruby .char { color: #F07; }
.typocode_ruby .ident { color: #004; }
.typocode_ruby .constant { color: #07F; }
.typocode_ruby .regex { color: #B66; background: #FEF; }
.typocode_ruby .number { color: #F99; }
.typocode_ruby .attribute { color: #7BB; }
.typocode_ruby .global { color: #7FB; }
.typocode_ruby .expr { color: #227; }
.typocode_ruby .escape { color: #277; }
.typocode_xml .normal {}
.typocode_xml .namespace { color: #B66; font-weight: bold; }
.typocode_xml .tag { color: #F88; }
.typocode_xml .comment { color: #005; font-style: italic; }
.typocode_xml .punct { color: #447; font-weight: bold; }
.typocode_xml .string { color: #944; }
.typocode_xml .number { color: #F99; }
.typocode_xml .attribute { color: #BB7; }
.typocode_yaml .normal {}
.typocode_yaml .document { font-weight: bold; color: #07F; }
.typocode_yaml .type { font-weight: bold; color: #05C; }
.typocode_yaml .key { color: #F88; }
.typocode_yaml .comment { color: #005; font-style: italic; }
.typocode_yaml .punct { color: #447; font-weight: bold; }
.typocode_yaml .string { color: #944; }
.typocode_yaml .number { color: #F99; }
.typocode_yaml .time { color: #F99; }
.typocode_yaml .date { color: #F99; }
.typocode_yaml .ref { color: #944; }
.typocode_yaml .anchor { color: #944; }
.typocode {
background-color:#eee;
padding:2px;
margin:5px;
margin-left:1em;
margin-bottom:1em;
}
.typocode pre {
padding: 0px;
margin: 0px;
border: none;
background: transparent;
font-family: monospace;
overflow:auto;
}
.typocode .lineno {
text-align: right;
/* color: #B00;*/
font-family: monospace;
padding-right: 1em;
}
code {
font-family: "Andale Mono", "Lucida Typewriter", "Bitstream Vera Sans Mono", fixed-width, monospace;
font-size: 0.9em;
}
pre {
background: #555;
border: 1px dashed #5189ea;
margin-bottom: 30px;
margin-top: -10px;
padding: 5px;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

260
public/f/cheat.el Normal file
View file

@ -0,0 +1,260 @@
;; cheat.el
;; Time-stamp: <2007-08-22 10:00:04 sjs>
;;
;; Copyright (c) 2007 Sami Samhuri <sami.samhuri@gmail.com>
;;
;; See http://sami.samhuri.net/2007/08/10/cheat-from-emacs for updates.
;;
;; License
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License
;; as published by the Free Software Foundation; either version 2
;; of the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, write to the Free Software
;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
;;
;;
;; Provide a handy interface to cheat.
;; See http://cheat.errtheblog.com for details on cheat itself.
;;
;; sjs 2007.08.21
;; * Cache the list of cheat sheets, update it once a day (configurable).
;; * Strictly complete cheat sheet names.
(defvar *cheat-host* "cheat.errtheblog.com")
(defvar *cheat-port* "80")
(defvar *cheat-uri* (concat *cheat-host* ":" *cheat-port*))
(defvar *cheat-directory* "~/.cheat")
(defvar *cheat-sheets-cache-file* (concat *cheat-directory* "/sheets"))
(defvar *cheat-last-sheet* nil
"Name of the most recently viewed cheat sheet.")
(defvar *cheat-sheet-history* nil
"List of the most recently viewed cheat sheets.")
(defconst +seconds-per-day+ 86400)
(defvar *cheat-cache-ttl* +seconds-per-day+
"The minimum age of a stale cache file, in seconds.")
;;; interactive functions
(defun cheat (name &optional silent)
"Show the specified cheat sheet.
If SILENT is non-nil then do not print any output, but return it
as a string instead."
(interactive (list (cheat-read-sheet-name)))
(if silent
(cheat-command-silent name)
(cheat-command name)))
(defun cheat-sheets ()
"List all cheat sheets."
(interactive)
(cheat-command "sheets"))
(defun cheat-recent ()
"Show recently added cheat sheets."
(interactive)
(cheat-command "recent"))
(defun cheat-clear-cache ()
"Clear the local cheat cache, located in ~/.cheat."
(interactive)
(cheat-command "--clear-cache")
(make-directory *cheat-directory*))
(defun cheat-versions (name)
"Version history of the specified cheat sheet."
(interactive (list (cheat-read-sheet-name)))
(cheat-command name "--versions"))
(defun cheat-diff (name version)
"Show the diff between the given version and the current version of the named cheat.
If VERSION is of the form m:n then show the diff between versions m and n."
(interactive (list (cheat-read-sheet-name)
(read-string "Cheat version(s): ")))
(cheat-command name "--diff" version))
(defun cheat-add-current-buffer (name)
"Add a new cheat with the specified name and the current buffer as the body."
(interactive "sCheat name: \n")
(post-cheat name (buffer-string) t)
(if (interactive-p)
(print (concat "Cheat added (" name ")"))))
(defun cheat-edit (name)
"Fetch the named cheat and open a buffer containing its body.
The cheat can be saved with `cheat-save-current-buffer'."
(interactive (list (cheat-read-sheet-name)))
(cheat-clear-cache name) ; make sure we're working with the latest version
(switch-to-buffer (get-buffer-create (cheat->buffer name)))
(insert (cheat-body name))
(if (interactive-p)
(print "Run `cheat-save-current-buffer' when you're done editing.")))
(defun cheat-save-current-buffer ()
"Save the current buffer using the buffer name for the title and the contents as the body."
(interactive)
(let ((name (buffer->cheat (buffer-name (current-buffer)))))
(post-cheat name (buffer-string))
;; TODO check for errors and kill the buffer on success
(if (interactive-p)
(print (concat "Cheat saved (" name ")")))
(cheat-clear-cache name)
(cheat name)))
;;; helpers
;; this is from rails-lib.el in the emacs-rails package
(defun string-join (separator strings)
"Join all STRINGS using SEPARATOR."
(mapconcat 'identity strings separator))
(defun blank (thing)
"Return T if THING is nil or an empty string, otherwise nil."
(or (null thing)
(and (stringp thing)
(= 0 (length thing)))))
(defun cheat-command (&rest rest)
"Run the cheat command with the given arguments, display the output."
(interactive "sArguments for cheat: \n")
(shell-command (concat "cheat " (string-join " " rest))))
(defun cheat-command-to-string (&rest rest)
"Run the cheat command with the given arguments and return the output as a string. Display nothing."
(shell-command-to-string (concat "cheat " (string-join " " rest))))
(defalias 'cheat-command-silent 'cheat-command-to-string)
(defun cheat-read-sheet-name (&optional prompt)
"Get the name of an existing cheat sheet, prompting with completion and history.
The name of the sheet read is stored in *cheat-last-sheet* unless it was blank."
(let* ((default (when (blank prompt) *cheat-last-sheet*))
(prompt (or prompt
(if (not (blank default))
(concat "Cheat name (default: " default "): ")
"Cheat name: ")))
(name (completing-read prompt
(cheat-sheets-list t)
nil
t
nil
'*cheat-sheet-history*
default)))
(when (not (blank name))
(setq *cheat-last-sheet* name))
name))
(defun cheat-sheets-list (&optional fetch-if-missing-or-stale)
"Get a list of all cheat sheets.
Return the cached list in *cheat-sheets-cache-file* if it's
readable and `cheat-cache-stale-p' returns nil.
When there is no cache or a stale cache, and
FETCH-IF-MISSING-OR-STALE is non-nil, cache the list and then
return it.
Otherwise return nil."
(cond ((and (file-readable-p *cheat-sheets-cache-file*)
(not (cheat-cache-stale-p)))
(save-excursion
(let* ((buffer (find-file *cheat-sheets-cache-file*))
(sheets (split-string (buffer-string))))
(kill-buffer buffer)
sheets)))
(fetch-if-missing-or-stale
(cheat-cache-list)
(cheat-sheets-list))
(t nil)))
(defun cheat-fetch-list ()
"Fetch a fresh list of all cheat sheets."
(nthcdr 3 (split-string (cheat-command-to-string "sheets"))))
(defun cheat-cache-list ()
"Cache the list of cheat sheets in *cheat-sheets-cache-file*. Return the list."
(when (not (file-exists-p *cheat-directory*))
(make-directory *cheat-directory*))
(save-excursion
(let ((buffer (find-file *cheat-sheets-cache-file*))
(sheets (cheat-fetch-list)))
(insert (string-join "\n" sheets))
(basic-save-buffer)
(kill-buffer buffer)
sheets)))
(defun cheat-cache-stale-p ()
"Non-nil if the cache in *cheat-sheets-cache-file* is more than *cheat-cache-ttl* seconds old.q
If the cache file does not exist then it is considered stale.
Also see `cheat-cache-sheets'."
(or (null (file-exists-p *cheat-sheets-cache-file*))
(let* ((now (float-time (current-time)))
(last-mod (float-time (sixth (file-attributes *cheat-sheets-cache-file*))))
(age (- now last-mod)))
(> age *cheat-cache-ttl*))))
(defun cheat-body (name)
"Call out to Ruby to load the YAML and return just the body."
(shell-command-to-string
(concat "ruby -ryaml -e '"
"puts YAML.load_file(File.expand_path(\"~/.cheat/"
name ".yml\")).to_a[0][-1]'")))
(defun url-http-post (url args)
"Send ARGS to URL as a POST request."
(let ((url-request-method "POST")
(url-request-extra-headers
'(("Content-Type" . "application/x-www-form-urlencoded")))
(url-request-data
(concat (mapconcat (lambda (arg)
(concat (url-hexify-string (car arg))
"="
(url-hexify-string (cdr arg))))
args
"&")
"\r\n")))
;; `kill-url-buffer' to discard the result
;; `switch-to-url-buffer' to view the results (debugging).
(url-retrieve url 'kill-url-buffer)))
(defun kill-url-buffer (status)
"Kill the buffer returned by `url-retrieve'."
(kill-buffer (current-buffer)))
(defun switch-to-url-buffer (status)
"Switch to the buffer returned by `url-retreive'.
The buffer contains the raw HTTP response sent by the server."
(switch-to-buffer (current-buffer)))
(defun post-cheat (title body &optional new)
(let ((uri (concat "http://" *cheat-uri* "/w/" (if new "" title))))
(url-http-post uri `(("sheet_title" . ,title)
("sheet_body" . ,body)
("from_gem" . "1")))))
(defun buffer->cheat (name)
(substring name 7 (- (length name) 1)))
(defun cheat->buffer (name)
(concat "*cheat-" name "*"))
(provide 'cheat)

BIN
public/f/download.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

256
public/f/feed-icon32x32.png Normal file
View file

@ -0,0 +1,256 @@
<html>
<head>
<title>samhuri.net</title>
<style type='text/css'>
body {
background: #000;
color: #ffc;
}
a, a:link {
color: #ff6;
text-decoration: none;
}
a:hover { color: #ff0; }
p { font-size: 72px; text-align: center; margin-top: 30%; }
</style>
</head>
<body>
<!-- BEGIN WAYBACK TOOLBAR INSERT -->
<script type="text/javascript" src="http://staticweb.archive.org/js/disclaim-element.js" ></script>
<script type="text/javascript" src="http://staticweb.archive.org/js/graph-calc.js" ></script>
<script type="text/javascript" src="http://staticweb.archive.org/jflot/jquery.min.js" ></script>
<script type="text/javascript">
//<![CDATA[
var firstDate = 820454400000;
var lastDate = 1325375999999;
var wbPrefix = "http://web.archive.org/web/";
var wbCurrentUrl = "http://samhuri.net/";
var curYear = -1;
var curMonth = -1;
var yearCount = 16;
var firstYear = 1996;
var imgWidth=400;
var yearImgWidth = 25;
var monthImgWidth = 2;
var trackerVal = "none";
var displayDay = "5";
var displayMonth = "Dec";
var displayYear = "2006";
var prettyMonths = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
function showTrackers(val) {
if(val == trackerVal) {
return;
}
if(val == "inline") {
document.getElementById("displayYearEl").style.color = "#ec008c";
document.getElementById("displayMonthEl").style.color = "#ec008c";
document.getElementById("displayDayEl").style.color = "#ec008c";
} else {
document.getElementById("displayYearEl").innerHTML = displayYear;
document.getElementById("displayYearEl").style.color = "#ff0";
document.getElementById("displayMonthEl").innerHTML = displayMonth;
document.getElementById("displayMonthEl").style.color = "#ff0";
document.getElementById("displayDayEl").innerHTML = displayDay;
document.getElementById("displayDayEl").style.color = "#ff0";
}
document.getElementById("wbMouseTrackYearImg").style.display = val;
document.getElementById("wbMouseTrackMonthImg").style.display = val;
trackerVal = val;
}
function getElementX2(obj) {
var thing = jQuery(obj);
if((thing == undefined)
|| (typeof thing == "undefined")
|| (typeof thing.offset == "undefined")) {
return getElementX(obj);
}
return Math.round(thing.offset().left);
}
function trackMouseMove(event,element) {
var eventX = getEventX(event);
var elementX = getElementX2(element);
var xOff = eventX - elementX;
if(xOff < 0) {
xOff = 0;
} else if(xOff > imgWidth) {
xOff = imgWidth;
}
var monthOff = xOff % yearImgWidth;
var year = Math.floor(xOff / yearImgWidth);
var yearStart = year * yearImgWidth;
var monthOfYear = Math.floor(monthOff / monthImgWidth);
if(monthOfYear > 11) {
monthOfYear = 11;
}
// 1 extra border pixel at the left edge of the year:
var month = (year * 12) + monthOfYear;
var day = 1;
if(monthOff % 2 == 1) {
day = 15;
}
var dateString =
zeroPad(year + firstYear) +
zeroPad(monthOfYear+1,2) +
zeroPad(day,2) + "000000";
var monthString = prettyMonths[monthOfYear];
document.getElementById("displayYearEl").innerHTML = year + 1996;
document.getElementById("displayMonthEl").innerHTML = monthString;
// looks too jarring when it changes..
//document.getElementById("displayDayEl").innerHTML = zeroPad(day,2);
var url = wbPrefix + dateString + '/' + wbCurrentUrl;
document.getElementById('wm-graph-anchor').href = url;
//document.getElementById("wmtbURL").value="evX("+eventX+") elX("+elementX+") xO("+xOff+") y("+year+") m("+month+") monthOff("+monthOff+") DS("+dateString+") Moy("+monthOfYear+") ms("+monthString+")";
if(curYear != year) {
var yrOff = year * yearImgWidth;
document.getElementById("wbMouseTrackYearImg").style.left = yrOff + "px";
curYear = year;
}
if(curMonth != month) {
var mtOff = year + (month * monthImgWidth) + 1;
document.getElementById("wbMouseTrackMonthImg").style.left = mtOff + "px";
curMonth = month;
}
}
//]]>
</script>
<style type="text/css">body{margin-top:0!important;padding-top:0!important;min-width:800px!important;}#wm-ipp a:hover{text-decoration:underline!important;}</style>
<div id="wm-ipp" style="display:none; position:relative;padding:0 5px;min-height:70px;min-width:800px; z-index:9000;">
<div id="wm-ipp-inside" style="position:fixed;padding:0!important;margin:0!important;width:97%;min-width:780px;border:5px solid #000;border-top:none;background-image:url(http://staticweb.archive.org/images/toolbar/wm_tb_bk_trns.png);text-align:center;-moz-box-shadow:1px 1px 3px #333;-webkit-box-shadow:1px 1px 3px #333;box-shadow:1px 1px 3px #333;font-size:11px!important;font-family:'Lucida Grande','Arial',sans-serif!important;">
<table style="border-collapse:collapse;margin:0;padding:0;width:100%;"><tbody><tr>
<td style="padding:10px;vertical-align:top;min-width:110px;">
<a href="http://wayback.archive.org/web/" title="Wayback Machine home page" style="background-color:transparent;border:none;"><img src="http://staticweb.archive.org/images/toolbar/wayback-toolbar-logo.png" alt="Wayback Machine" width="110" height="39" border="0"/></a>
</td>
<td style="padding:0!important;text-align:center;vertical-align:top;width:100%;">
<table style="border-collapse:collapse;margin:0 auto;padding:0;width:570px;"><tbody><tr>
<td style="padding:3px 0;" colspan="2">
<form target="_top" method="get" action="http://wayback.archive.org/web/form-submit.jsp" name="wmtb" id="wmtb" style="margin:0!important;padding:0!important;"><input type="text" name="url" id="wmtbURL" value="http://samhuri.net/" style="width:400px;font-size:11px;font-family:'Lucida Grande','Arial',sans-serif;" onfocus="javascript:this.focus();this.select();" /><input type="hidden" name="type" value="replay" /><input type="hidden" name="date" value="20061205055004" /><input type="submit" value="Go" style="font-size:11px;font-family:'Lucida Grande','Arial',sans-serif;margin-left:5px;" /><span id="wm_tb_options" style="display:block;"></span></form>
</td>
<td style="vertical-align:bottom;padding:5px 0 0 0!important;" rowspan="2">
<table style="border-collapse:collapse;width:110px;color:#99a;font-family:'Helvetica','Lucida Grande','Arial',sans-serif;"><tbody>
<!-- NEXT/PREV MONTH NAV AND MONTH INDICATOR -->
<tr style="width:110px;height:16px;font-size:10px!important;">
<td style="padding-right:9px;font-size:11px!important;font-weight:bold;text-transform:uppercase;text-align:right;white-space:nowrap;overflow:visible;" nowrap="nowrap">
<a href="http://web.archive.org/web/20061004083901/http://samhuri.net/" style="text-decoration:none;color:#33f;font-weight:bold;background-color:transparent;border:none;" title="4 Oct 2006"><strong>OCT</strong></a>
</td>
<td id="displayMonthEl" style="background:#000;color:#ff0;font-size:11px!important;font-weight:bold;text-transform:uppercase;width:34px;height:15px;padding-top:1px;text-align:center;" title="You are here: 5:50:04 Dec 5, 2006">DEC</td>
<td style="padding-left:9px;font-size:11px!important;font-weight:bold;text-transform:uppercase;white-space:nowrap;overflow:visible;" nowrap="nowrap">
Jan
</td>
</tr>
<!-- NEXT/PREV CAPTURE NAV AND DAY OF MONTH INDICATOR -->
<tr>
<td style="padding-right:9px;white-space:nowrap;overflow:visible;text-align:right!important;vertical-align:middle!important;" nowrap="nowrap">
<a href="http://web.archive.org/web/20061004083901/http://samhuri.net/" title="8:39:01 Oct 4, 2006" style="background-color:transparent;border:none;"><img src="http://staticweb.archive.org/images/toolbar/wm_tb_prv_on.png" alt="Previous capture" width="14" height="16" border="0" /></a>
</td>
<td id="displayDayEl" style="background:#000;color:#ff0;width:34px;height:24px;padding:2px 0 0 0;text-align:center;font-size:24px;font-weight: bold;" title="You are here: 5:50:04 Dec 5, 2006">5</td>
<td style="padding-left:9px;white-space:nowrap;overflow:visible;text-align:left!important;vertical-align:middle!important;" nowrap="nowrap">
<img src="http://staticweb.archive.org/images/toolbar/wm_tb_nxt_off.png" alt="Next capture" width="14" height="16" border="0"/>
</td>
</tr>
<!-- NEXT/PREV YEAR NAV AND YEAR INDICATOR -->
<tr style="width:110px;height:13px;font-size:9px!important;">
<td style="padding-right:9px;font-size:11px!important;font-weight: bold;text-align:right;white-space:nowrap;overflow:visible;" nowrap="nowrap">
2005
</td>
<td id="displayYearEl" style="background:#000;color:#ff0;font-size:11px!important;font-weight: bold;padding-top:1px;width:34px;height:13px;text-align:center;" title="You are here: 5:50:04 Dec 5, 2006">2006</td>
<td style="padding-left:9px;font-size:11px!important;font-weight: bold;white-space:nowrap;overflow:visible;" nowrap="nowrap">
2007
</td>
</tr>
</tbody></table>
</td>
</tr>
<tr>
<td style="vertical-align:middle;padding:0!important;">
<a href="http://wayback.archive.org/web/20061205055004*/http://samhuri.net/" style="color:#33f;font-size:11px;font-weight:bold;background-color:transparent;border:none;" title="See a list of every capture for this URL"><strong>7 captures</strong></a>
<div style="margin:0!important;padding:0!important;color:#666;font-size:9px;padding-top:2px!important;white-space:nowrap;" title="Timespan for captures of this URL">2 Apr 06 - 5 Dec 06</div>
</td>
<td style="padding:0!important;">
<a style="position:relative; white-space:nowrap; width:400px;height:27px;" href="" id="wm-graph-anchor">
<div id="wm-ipp-sparkline" style="position:relative; white-space:nowrap; width:400px;height:27px;background-color:#fff;cursor:pointer;border-right:1px solid #ccc;" title="Explore captures for this URL">
<img id="sparklineImgId" style="position:absolute; z-index:9012; top:0px; left:0px;"
onmouseover="showTrackers('inline');"
onmouseout="showTrackers('none');"
onmousemove="trackMouseMove(event,this)"
alt="sparklines"
width="400"
height="27"
border="0"
src="http://wayback.archive.org/jsp/graph.jsp?graphdata=400_27_1996:-1:000000000000_1997:-1:000000000000_1998:-1:000000000000_1999:-1:000000000000_2000:-1:000000000000_2001:-1:000000000000_2002:-1:000000000000_2003:-1:000000000000_2004:-1:000000000000_2005:-1:000000000000_2006:11:000101030101_2007:-1:000000000000_2008:-1:000000000000_2009:-1:000000000000_2010:-1:000000000000_2011:-1:000000000000"></img>
<img id="wbMouseTrackYearImg"
style="display:none; position:absolute; z-index:9010;"
width="25"
height="27"
border="0"
src="http://staticweb.archive.org/images/toolbar/transp-yellow-pixel.png"></img>
<img id="wbMouseTrackMonthImg"
style="display:none; position:absolute; z-index:9011; "
width="2"
height="27"
border="0"
src="http://staticweb.archive.org/images/toolbar/transp-red-pixel.png"></img>
</div>
</a>
</td>
</tr></tbody></table>
</td>
<td style="text-align:right;padding:5px;width:65px;font-size:11px!important;">
<a href="javascript:;" onclick="document.getElementById('wm-ipp').style.display='none';" style="display:block;padding-right:18px;background:url(http://staticweb.archive.org/images/toolbar/wm_tb_close.png) no-repeat 100% 0;color:#33f;font-family:'Lucida Grande','Arial',sans-serif;margin-bottom:23px;background-color:transparent;border:none;" title="Close the toolbar">Close</a>
<a href="http://faq.web.archive.org/" style="display:block;padding-right:18px;background:url(http://staticweb.archive.org/images/toolbar/wm_tb_help.png) no-repeat 100% 0;color:#33f;font-family:'Lucida Grande','Arial',sans-serif;background-color:transparent;border:none;" title="Get some help using the Wayback Machine">Help</a>
</td>
</tr></tbody></table>
</div>
</div>
<script type="text/javascript">
var wmDisclaimBanner = document.getElementById("wm-ipp");
if(wmDisclaimBanner != null) {
disclaimElement(wmDisclaimBanner);
}
</script>
<!-- END WAYBACK TOOLBAR INSERT -->
<p>samhuri.net</a>
</body>
</html>
<!--
FILE ARCHIVED ON 5:50:04 Dec 5, 2006 AND RETRIEVED FROM THE
INTERNET ARCHIVE ON 2:38:29 Aug 21, 2011.
JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
SECTION 108(a)(3)).
-->

35
public/f/german_keys.txt Normal file
View file

@ -0,0 +1,35 @@
DVORAK
------
§1234567890[]
±!@#$%^&*(){}
',.pyfgcrl/=
"<>PYFGCRL?+
aoeuidhtns-\
AOEUIDHTNS_|
`;qjkxbmwvz
~:QJKXBMWVZ
QWERTY
------
§12344567890-=
±!@#$%^&*()_+
qwertyuiop[]
QWERTYUIOP{}
asdfghjkl;'\
ASDFGHJKL:"|
`zxcvbnm,./
~ZXCVBNM<>?
QWERTZ (German)
---------------
^1234567890ß´
°!"§$%&/()=?`

View file

@ -0,0 +1,14 @@
#!/bin/sh
mkdir /tmp/gtkpod-fix
cd /tmp/gtkpod-fix
wget http://ftp.uni-kl.de/debian-multimedia/pool/main/libm/libmpeg4ip/libmp4v2-0_1.5.0.1-0.3_amd64.deb
wget http://ftp.uni-kl.de/debian-multimedia/pool/main/libm/libmpeg4ip/libmp4v2-dev_1.5.0.1-0.3_amd64.deb
wget http://ftp.uni-kl.de/debian-multimedia/pool/main/libm/libmpeg4ip/libmpeg4ip-0_1.5.0.1-0.3_amd64.deb
wget http://ftp.uni-kl.de/debian-multimedia/pool/main/libm/libmpeg4ip/libmpeg4ip-dev_1.5.0.1-0.3_amd64.deb
for f in *.deb; do sudo gdebi -n "$f"; done
svn co https://gtkpod.svn.sourceforge.net/svnroot/gtkpod/gtkpod/trunk gtkpod
cd gtkpod
./autogen.sh --with-mp4v2 && make && sudo make install
cd
rm -rf /tmp/gtkpod-fix

BIN
public/f/ims-demo.mov Normal file

Binary file not shown.

438
public/f/island.css Normal file
View file

@ -0,0 +1,438 @@
/* Island screen styles */
body {
font: 1em/1.15em "Hoefler Text", Georgia, "Adobe Garamond Pro", Palatino, "Times New Roman", serif;
color: #eee;
background: #000;
margin: 5px;
}
#leftcolumn {
width: 23%;
float: right;
margin: 0 10px 0 20px;
text-align: right;
}
#header {
/* text-align: center;*/
}
#content {
/* padding-top: 50px;*/
width: 72%;
float: left;
}
#main {
}
#search {
padding: 3px;
}
#sidebar {
}
#footer {
text-align: center;
/* background: #333;*/
border-top: 1px solid #666;
padding-bottom: 5px;
clear: both;
}
#footer a { border: none; }
#footer img { border: none; }
/*+-------------------------------------------+
| LINKS |
+-------------------------------------------+*/
a {
color: #5189ea;
text-decoration: none;
border-bottom: 1px dotted #3179ca;
padding-top: 2px;
}
a:hover {
background: #ffa;
color: #000;
}
/*+-------------------------------------------+
| UTILITY |
+-------------------------------------------+*/
h1, h2, h3, h4, h5, h6 {
margin: 0;
padding: 0;
}
form, div { padding: 0; margin: 0; }
p { margin: 0 0 1em 0; padding: 0; }
img {
border: 0;
padding: 5px;
}
/*+-------------------------------------------+
| HEADER |
+-------------------------------------------+*/
#header h1 {
margin-top: 30px;
font-size: 5em;
}
#header h1 a {
color: #ffa;
background: inherit;
text-decoration: none;
border-bottom: none;
}
#header h1 a:hover {
background: #000;
}
#header h2 {
color: #555;
padding-top: .2em;
font-size: 1.2em;
letter-spacing: 2px;
}
/*+-------------------------------------------+
| SEARCH |
+-------------------------------------------+*/
#sform {
padding-top: 15px;
}
#search-results {
text-align: left;
padding-bottom: 5px;
border-bottom: 1px dotted #666;
}
/*+-------------------------------------------+
| POST |
+-------------------------------------------+*/
.post {
padding: 10px 0 10px 0;
margin: 5px 0 15px 5px;
/* clear: left;*/
}
.post h2 {
font-size: 140%;
line-height: 1.4em;
margin: 5px 0;
/* padding-top: 15px;*/
}
.post h3 {
margin: 5px 0;
}
.post h2 a {
color: #fff;
text-decoration: none;
border: none;
}
.post h2 a:before {
content: '# ';
}
.post h2 a:hover {
color: #ffa;
background: #000;
}
.post p {
margin-left: 5px;
}
p.meta {
font-size: 75%;
text-align: right;
margin-right: 15px;
/* border-right: 1px solid #999;*/
/* float: left;*/
/* width: 75px;*/
}
p.auth {
font-size: 85%;
font-weight: bold;
color: #999;
}
/*+-------------------------------------------+
| COMMENTS |
+-------------------------------------------+*/
.comment-list li, #preview {
background: #666;
padding: 5px;
margin-bottom: 8px;
color: #eee;
/*border-right: 20px solid #d3e0ea;*/
min-height: 60px;
}
.gravatar {
float: right;
padding: 0 5px;
}
/*+-------------------------------------------+
| SIDEBAR |
+-------------------------------------------+*/
#sidebar h3 {
font-size: 110%;
line-height: 1.5em;
color: #ff9d47;
margin-top: 15px;
margin-bottom: 2px;
text-transform: lowercase;
}
#sidebar h3:before {
content: "<< ";
font-size: small;
}
#sidebar h3:after {
content: " >>";
font-size: small;
}
#sidebar h3 a {
color: #ff9d47;
border-bottom: 1px dotted #ff9d47;
}
#sidebar h3 a:hover {
color: #000;
background: #ffa;
}
#sidebar ul {
text-align: right;
margin: 0;
padding: 0;
list-style-type: none;
}
#sidebar ul li {
/* background: url(http://web.archive.org/web/20060321041209/http://sami.samhuri.net/images/theme/small_arrow.png) 45% no-repeat;*/
/* padding-left: 12px;*/
}
#sidebar a.feed,
#sidebar a.feed:link,
#sidebar a.feed:hover {
display: inline;
border: none;
background: #000;
}
/*+-------------------------------------------+
| FOOTER |
+-------------------------------------------+*/
#footer ul {
margin: 0;
padding: 10px 0 0 0;
list-style: none;
}
#footer ul li {
display: inline;
margin: 0;
padding: 0 5px 0 0;
font-size: 100%;
}
/*+-------------------------------------------+
| FORMS |
+-------------------------------------------+*/
input, textarea, select {
border: 1px solid #8ab3d1;
background: #f9f9f9;
}
.frm-tbl td { vertical-align: top; padding: 5px; }
td#frm-btns { text-align: right; }
#comment_body { height: 220px; }
#form-submit-button { background: #d3e0ea; }
/*+-------------------------------------------+
| MISC |
+-------------------------------------------+*/
.powered { border: none; }
.powered img { margin-top: 20px; }
.pullquote {
width: 30%;
float:right;
font: 150%/1.5em Times, Helvetica, "Times New Roman", serif;
color: #666;
margin:10px;
background: url(http://web.archive.org/web/20060321041209/http://sami.samhuri.net/images/theme/q-close.gif) no-repeat 70% 100% !important;
background /**/:url(); /* removing quote graphic in IE5+ */
padding: 0 25px 5px 0;
}
.pullquote:first-letter {
background: url(http://web.archive.org/web/20060321041209/http://sami.samhuri.net/images/theme/q-open.gif) no-repeat left top !important;
padding:5px 2px 10px 35px!important;
padding /**/:0px; /* resetting padding in IE5+ */
background /**/: url(); /* removing quote graphic in IE5+ */
}
.light-bg { background: #666; padding: 2px; }
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
#errors {
color: red;
}
.admintools {
float: right;
background-color: #fff;
font-size: smaller;
padding: 0 2px;
margin: 0 1px;
color: #ccc;
border: 1px solid #ccc;
}
.admintools:hover {
color: #c00;
border: 1px solid #c00;
}
a[name] { border: none; }
/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
/* End hide from IE-mac */
#categories li em, #archives li em
{
color: #98B4D1;
font-size: smaller;
}
/* Syntax highlighting */
.typocode_ruby .normal {}
.typocode_ruby .comment { color: #005; font-style: italic; }
.typocode_ruby .keyword { color: #A00; font-weight: bold; }
.typocode_ruby .method { color: #077; }
.typocode_ruby .class { color: #074; }
.typocode_ruby .module { color: #050; }
.typocode_ruby .punct { color: #447; font-weight: bold; }
.typocode_ruby .symbol { color: #099; }
.typocode_ruby .string { color: #944; background: #FFE; }
.typocode_ruby .char { color: #F07; }
.typocode_ruby .ident { color: #004; }
.typocode_ruby .constant { color: #07F; }
.typocode_ruby .regex { color: #B66; background: #FEF; }
.typocode_ruby .number { color: #F99; }
.typocode_ruby .attribute { color: #7BB; }
.typocode_ruby .global { color: #7FB; }
.typocode_ruby .expr { color: #227; }
.typocode_ruby .escape { color: #277; }
.typocode_xml .normal {}
.typocode_xml .namespace { color: #B66; font-weight: bold; }
.typocode_xml .tag { color: #F88; }
.typocode_xml .comment { color: #005; font-style: italic; }
.typocode_xml .punct { color: #447; font-weight: bold; }
.typocode_xml .string { color: #944; }
.typocode_xml .number { color: #F99; }
.typocode_xml .attribute { color: #BB7; }
.typocode_yaml .normal {}
.typocode_yaml .document { font-weight: bold; color: #07F; }
.typocode_yaml .type { font-weight: bold; color: #05C; }
.typocode_yaml .key { color: #F88; }
.typocode_yaml .comment { color: #005; font-style: italic; }
.typocode_yaml .punct { color: #447; font-weight: bold; }
.typocode_yaml .string { color: #944; }
.typocode_yaml .number { color: #F99; }
.typocode_yaml .time { color: #F99; }
.typocode_yaml .date { color: #F99; }
.typocode_yaml .ref { color: #944; }
.typocode_yaml .anchor { color: #944; }
.typocode {
background-color:#eee;
padding:2px;
margin:5px;
margin-left:1em;
margin-bottom:1em;
}
.typocode pre {
padding: 0px;
margin: 0px;
border: none;
background: transparent;
font-family: monospace;
overflow:auto;
}
.typocode .lineno {
text-align: right;
/* color: #B00;*/
font-family: monospace;
padding-right: 1em;
}
code {
font-family: "Andale Mono", "Lucida Typewriter", "Bitstream Vera Sans Mono", fixed-width, monospace;
/* font-size: 120%;*/
}
pre {
background: #555;
border: 1px dashed #5189ea;
margin-bottom: 30px;
margin-top: -10px;
padding: 5px;
}
/*+-------------------------------------------+
| TAGLIST |
+-------------------------------------------+*/
ul#taglist li {
display: inline;
line-height: 3em;
}
.tags .tags0 { font-size: 1.0em; }
.tags .tags1 { font-size: 1.2em; }
.tags .tags2 { font-size: 1.4em; }
.tags .tags3 { font-size: 1.6em; }
.tags .tags4 { font-size: 1.8em; }
.tags .tags5 { font-size: 2.0em; }
.tags .tags6 { font-size: 2.2em; }
.tags .tags7 { font-size: 2.4em; }
.tags .tags8 { font-size: 2.6em; }
.tags .tags9 { font-size: 2.8em; }
.tags .tags10 { font-size: 3.0em; }

BIN
public/f/menu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View file

@ -0,0 +1,81 @@
diff -Nupr mephisto_converters/lib/converters/typo/article.rb mephisto_converters-schema_61/lib/converters/typo/article.rb
--- mephisto_converters/lib/converters/typo/article.rb 2006-11-23 10:57:06.000000000 -0800
+++ mephisto_converters-schema_61/lib/converters/typo/article.rb 2007-05-26 01:54:19.000000000 -0700
@@ -1,7 +1,8 @@
module Typo
class Article < Content
- has_many :comments, :dependent => true, :order => "created_at ASC", :class_name => 'Typo::Comment'
+ has_many :comments, :dependent => :destroy, :order => "created_at ASC", :class_name => 'Typo::Comment'
has_and_belongs_to_many :tags, :class_name => 'Typo::Tag'
- has_and_belongs_to_many :categories, :class_name => 'Typo::Category'
+ has_many :categorizations, :class_name => 'Typo::Categorization'
+ has_many :categories, :class_name => 'Typo::Category', :through => :categorizations
end
end
diff -Nupr mephisto_converters/lib/converters/typo/categorization.rb mephisto_converters-schema_61/lib/converters/typo/categorization.rb
--- mephisto_converters/lib/converters/typo/categorization.rb 1969-12-31 16:00:00.000000000 -0800
+++ mephisto_converters-schema_61/lib/converters/typo/categorization.rb 2007-05-26 01:44:19.000000000 -0700
@@ -0,0 +1,7 @@
+module Typo
+ class Categorization < ActiveRecord::Base
+ establish_connection configurations['typo']
+ belongs_to :article, :class_name => 'Typo::Article'
+ belongs_to :category, :class_name => 'Typo::Category'
+ end
+end
diff -Nupr mephisto_converters/lib/converters/typo/category.rb mephisto_converters-schema_61/lib/converters/typo/category.rb
--- mephisto_converters/lib/converters/typo/category.rb 2006-11-23 10:57:06.000000000 -0800
+++ mephisto_converters-schema_61/lib/converters/typo/category.rb 2007-05-26 01:42:02.000000000 -0700
@@ -1,6 +1,7 @@
module Typo
class Category < ActiveRecord::Base
establish_connection configurations['typo']
- has_and_belongs_to_many :articles, :class_name => 'Typo::Article'
+ has_many :categorizations, :class_name => 'Typo::Categorization'
+ has_many :articles, :class_name => 'Typo::Article', :through => :categorizations
end
end
diff -Nupr mephisto_converters/lib/converters/typo/comment.rb mephisto_converters-schema_61/lib/converters/typo/comment.rb
--- mephisto_converters/lib/converters/typo/comment.rb 2006-11-23 10:57:06.000000000 -0800
+++ mephisto_converters-schema_61/lib/converters/typo/comment.rb 2007-05-26 01:54:30.000000000 -0700
@@ -1,5 +1,7 @@
module Typo
- class Comment < Content
-# belongs_to :article, :foreign_key => 'parentid', :class_name => 'Typo::Comment'
+ class Comment < Feedback
+ establish_connection configurations['typo']
+ belongs_to :article, :class_name => 'Typo::Article'
+ belongs_to :user, :class_name => 'Typo::User'
end
end
diff -Nupr mephisto_converters/lib/converters/typo/feedback.rb mephisto_converters-schema_61/lib/converters/typo/feedback.rb
--- mephisto_converters/lib/converters/typo/feedback.rb 1969-12-31 16:00:00.000000000 -0800
+++ mephisto_converters-schema_61/lib/converters/typo/feedback.rb 2007-05-26 01:55:28.000000000 -0700
@@ -0,0 +1,6 @@
+module Typo
+ class Feedback < Content
+ set_table_name 'feedback'
+ establish_connection configurations['typo']
+ end
+end
diff -Nupr mephisto_converters/lib/converters/typo.rb mephisto_converters-schema_61/lib/converters/typo.rb
--- mephisto_converters/lib/converters/typo.rb 2006-11-23 10:57:06.000000000 -0800
+++ mephisto_converters-schema_61/lib/converters/typo.rb 2007-05-26 01:53:14.000000000 -0700
@@ -1,8 +1,10 @@
require 'converters/typo/content'
require 'converters/typo/page'
require 'converters/typo/article'
+require 'converters/typo/feedback'
require 'converters/typo/comment'
require 'converters/typo/category'
+require 'converters/typo/categorization'
require 'converters/typo/user'
require 'converters/typo/tag'
@@ -77,4 +79,4 @@ class TypoConverter < BaseConverter
memo << (sections[::Section.permalink_for(cat.name)] || site.sections.create(:name => cat.name)).id
end
end
-end
\ No newline at end of file
+end

29
public/f/note.html Normal file
View file

@ -0,0 +1,29 @@
<!doctype html>
<html lang="en">
<style>
html,body { height: 100% }
#note { width: 100%; height: 100% }
</style>
<script>
var note, html, timeout;
window.addEventListener('load', function() {
note = document.getElementById('note');
html = document.getElementsByTagName('html')[0];
html.addEventListener('keyup', function(ev) {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(saveNote, 100);
});
restoreNote();
note.focus();
});
function saveNote() {
localStorage.note = note.innerText;
timeout = null;
}
function restoreNote() {
note.innerText = localStorage.note || '';
}
</script>
<h1>Notepad (type below, notes persist)</h1>
<p id="note" contenteditable></p>
</html>

BIN
public/f/pacman-tones.zip Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/f/spinner-blue.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
public/f/spinner.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

34
public/f/tagify.el Normal file
View file

@ -0,0 +1,34 @@
(defun wrap-region (left right)
"Wrap the region in arbitrary text, LEFT goes to the left and RIGHT goes to the right."
(interactive)
(let ((beg (region-beginning))
(end (region-end)))
(goto-char beg)
(insert left)
(goto-char (+ end (length left)))
(insert right)
(goto-char (+ end (length left) (length right)))))
(defun tagify-region-or-insert-self (arg)
"If there is a visible region, call `tagify-region-or-insert', otherwise
call `self-insert-command' passing it any prefix arg given."
(interactive "*P")
(if (and mark-active transient-mark-mode)
(call-interactively 'tagify-region-or-insert-tag)
(self-insert-command (prefix-numeric-value arg))))
(defun tagify-region-or-insert-tag (tag)
"If there is a visible region, wrap it in the given HTML/XML tag using
`wrap-region'. If any attributes are specified then they are only included
in the opening tag.
Otherwise insert the opening and closing tags and position point between the two."
(interactive "*sTag (including attributes): \n")
(let* ((open (concat "<" tag ">"))
(close (concat "</" (car (split-string tag " ")) ">")))
(if (and mark-active transient-mark-mode)
(wrap-region open close)
(insert (concat open close))
(backward-char (length close)))))
(provide 'tagify)

21
public/f/volume.rb Normal file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env ruby
Ops = {
:+ => [lambda { |x| x + 5 > 100 ? 100 : x + 5 }, "increased"],
:- => [lambda { |x| x - 5 < 0 ? 0 : x - 5 } , "decreased"]
}
def vol_op id, vol
[Ops[id].first.call(vol), Ops[id].last]
end
op = ARGV.shift.to_sym
unless Ops.keys.include?(op)
raise "#{op} is not a valid argument. Expected one of: #{Ops.keys.join(', ')}."
else
`amixer get Master`.split("\n").grep(/%/).first =~ /\[(\d+)/
vol = $1.to_i
new_vol, action = *vol_op(op, vol)
system("amixer set Master #{new_vol}%")
system("notify-send --urgency=low --icon=~/.icons/audio-volume-medium.gif --expire-time=500 \"Volume #{action}\" \"#{new_vol}%\"")
end

49
public/f/wrap-region.el Normal file
View file

@ -0,0 +1,49 @@
;; help out a TextMate junkie
(defun wrap-region (left right beg end)
"Wrap the region in arbitrary text, LEFT goes to the left and RIGHT goes to the right."
(interactive)
(save-excursion
(goto-char beg)
(insert left)
(goto-char (+ end (length left)))
(insert right)))
(defmacro wrap-region-with-function (left right)
"Returns a function which, when called, will interactively `wrap-region-or-insert' using LEFT and RIGHT."
`(lambda () (interactive)
(wrap-region-or-insert ,left ,right)))
(defun wrap-region-with-tag-or-insert ()
(interactive)
(if (and mark-active transient-mark-mode)
(call-interactively 'wrap-region-with-tag)
(insert "<")))
(defun wrap-region-with-tag (tag beg end)
"Wrap the region in the given HTML/XML tag using `wrap-region'. If any
attributes are specified then they are only included in the opening tag."
(interactive "*sTag (including attributes): \nr")
(let* ((elems (split-string tag " "))
(tag-name (car elems))
(right (concat "</" tag-name ">")))
(if (= 1 (length elems))
(wrap-region (concat "<" tag-name ">") right beg end)
(wrap-region (concat "<" tag ">") right beg end))))
(defun wrap-region-or-insert (left right)
"Wrap the region with `wrap-region' if an active region is marked, otherwise insert LEFT at point."
(interactive)
(if (and mark-active transient-mark-mode)
(wrap-region left right (region-beginning) (region-end))
(insert left)))
(global-set-key "'" (wrap-region-with-function "'" "'"))
(global-set-key "\"" (wrap-region-with-function "\"" "\""))
(global-set-key "`" (wrap-region-with-function "`" "`"))
(global-set-key "(" (wrap-region-with-function "(" ")"))
(global-set-key "[" (wrap-region-with-function "[" "]"))
(global-set-key "{" (wrap-region-with-function "{" "}"))
(global-set-key "<" 'wrap-region-with-tag-or-insert) ;; I opted not to have a wrap-with-angle-brackets
(provide 'wrap-region)

BIN
public/f/zelda-tones.zip Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

BIN
public/images/blog/menu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

766
public/js/gitter.js Normal file
View file

@ -0,0 +1,766 @@
/// gitter
/// http://github.com/samsonjs/gitter
/// @_sjs
///
/// Copyright 2010 - 2012 Sami Samhuri <sami@samhuri.net>
/// MIT License
(function() {
"use strict"
var global = (function() { return this || (1, eval)('this') }())
, isBrowser = 'document' in global
, ie
if (isBrowser) {
ie = (function() {
var undef
, v = 3
, div = document.createElement('div')
, all = div.getElementsByTagName('i')
while (
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
all[0]
);
return v > 4 ? v : undef
}())
}
var inherits
if ('create' in Object) {
// util.inherits from node
inherits = function(ctor, superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false
}
})
}
}
else if ([].__proto__) {
inherits = function(ctor, superCtor) {
ctor.super_ = superCtor
ctor.prototype.__proto__ = superCtor.prototype
ctor.prototype.constructor = ctor
}
}
else { // ie8
var __hasProp = Object.prototype.hasOwnProperty
inherits = function(child, parent) {
for (var key in parent) {
if (__hasProp.call(parent, key)) child[key] = parent[key]
}
function ctor() { this.constructor = child }
ctor.prototype = parent.prototype
child.prototype = new ctor
child.__super__ = parent.prototype
return child
}
}
var api = {
// Blob
blob: function(user, repo, sha, cb) {
return new Blob(user, repo, sha, cb)
}
// Branch
, branch: function(user, repo, name, cb) {
return new Branch(user, repo, name, cb)
}
// Commit
, commit: function(user, repo, sha, cb) {
return new Commit(user, repo, sha, cb)
}
// Download
, download: function(user, repo, id, cb) {
return new Download(user, repo, id, cb)
}
// Issue
, issue: function(user, repo, id, cb) {
return new Issue(user, repo, id, cb)
}
// Organization
, org: function(name, cb) {
return new Org(name, cb)
}
, members: function(name, cb) {
return new Org(name).fetchMembers(cb)
}
// Repo
, repo: function(user, repo, cb) {
return new Repo(user, repo, cb)
}
, branches: function(user, repo, cb) {
return new Repo(user, repo).fetchBranches(cb)
}
, collaborators: function(user, repo, cb) {
return new Repo(user, repo).fetchCollaborators(cb)
}
, contributors: function(user, repo, cb) {
return new Repo(user, repo).fetchContributors(cb)
}
, downloads: function(user, repo, cb) {
return new Repo(user, repo).fetchDownloads(cb)
}
, forks: function(user, repo, cb) {
return new Repo(user, repo).fetchForks(cb)
}
, issues: function(user, repo, cb) {
return new Repo(user, repo).fetchIssues(cb)
}
, languages: function(user, repo, cb) {
return new Repo(user, repo).fetchLanguages(cb)
}
, tags: function(user, repo, cb) {
return new Repo(user, repo).fetchTags(cb)
}
, watchers: function(user, repo, cb) {
return new Repo(user, repo).fetchWatchers(cb)
}
, ref: function(user, repo, name, cb) {
return new Ref(user, repo, name, cb)
}
// Tag
, tag: function(user, repo, name, cb) {
return new Tag(user, repo, name, cb)
}
// Tree
, tree: function(user, repo, sha, cb) {
return new Tree(user, repo, sha, cb)
}
// User
, user: function(login, cb) {
return new User(login, cb)
}
, followers: function(login, cb) {
return new User(login).fetchFollowers(cb)
}
, following: function(login, cb) {
return new User(login).fetchFollowing(cb)
}
, repos: function(login, cb) {
return new User(login).fetchRepos(cb)
}
, watched: function(login, cb) {
return new User(login).fetchWatched(cb)
}
// Why not, expose the resources directly as well.
, Blob: Blob
, Branch: Branch
, Commit: Commit
, Download: Download
, Issue: Issue
, Org: Org
, Ref: Ref
, Repo: Repo
, Tree: Tree
, User: User
}
// when running in the browser request is set later, in shim()
var request
if (isBrowser) {
shim()
global.GITR = api
}
else {
var https = require('https')
request = function(options, cb) {
var req = https.request(options, function(response) {
var bodyParts = []
response.on('data', function(b) { bodyParts.push(b) })
response.on('end', function() {
var body = bodyParts.join('')
if (response.statusCode === 200) {
cb(null, body, response)
}
else {
console.dir(options, response, body)
var err = new Error('http error')
err.statusCode = response.statusCode
err.body = body
cb(err)
}
})
})
req.end()
req.on('error', function(err) { cb(err) })
}
module.exports = api
}
// Generic Resource //
//
// Used as the prototype by createResource. Provides
// methods for fetching the resource and related
// sub-resources.
function Resource() {}
// Fetch data for this resource and pass it to the
// callback after mixing the data into the object.
// Data is also available via the `data` property.
Resource.prototype.fetch = function(cb) {
if (this.data) {
cb(null, this.data)
}
else {
var self = this
fetch(this.path, function(err, data) {
// console.log('FETCH', self.path, err, data)
if (err) {
// console.log(err)
}
else {
self.data = data
mixin(self, data)
}
if (typeof cb === 'function') {
cb.call(self, err, data)
}
})
}
return this
}
Resource.prototype.fetchSubResource = function(thing, cb) {
if (this['_' + thing]) {
cb(null, this['_' + thing])
}
else {
var self = this
fetch(this.path + '/' + thing, function(err, data) {
// console.log('FETCH SUBRESOURCE', self.path, thing, err, data)
if (err) {
// console.log(self.path, err)
}
else {
self['_' + thing] = data
}
if (typeof cb === 'function') {
cb.call(self, err, data)
}
})
}
return this
}
var __slice = Array.prototype.slice
// Create a resource w/ Resource as the prototype.
//
// spec: an object with the following properties:
//
// - constructor: a constructor function
// - has: a list of resources belonging to this resource
//
// Typically the constructor accepts one or more arguments specifying
// the name or pieces of info identifying the specific resource and
// used to build the URL to fetch it. It also accepts an optional
// callback as the last parameter.
//
// The constructor must set the `path` property which is used to
// fetch the resource.
//
// If a callback is provided then the resource is immediately
// fetched and the callback is threaded through to the `fetch`
// method. The callback function has the signature
// `function(err, data)`.
//
// The `has` list specifies sub-resources, e.g. a user has repos,
// followers, etc. An organization has members.
//
// Each related sub-resource gets a method named appropriately,
// e.g. the User resource has followers so User objects have a
// `fetchFollowers` method.
function createResource(spec) {
var subResources = spec.has ? __slice.call(spec.has) : null
, resource = function(/* ..., cb */) {
var args = __slice.call(arguments)
, lastArgIsCallback = typeof args[args.length - 1] === 'function'
, cb = lastArgIsCallback ? args.pop() : null
, result = spec.constructor.apply(this, args)
if (typeof cb === 'function') {
this.fetch(cb)
}
return result
}
inherits(resource, Resource)
if (subResources) {
subResources.forEach(function(thing) {
var fnName = 'fetch' + toTitleCase(thing)
resource.prototype[fnName] = function(cb) {
return this.fetchSubResource(thing, cb)
}
})
}
return resource
}
// Define Resources //
var Blob = createResource({
constructor: function(user, repo, sha) {
this.user = user
this.repo = repo
this.sha = sha
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/git/blobs/' + sha
}
})
var Branch = createResource({
constructor: function (user, repo, name) {
this.user = user
this.repo = repo
this.name = name
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/git/refs/heads/' + name
}
})
var Commit = createResource({
constructor: function Commit(user, repo, sha) {
this.user = user
this.repo = repo
this.sha = sha
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/git/commits/' + sha
}
})
var Download = createResource({
constructor: function(user, repo, id) {
this.user = user
this.repo = repo
this.id = id
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/downloads/' + id
}
})
var Issue = createResource({
constructor: function(user, repo, id) {
this.user = user
this.repo = repo
this.id = id
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/issues/' + id
}
})
var Org = createResource({
constructor: function(name) {
this.name = name
this.path = '/orgs/' + encodeURIComponent(nam)
}
, has: 'members repos'.split(' ')
})
var Ref = createResource({
constructor: function (user, repo, name) {
this.user = user
this.repo = repo
this.name = name
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/git/refs/' + name
}
})
var Repo = createResource({
constructor: function(user, repo) {
this.user = user
this.repo = repo
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/')
}
, has: ('branches collaborators contributors downloads' +
' forks languages tags teams watchers').split(' ')
})
var Tag = createResource({
constructor: function (user, repo, name) {
this.user = user
this.repo = repo
this.name = name
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/git/refs/tags/' + name
}
})
var Tree = createResource({
constructor: function(user, repo, sha) {
this.user = user
this.repo = repo
this.sha = sha
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/git/trees/' + sha
}
})
var User = createResource({
constructor: function(login) {
// Allow creating a user from an object returned by the API
if (login.login) {
login = login.login
}
this.login = login
this.path = '/users/' + encodeURIComponent(login)
}
, has: 'followers following repos watched'.split(' ')
})
// Fetch data from github. JSON is parsed and keys are camelized.
//
// path: the path to the resource
// cb: callback(err, data)
function fetch(path, cb) {
request({ host: 'api.github.com', path: path }, function(err, body, response) {
// JSONP requests in the browser return the object directly
var data = body
// Requests in Node return json text, try to parse it
if (response && /json/i.exec(response.headers['content-type'])) {
try {
data = JSON.parse(body)
}
catch (e) {
err = e
data = null
}
}
cb(err, camelize(data))
})
}
// created_at => createdAt
function camel(s) {
return s.replace(/_(.)/g, function(_, l) { return l.toUpperCase() })
}
// camelize all keys of an object, or all objects in an array
function camelize(obj) {
if (!obj || typeof obj === 'string') return obj
if (Array.isArray(obj)) return obj.map(camelize)
if (typeof obj === 'object') {
return Object.keys(obj).reduce(function(camelizedObj, k) {
camelizedObj[camel(k)] = camelize(obj[k])
return camelizedObj
}, {})
}
return obj
}
function toTitleCase(s) {
return s.charAt(0).toUpperCase() + s.slice(1)
}
function mixin(a, b) {
for (var k in b) {
if (b.hasOwnProperty(k)) a[k] = b[k]
}
}
// Browser Utilities //
function shim() {
shimBind()
shimES5()
shimRequest()
}
function shimBind() {
// bind from Prototype
if (!Function.prototype.bind) {
(function(){
function update(array, args) {
var arrayLength = array.length, length = args.length
while (length--) array[arrayLength + length] = args[length]
return array
}
function merge(array, args) {
array = __slice.call(array, 0)
return update(array, args)
}
Function.prototype.bind = function(context) {
if (arguments.length < 2 && typeof arguments[0] === 'undefined') return this
var __method = this, args = __slice.call(arguments, 1)
return function() {
var a = merge(args, arguments)
return __method.apply(context, a)
}
}
}())
}
}
// a few functions from Kris Kowal's es5-shim
// https://github.com/kriskowal/es5-shim
function shimES5() {
var has = Object.prototype.hasOwnProperty
// ES5 15.2.3.6
if (!Object.defineProperty || ie === 8) { // ie8
Object.defineProperty = function(object, property, descriptor) {
if (typeof descriptor == "object" && object.__defineGetter__) {
if (has.call(descriptor, "value")) {
if (!object.__lookupGetter__(property) && !object.__lookupSetter__(property)) {
// data property defined and no pre-existing accessors
object[property] = descriptor.value
}
if (has.call(descriptor, "get") || has.call(descriptor, "set")) {
// descriptor has a value property but accessor already exists
throw new TypeError("Object doesn't support this action")
}
}
// fail silently if "writable", "enumerable", or "configurable"
// are requested but not supported
else if (typeof descriptor.get == "function") {
object.__defineGetter__(property, descriptor.get)
}
if (typeof descriptor.set == "function") {
object.__defineSetter__(property, descriptor.set)
}
}
return object
}
}
// ES5 15.2.3.14
// http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
if (!Object.keys) { // ie8
(function() {
var hasDontEnumBug = true,
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length
for (var key in {"toString": null}) {
hasDontEnumBug = false
}
Object.keys = function (object) {
if (
typeof object !== "object" && typeof object !== "function"
|| object === null
)
throw new TypeError("Object.keys called on a non-object")
var keys = []
for (var name in object) {
if (has.call(object, name)) {
keys.push(name)
}
}
if (hasDontEnumBug) {
for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
var dontEnum = dontEnums[i]
if (has.call(object, dontEnum)) {
keys.push(dontEnum)
}
}
}
return keys
}
}())
} // Object.keys
//
// Array
// =====
//
// ES5 15.4.3.2
if (!Array.isArray) {
Array.isArray = function(obj) {
return Object.prototype.toString.call(obj) == "[object Array]"
}
}
// ES5 15.4.4.18
if (!Array.prototype.forEach) { // ie8
Array.prototype.forEach = function(block, thisObject) {
var len = this.length >>> 0
for (var i = 0; i < len; i++) {
if (i in this) {
block.call(thisObject, this[i], i, this)
}
}
}
}
// ES5 15.4.4.19
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
if (!Array.prototype.map) { // ie8
Array.prototype.map = function(fun /*, thisp*/) {
var len = this.length >>> 0
if (typeof fun != "function") {
throw new TypeError()
}
var res = new Array(len)
var thisp = arguments[1]
for (var i = 0; i < len; i++) {
if (i in this) {
res[i] = fun.call(thisp, this[i], i, this)
}
}
return res
}
}
// ES5 15.4.4.20
if (!Array.prototype.filter) { // ie8
Array.prototype.filter = function (block /*, thisp */) {
var values = []
, thisp = arguments[1]
for (var i = 0; i < this.length; i++) {
if (block.call(thisp, this[i])) {
values.push(this[i])
}
}
return values
}
}
// ES5 15.4.4.21
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
if (!Array.prototype.reduce) { // ie8
Array.prototype.reduce = function(fun /*, initial*/) {
var len = this.length >>> 0
if (typeof fun != "function") {
throw new TypeError()
}
// no value to return if no initial value and an empty array
if (len == 0 && arguments.length == 1) {
throw new TypeError()
}
var i = 0
if (arguments.length >= 2) {
var rv = arguments[1]
} else {
do {
if (i in this) {
rv = this[i++]
break
}
// if array contains no values, no initial value to return
if (++i >= len) {
throw new TypeError()
}
} while (true)
}
for (; i < len; i++) {
if (i in this) {
rv = fun.call(null, rv, this[i], i, this)
}
}
return rv
}
} // Array.prototype.reduce
} // function shimES5()
// jsonp request, quacks like node's http.request
function shimRequest() {
var load, _jsonpCounter = 1
// request is declared earlier
request = function(options, cb) {
var jsonpCallbackName = '_jsonpCallback' + _jsonpCounter++
, url = 'https://' + options.host + options.path + '?callback=GITR.' + jsonpCallbackName
GITR[jsonpCallbackName] = function(response) {
if (response.meta.status >= 200 && response.meta.status < 300) {
cb(null, response.data)
}
else {
var err = new Error('http error')
err.statusCode = response.meta.status
err.response = response
cb(err)
}
setTimeout(function() { delete GITR[jsonpCallbackName] }, 0)
}
load(url)
}
// bootstrap loader from LABjs (load is declared earlier)
load = function(url) {
var oDOC = document
, handler
, head = oDOC.head || oDOC.getElementsByTagName("head")
// loading code borrowed directly from LABjs itself
// (now removes script elem when done and nullifies its reference --sjs)
setTimeout(function () {
if ("item" in head) { // check if ref is still a live node list
if (!head[0]) { // append_to node not yet ready
setTimeout(arguments.callee, 25)
return
}
head = head[0]; // reassign from live node list ref to pure node ref -- avoids nasty IE bug where changes to DOM invalidate live node lists
}
var scriptElem = oDOC.createElement("script")
, scriptdone = false
scriptElem.onload = scriptElem.onreadystatechange = function () {
if ((scriptElem.readyState && scriptElem.readyState !== "complete" && scriptElem.readyState !== "loaded") || scriptdone) {
return false
}
scriptElem.onload = scriptElem.onreadystatechange = null
scriptElem.parentNode.removeChild(scriptElem)
scriptElem = null
scriptdone = true
}
scriptElem.src = url
head.insertBefore(scriptElem, head.firstChild)
}, 0) // setTimeout
// required: shim for FF <= 3.5 not having document.readyState
if (oDOC.readyState == null && oDOC.addEventListener) {
oDOC.readyState = "loading"
oDOC.addEventListener("DOMContentLoaded", function handler() {
oDOC.removeEventListener("DOMContentLoaded", handler, false)
oDOC.readyState = "complete"
}, false)
}
} // function load(url)
} // function shimRequest()
}())

137
public/js/projects.js Normal file
View file

@ -0,0 +1,137 @@
;(function() {
if (typeof console === 'undefined') {
console = {log:function(){}}
}
var global = this
global.SJS = {
proj: function(name) {
SJS.projName = name
var data = createObjectStore(name)
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', ready, false)
} else if (window.attachEvent) {
window.attachEvent('onload', ready)
}
function ready() {
function addClass(el, name) {
var c = el.className || name
if (!c.match(new RegExp('\b' + name + '\b', 'i'))) c += ' ' + name
}
function html(id, h) {
document.getElementById(id).innerHTML = h
}
var body = document.getElementsByTagName('body')[0]
, text
if ('innerText' in body) {
text = function(id, text) {
document.getElementById(id).innerText = text
}
} else {
text = function(id, text) {
document.getElementById(id).textContent = text
}
}
function highlight(id) {
document.getElementById(id).style.className = ' highlight'
}
function textHighlight(id, t) {
text(id, t)
document.getElementById(id).className = ' highlight'
}
function hide(id) {
document.getElementById(id).style.display = 'none'
}
function langsByUsage(langs) {
return Object.keys(langs).sort(function(a, b) {
return langs[a] < langs[b] ? -1 : 1
})
}
function listify(things) {
return '<ul><li>' + things.join('</li><li>') + '</li></ul>'
}
function updateBranches(name, branches) {
function branchLink(b) {
return '<a href=https://github.com/samsonjs/' + name + '/tree/' + b.name + '>' + b.name + '</a>'
}
html('branches', listify(branches.map(branchLink)))
}
function updateContributors(contributors) {
function userLink(u) {
return '<a href=https://github.com/' + u.login + '>' + (u.name || u.login) + '</a>'
}
html('contributors', listify(contributors.map(userLink)))
}
function updateLangs(langs) {
html('langs', listify(langsByUsage(langs)))
}
function updateN(name, things) {
textHighlight('n' + name, things.length)
if (things.length === 1) hide(name.charAt(0) + 'plural')
}
var t = data.get('t-' + name)
if (!t || +new Date() - t > 3600 * 1000) {
console.log('stale ' + String(t))
data.set('t-' + name, +new Date())
GITR.repo('samsonjs', name)
.fetchBranches(function(err, branches) {
if (err) {
text('branches', '(oops)')
} else {
data.set('branches', branches)
updateBranches(name, branches)
}
})
.fetchLanguages(function(err, langs) {
if (err) {
text('langs', '(oops)')
return
}
data.set('langs', langs)
updateLangs(langs)
})
.fetchContributors(function(err, users) {
if (err) {
text('contributors', '(oops)')
} else {
data.set('contributors', users)
updateContributors(users)
}
})
.fetchWatchers(function(err, users) {
if (err) {
text('nwatchers', '?')
} else {
data.set('watchers', users)
updateN('watchers', users)
}
})
.fetchForks(function(err, repos) {
if (err) {
text('nforks', '?')
} else {
data.set('forks', repos)
updateN('forks', repos)
}
})
} else {
console.log('hit ' + t + ' (' + (+new Date() - t) + ')')
updateBranches(name, data.get('branches'))
updateLangs(data.get('langs'))
updateContributors(data.get('contributors'))
updateN('watchers', data.get('watchers'))
updateN('forks', data.get('forks'))
}
}
}
}
}());

View file

@ -0,0 +1,92 @@
if (!window.localStorage || !window.sessionStorage) (function () {
var Storage = function (type) {
function createCookie(name, value, days) {
var date, expires;
if (days) {
date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
expires = "; expires="+date.toGMTString();
} else {
expires = "";
}
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=",
ca = document.cookie.split(';'),
i, c;
for (i=0; i < ca.length; i++) {
c = ca[i];
while (c.charAt(0)==' ') {
c = c.substring(1,c.length);
}
if (c.indexOf(nameEQ) == 0) {
return c.substring(nameEQ.length,c.length);
}
}
return null;
}
function setData(data) {
data = JSON.stringify(data);
if (type == 'session') {
window.top.name = data;
} else {
createCookie('localStorage', data, 365);
}
}
function clearData() {
if (type == 'session') {
window.top.name = '';
} else {
createCookie('localStorage', '', 365);
}
}
function getData() {
var data = type == 'session' ? window.top.name : readCookie('localStorage');
return data ? JSON.parse(data) : {};
}
// initialise if there's already data
var data = getData();
return {
clear: function () {
data = {};
clearData();
},
getItem: function (key) {
return data[key] || null;
},
key: function (i) {
// not perfect, but works
var ctr = 0;
for (var k in data) {
if (ctr == i) return k;
else ctr++;
}
return null;
},
removeItem: function (key) {
delete data[key];
setData(data);
},
setItem: function (key, value) {
data[key] = value+''; // forces the value to a string
setData(data);
}
};
};
if (!window.localStorage) window.localStorage = new Storage('local');
if (!window.sessionStorage) window.sessionStorage = new Storage('session');
}());

51
public/js/store.js Normal file
View file

@ -0,0 +1,51 @@
;(function() {
var global = this
if (typeof localStorage !== 'undefined') {
global.createObjectStore = function(namespace) {
function makeKey(k) {
return '--' + namespace + '-' + (k || '')
}
return {
clear: function() {
var i = localStorage.length
, k
, prefix = new RegExp('^' + makeKey())
while (--i) {
k = localStorage.key(i)
if (k.match(prefix)) {
localStorage.remove(k)
}
}
},
get: function(key) {
var val = localStorage[makeKey(key)]
try {
while (typeof val === 'string') val = JSON.parse(val)
} catch (e) {
//console.log('string?')
}
return val
},
set: function(key, val) {
localStorage[makeKey(key)] = typeof val === 'string' ? val : JSON.stringify(val)
},
remove: function(key) {
delete localStorage[makeKey(key)]
}
}
}
global.ObjectStore = createObjectStore('default')
} else {
// Create an in-memory store, should probably fall back to cookies
global.createObjectStore = function() {
var store = {}
return {
clear: function() { store = {} },
get: function(key) { return store[key] },
set: function(key, val) { store[key] = val },
remove: function(key) { delete store[key] }
}
}
global.ObjectStore = createObjectStore()
}
}());