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 = sanitizeHTML(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") .replace(/\r/g, "") .replace(/\n/g, "") .replace(/<\/code>\n/g, "") 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 + sdk.opt.s3.path + "/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 + sdk.opt.s3.path + "/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 }