var is_iphone = (navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))
var is_ipad = (navigator.userAgent.match(/iPad/i))
var is_android = (navigator.userAgent.match(/Android/i))
var is_mobile = is_iphone || is_ipad || is_android
var is_desktop = ! is_mobile;
document.body.classList.add(is_desktop ? 'desktop' : 'mobile');
function choice(a){ return a[randint(a.length)] }
function csrf() {
return $("[name=_csrf]").attr("value")
}
function bold_terms (s, terms) {
s = sanitize(s)
terms.forEach( (term) => {
s = s.replace(new RegExp(term, "ig"), "" + term + "")
})
return s
}
function querystring(opt){
return '?' + Object.keys(opt).map((key) => {
return encodeURIComponent(key) + "=" + encodeURIComponent(opt[key])
}).join("&")
}
function commatize (n, radix) {
radix = radix || 1024
var nums = [], i, counter = 0, r = Math.floor
if (n > radix) {
n /= radix
nums.unshift(r((n * 10) % 10))
nums.unshift(".")
}
do {
i = n % 10
n = r(n / 10)
if (n && ! (++counter % 3))
{ i = ' ' + r(i) }
nums.unshift(r(i))
}
while (n)
return nums.join("")
}
function privacy_dot (p) {
if (! p) return "·"
else return ".:"
}
var short_months = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" ")
function verbose_date (date, no_pad_hours) {
var date = new Date(date * 1000)
var d = date.getDate()
var m = date.getMinutes()
var h = date.getHours()
var meridian
if (h == 0) {
h = 12
meridian = " am"
}
else if (h == 12) {
meridian = " pm"
}
else if (h > 12) {
h -= 12
meridian = " pm"
}
else {
meridian = " am"
}
if (d < 10) d = "0" + d
if (m < 10) m = "0" + m
if (! no_pad_hours && h < 10) h = "0" + h
// non-breaking hyphen: ‑
var date = d + ' ' + short_months[date.getMonth()] + ' ' + date.getFullYear()
var time = h + ':' + m + meridian
return [date, time]
}
function carbon_date (date, no_bold) {
var span = (+new Date() / 1000 - date)
if (! no_bold && span < 86400) // modified today
{ color = "new" }
else if (span < 604800) // modifed this week
{ color = "recent" }
else if (span < 1209600) // modifed 2 weeks ago
{ color = "med" }
else if (span < 3024000) // modifed 5 weeks ago
{ color = "old" }
else if (span < 12315200) // modifed 6 months ago
{ color = "older" }
else
{ color = "quiet" }
return color
}
function hush_views (n, bias, no_bold) {
var txt = commatize(n, 1000)
bias = bias || 1
n = n || 0
if (n < 30) { return["quiet", n + " v."] }
if (n < 200) { return ["quiet", txt + " v."] }
else if (n < 500) { return ["quiet", txt + " v."] }
else if (n < 1000) { return ["old", txt + " v."] }
else if (n < 5000) { return ["med", txt + " kv."] }
else if (no_bold || n < 10000) { return ["recent", txt + " kv."] }
else { return ["new", txt + " kv."] }
}
function hush_threads (n, bias, no_bold) {
var txt = commatize(n, 1000)
bias = bias || 1
n = n || 0
if (n < 10) { return["quiet", n + " t."] }
else if (n < 25) { return ["old", txt + " t."] }
else if (n < 50) { return ["med", txt + " t."] }
else if (no_bold || n < 100) { return ["recent", txt + " t."] }
else { return ["new", txt + " t."] }
}
function hush_size (n, bias, no_bold) {
var txt = commatize(Math.floor(n / 1024))
bias = 1 || bias
n = n || 0
if (n < 1024) {
return ["quiet", n + " b."]
}
if (n < 1024*1024) {
return ["quiet", txt + " kb."]
}
else if (n < (20000000/bias)) {
return ["quiet", txt + " mb."]
}
else if (n < (50000000/bias)) {
return ["old", txt + " mb."]
}
else if (n < (80000000/bias)) {
return ["med", txt + " mb."]
}
else if (no_bold || n < (170000000/bias)) {
return ["recent", txt + " mb."]
}
else {
return ["new", txt + " mb."]
}
}
function hush_null (n, unit, no_bold) {
var s = unit ? n + " " + unit + "." : n
if (n < 3) {
return ["quiet", s]
}
else if (n < 6) {
return ["older", s]
}
else if (n < 10) {
return ["old", s]
}
else if (n < 16) {
return ["med", s]
}
else if (no_bold || n < 21) {
return ["recent", s]
}
else {
return ["new", s]
}
}
function courtesy_s (n, s) { return n == 1 ? "" : (s || "s") }
var revision_letters = "z a b c d f g h j k l m n p q r s t v w x y".split(" ")
function get_revision (thread) {
if (! thread.revision) return ""
var rev = thread.revision
var n = 0
var digits = ""
do {
n = rev % 21
rev = Math.floor(rev / 21)
digits = revision_letters[n] + digits
}
while (rev !== 0)
return digits
}
function get_age (t) {
var age = Math.abs( Date.now()/1000 - t)
var r = Math.floor
var m
if (age < 5) { return "now" }
if (age < 60) { return r(age) + "s" }
age /= 60
if (age < 60) { return r(age) + "m" }
m = r(age % 60)
age /= 60
if (m > 0 && age < 2) { return r(age) + "h" + m + "m" }
if (age < 24) { return r(age) + "h" }
age /= 24
if (age < 7) { return r(age) + "d" }
age /= 7
if (age < 12) { return r(age) + "w" }
age /= 4
if (age < 12) { return r(age) + "m" }
age /= 12
return r(age) + "y"
}
function tidy_urls (s, short_urls) {
var ret = s.split("\n").map(function(line){
if (line.indexOf("<") !== -1) {
return line
}
return line.replace(/https?:\/\/[^ ]+/g, function(url){
if (is_image(url)) {
return '
'
}
else if (short_urls) {
return '[' + get_domain(url) + ']'
}
else {
return '' + url + ''
}
});
}).join("\n")
return ret
}
function get_domain(url){
return url.replace(/https?:\/\//,"").replace(/\/.*/,"").replace(/www\./, "")
}
function is_image(url){
return !! url.match(/\.(gif|jpe?g|png)\??.*$/i)
}
function make_link(file){
if (file.storage) {
return "//s3.amazonaws.com/" + file.storage + "/bucky/data/" + file.thread + "/" + encodeURIComponent(file.filename)
}
if (file.filename.indexOf("http") !== 0) {
return "/data/" + file.thread + "/" + encodeURIComponent(file.filename)
}
return file.filename
}
function profile_image(username){
return "//s3.amazonaws.com/i.asdf.us/bucky/profile/" + username + ".jpg"
}
function make_thumb(file){
if (file.storage) {
return "//s3.amazonaws.com/" + file.storage + "/bucky/data/" + file.thread + "/" + encodeURIComponent(file.filename)
}
if (file.filename.indexOf("http") !== 0) {
return "/data/" + file.thread + "/" + file.filename
}
return "/data/" + file.thread + "/" + file.filename
// var partz = file.filename.toLowerCase().split("/")
// return partz.splice(partz.length-2, 0, ".thumb").join("/")
}
var metadataTemplate = $(".metadata_template").html()
function metadata(thread){
var datetime = verbose_date(thread.createdate, true)
var age = get_age(thread.lastmodified, true)
var t = metadataTemplate
.replace(/{{username}}/g, thread.username)
.replace(/{{date}}/g, datetime[0])
.replace(/{{time}}/g, datetime[1])
.replace(/{{active}}/g, age + " ago")
.replace(/{{views}}/g, thread.viewed + " view" + courtesy_s(thread.viewed))
return t
}