export function uniq(xs) { var seen = {}; return xs.filter(x => seen.hasOwnProperty(x) ? false : (seen[x] = true)); } export function groupBy(xs, key) { return xs.reduce(function(rv, x) { var v = key instanceof Function ? key(x) : x[key]; (rv[v] = rv[v] || []).push(x); return rv; }, {}); } export function groupByArray(xs, key) { var mapping = {}; return xs.reduce(function(rv, x) { var v = key instanceof Function ? key(x) : x[key]; var el = mapping[v]; if(el) el.values.push(x); else rv.push(mapping[v] = { key: v, values: [x] }); return rv; }, []); } export function pivotByArray(xs, key, reducer) { var groups = groupByArray(xs, key); groups.forEach(function(group) { group.aggregate = group.values.reduce(reducer, {}); }); return groups; } export function quantile_sorted(arr_sorted, quantile) { var pos = (arr_sorted.length - 1) * quantile, base = Math.floor(pos), rest = pos - base; return arr_sorted[base + 1] !== undefined ? arr_sorted[base] + rest * (arr_sorted[base + 1] - arr_sorted[base]) : arr_sorted[base]; } export function strtr(s, a, b) { var res = ''; for(var i = 0; i < s.length; ++i) { var j = a.indexOf(s.charAt(i)); res += j >= 0 ? b.charAt(j) : s.charAt(i); } return res; } export function strtr_unscramble(name) { return name.length > 0 ? (name.charAt(0) + strtr(name.substring(1), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'LKJIHGFEDCBAZYXWVUTSRQPONM')) : name; } export function strHashCode(str) { var hash = 0; for(var i = 0; i < str.length; ++i) hash = str.charCodeAt(i) + ((hash << 5) - hash); return hash & hash; // convert to 32 bit } export function strHashJenkins(str) { for(var hash = 0, i = str.length; i--;) hash += str.charCodeAt(i), hash += hash << 10, hash ^= hash >> 6; hash += hash << 3; hash ^= hash >> 11; return (hash + (hash << 15) & 4294967295) >>> 0 } export function strHashHex(str) { var hash = strHashJenkins(str), color = '#'; for(var i = 0; i < 3; ++i) color += ('00' + ((hash >> (i * 8)) & 0xFF).toString(16)).slice(-2); return color; } export function strHashHSL(str, lightness='50%') { var hash = strHashJenkins(str); return 'hsl(' + (hash%360) + ',' + (hash%100) + '%,' + lightness + ')'; } export function strftime_vista(date) { return 10000*(date.getFullYear() - 1700) + 100*(date.getMonth() + 1) + date.getDate() + date.getHours()/100 + date.getMinutes()/10000 + date.getSeconds()/1000000 + date.getMilliseconds()/1000000000; } export function strfdate_vista(date) { return 10000*(date.getFullYear() - 1700) + 100*(date.getMonth() + 1) + date.getDate(); } export function strptime_vista(s) { s = +s; var date = Math.floor(s), time = s - date; return new Date(Math.floor(date/10000) + 1700, (Math.floor(date/100) + '').slice(-2) - 1, (date + '').slice(-2), Math.floor(time*100), (Math.floor(time*10000) + '').slice(-2), (Math.floor(time*1000000) + '').slice(-2), (Math.floor(time*1000000000) + '').slice(-3)); } export function debounce(fn, delay) { var clock = null; return function() { clearTimeout(clock); var self = this, args = arguments; clock = setTimeout(function() { fn.apply(self, args) }, delay); } } function Descendant() {} export function inherit(obj) { Descendant.prototype = obj; return new Descendant(); }