/* exported getParameterByName, updateQueryString, throttle, debounce, getHashParams, setStatus, addAtPosition, getValue, getValueJSON, setValueJSON, bindString, ellipsize, sizeOfObject, base64Encode */ //the following is absolutely necessary for IE compatibility, because IE <= 9 have no console object window.console = window.console || (function() { var c = {}; c.log = c.warn = c.debug = c.info = c.error = c.time = c.dir = c.profile = c.clear = c.exception = c.trace = c.assert = function(){}; return c; })(); function getParameterByName(name) { name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(window['location']['search']); return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); } function updateQueryString(key, value, url) { if (!url) url = window.location.href; var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"), hash; if (re.test(url)) { if (typeof value !== 'undefined' && value !== null) return url.replace(re, '$1' + key + "=" + value + '$2$3'); else { hash = url.split('#'); url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, ''); if (typeof hash[1] !== 'undefined' && hash[1] !== null) url += '#' + hash[1]; return url; } } else { if (typeof value !== 'undefined' && value !== null) { var separator = url.indexOf('?') !== -1 ? '&' : '?'; hash = url.split('#'); url = hash[0] + separator + key + '=' + value; if (typeof hash[1] !== 'undefined' && hash[1] !== null) url += '#' + hash[1]; return url; } else return url; } } function throttle(func, wait, options) { var context, args, result; var timeout = null; var previous = 0; if(!options) options = {}; var later = function() { previous = options['leading'] === false ? 0 : (new Date().getTime()); timeout = null; result = func.apply(context, args); context = args = null; }; return function() { var now = new Date().getTime(); if (!previous && options['leading'] === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); context = args = null; } else if (!timeout && options['trailing'] !== false) { timeout = setTimeout(later, remaining); } return result; }; } /** * Returns a function, that, as long as it continues to be invoked, will not * be triggered. The function will be called after it stops being called for * N milliseconds. If `immediate` is passed, trigger the function on the * leading edge, instead of the trailing. * * @param {function} func * @param {number} wait * @param {boolean} immediate */ function debounce(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; clearTimeout(timeout); timeout = setTimeout(function() { timeout = null; if (!immediate) func.apply(context, args); }, wait); if (immediate && !timeout) func.apply(context, args); }; } /** * Parses the hash parameters to this page and returns them as an object. * @function */ function getHashParams() { var params = {}; var hashFragment = window.location.hash; if(hashFragment) { // split up the query string and store in an object var paramStrs = hashFragment.slice(1).split('&'); for (var i = 0; i < paramStrs.length; i++) { var paramStr = paramStrs[i].split('='); params[paramStr[0]] = unescape(paramStr[1]); } } // Opening from Drive will encode the state in a query search parameter var searchFragment = window.location.search; if (searchFragment) { // split up the query string and store in an object var paramStrs2 = searchFragment.slice(1).split('&'); for(var j = 0; j < paramStrs2.length; j++) { var paramStr2 = paramStrs2[j].split('='); params[paramStr2[0]] = unescape(paramStr2[1]); } } return params; } function addAtPosition($item, $list, index) { //append to end if(index === null || typeof(index) == 'undefined' || index > $('li', $list).length) { $item.appendTo($list); } else if(index === 0) { $item.prependTo($list); } else { $item.insertAfter($list.children().eq(index-1)); } } function ellipsize(text, maxLength) { var ret = text; if(ret.length > maxLength) ret = ret.substr(0, maxLength - 1) + "…"; return ret; } function sizeOfObject(object) { var objectList = []; var stack = [ object ]; var bytes = 0; while ( stack.length ) { var value = stack.pop(); if ( typeof value === 'boolean' ) { bytes += 4; } else if ( typeof value === 'string' ) { bytes += value.length * 2; } else if ( typeof value === 'number' ) { bytes += 8; } else if ( typeof value === 'object' && objectList.indexOf( value ) === -1 ) { objectList.push( value ); for( var i in value ) { stack.push( value[ i ] ); } } } return bytes; } function setStatus(status) { window['status'] = status; console.log(window['status'] = status); } function base64Encode(str) { var CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var out = "", i = 0, len = str.length, c1, c2, c3; while (i < len) { c1 = str.charCodeAt(i++) & 0xff; if (i == len) { out += CHARS.charAt(c1 >> 2); out += CHARS.charAt((c1 & 0x3) << 4); out += "=="; break; } c2 = str.charCodeAt(i++); if (i == len) { out += CHARS.charAt(c1 >> 2); out += CHARS.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)); out += CHARS.charAt((c2 & 0xF) << 2); out += "="; break; } c3 = str.charCodeAt(i++); out += CHARS.charAt(c1 >> 2); out += CHARS.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)); out += CHARS.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)); out += CHARS.charAt(c3 & 0x3F); } return out; } function formatMoney(c) { if(!c) return ''; return Number(c).toLocaleString('en-us', { style: 'currency', currency: 'USD' }).split('.')[0]; } function formatDate(dt) { if(!dt) return ''; var date = new Date(dt); var year = date.getFullYear(); var month = (1 + date.getMonth()).toString(); month = month.length > 1 ? month : '0' + month; var day = date.getDate().toString(); day = day.length > 1 ? day : '0' + day; return year + '-' + month + '-' + day; } function array_intersection(old, nu, property, inclusion) { //items to add starts empty var added = []; //start with all the old items, which we'll remove as we find them in the new list var removed = old.slice(0); var unchanged = []; //go through all new items for(var i = 0; i < nu.length; i++) { if(!nu[i]) continue; var found = false; //go through all old items for(var j = 0; j < removed.length; j++) { if(!removed[j]) continue; //if the new item is found in the old list //also check if the item is to be included no matter what if(removed[j][property] == nu[i][property] || (inclusion && removed[j][property] == inclusion[property])) { //this new item is in the old list, so remove it from the old list found = true; //remove this item from the remove list var unchanged_item = removed.splice(j, 1)[0]; //add it to the unchanged list unchanged.push(unchanged_item); break; } } if(!found) added.push(nu[i]); } var obj = { 'added': added, 'removed': removed, 'unchanged': unchanged }; return obj; } var second = 1e3, minute = 6e4, hour = 36e5, day = 864e5, week = 6048e5; function timeFromNow(tm) { var system_date = new Date(Date.parse(tm)); var user_date = new Date(); var diff = Math.floor((user_date - system_date) / 1000); if (diff <= 1) {return "just now";} if (diff < 20) {return diff + " seconds ago";} if (diff < 40) {return "half a minute ago";} if (diff < 60) {return "less than a minute ago";} if (diff <= 90) {return "one minute ago";} if (diff <= 3540) {return Math.round(diff / 60) + " minutes ago";} if (diff <= 5400) {return "1 hour ago";} if (diff <= 86400) {return Math.round(diff / 3600) + " hours ago";} if (diff <= 129600) {return "1 day ago";} if (diff < 604800) {return Math.round(diff / 86400) + " days ago";} if (diff <= 777600) {return "1 week ago";} /* if (diff < 1209600) {return Math.round(diff / 1209600) + " weeks ago";} if (diff <= 4838400) {return "1 month ago";} */ var dateString = system_date.getFullYear() +"/"+ ("0" + (system_date.getMonth()+1)).slice(-2) +"/"+ ("0" + system_date.getDate()).slice(-2) + " " + ("0" + system_date.getHours()).slice(-2) + ":" + ("0" + system_date.getMinutes()).slice(-2) + ":" + ("0" + system_date.getSeconds()).slice(-2); return "on " + dateString; } function timeDifference(a, b) { var date_a = new Date(a); var date_b = new Date(b); var sec = parseInt((date_b - date_a) / 1000); var ret = ''; if(sec > 60) { ret += parseInt(sec / 60) + ' min '; sec = sec % 60; } ret += sec + ' sec'; return ret; }