if (window.$) { $.fn.int = function() { return parseInt($(this).val(),10) } $.fn.float = function() { return parseFloat($(this).val()) } $.fn.string = function() { return trim($(this).val()) } $.fn.enable = function() { return $(this).attr("disabled",null) } $.fn.disable = function() { return $(this).attr("disabled","disabled") } $.fn.sanitize = function(s) { return trim(sanitize($(this).val())) } $.fn.stripHTML = function(s) { return trim(stripHTML($(this).val())) } $.fn.sanitizeName = function(s) { return trim(sanitizeName($(this).val())) } $.fn.htmlSafe = function(s) { return $(this).html(sanitize(s)) } $.fn.toDollars = function(i) { return $(this).html((i/100).toFixed(2)) } } function trim (s){ return s.replace(/^\s+/,"").replace(/\s+$/,"") } function sanitize (s){ return (s || "").replace(new RegExp("[<>&]", 'g'), "") } function sanitizeName (s){ return (s || "").replace(new RegExp("[^-_a-zA-Z0-9]", 'g'), "") } function stripHTML (s){ return (s || "").replace(/<[^>]+>/g, "") } function sanitizeHTML (s){ return (s || "").replace(/&/g, "&").replace(//g, ">") } function capitalize (s){ return s.split(" ").map(capitalizeWord).join(" ") } function capitalizeWord (s){ return s.charAt(0).toUpperCase() + s.slice(1) } function slugify (s){ return (s || "").toLowerCase().replace(/\s/g,"-").replace(/[^-_a-zA-Z0-9]/g, '-').replace(/-+/g,"-") } function rgb_string (rgb) { return "rgb(" + rgb.map(Math.round).join(",") + ")" } function rgba_string (rgb,a) { return "rgba(" + rgb.map(Math.round).join(",") + "," + a + ")" } function hex_string (rgb) { return "#" + rgb.map(Math.round).map(function(n){ var s = n.toString(16); return s.length == 1 ? "0"+s : s }).join("") } function parse_rgba_string (s) { return s.match(/(\d+)/g).slice(0,3) } var E = Math.E var PI = Math.PI var PHI = (1+Math.sqrt(5))/2 var TWO_PI = PI*2 var HALF_PI = PI/2 var LN10 = Math.LN10 function clamp(n,a,b){ return n= a) + 0 // ^^ bool -> int } function julestep (a,b,n) { return clamp(norm(n,a,b), 0.0, 1.0); } // hermite curve apparently function smoothstep(min,max,n){ var t = clamp((n - min) / (max - min), 0.0, 1.0); return t * t * (3.0 - 2.0 * t) } function shuffle(a){ var r, swap for (var i = a.length; i > 0; i--){ r = randint(i) swap = a[i-1] a[i-1] = a[r] a[r] = swap } return a } function reverse(a){ var reversed = [] for (var i = 0, _len = a.length-1; i <= _len; i++){ reversed[i] = a[_len-i] } return reversed } function deinterlace(a){ var odd = [], even = [] for (var i = 0, _len = a.length; i < _len; i++) { if (i % 2) even.push(a[i]) else odd.push(a[i]) } return [even, odd] } function weave(a){ var aa = deinterlace(a) var b = [] aa[0].forEach(function(el){ b.push(el) }) reverse(aa[1]).forEach(function(el){ b.push(el) }) return b } function range(m,n,s){ var a = [] s = s || 1 for (var i = m; i <= n; i += s) { a.push(i) } return a } var guid_syllables = "iz az ez or iv ex baz el lo lum ot un no".split(" ") var guid_n = 0 function guid(n){ var len = guid_syllables.length return ((++guid_n*(len-1)*(~~log(guid_n))).toString(len)).split("").map(function(s){ return guid_syllables[parseInt(s, len) % len--] }).join("") } function defaults (dest, src) { dest = dest || {} for (var i in src) { dest[i] = typeof dest[i] == 'undefined' ? src[i] : dest[i] } return dest } // Change straight quotes to curly and double hyphens to em-dashes. function smarten(a) { a = a.replace(/(^|[-\u2014\s(\["])'/g, "$1\u2018"); // opening singles a = a.replace(/'/g, "\u2019"); // closing singles & apostrophes a = a.replace(/(^|[-\u2014/\[(\u2018\s])"/g, "$1\u201c"); // opening doubles a = a.replace(/"/g, "\u201d"); // closing doubles a = a.replace(/--/g, "\u2014"); // em-dashes return a }; function pairs(h){ var a = [] for (var i in h) { if(h.hasOwnProperty(i)) { a.push([i, h[i]]) } } return a } function invert_hash (h) { var k = {} for (var i in h) { if (h.hasOwnProperty(i)) k[h[i]] = i } return k } function filenameFromUrl (url) { var partz = url.split( "/" ) return partz[partz.length-1].split(".")[0] } function bitcount(v) { v = v - ((v >>> 1) & 0x55555555); v = (v & 0x33333333) + ((v >>> 2) & 0x33333333); return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; } // Function.bind polyfill if (!Function.prototype.bind) { Function.prototype.bind = function(oThis) { if (typeof this !== 'function') { // closest thing possible to the ECMAScript 5 // internal IsCallable function throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); } var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function() {}, fBound = function() { return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); }; fNOP.prototype = this.prototype; fBound.prototype = new fNOP(); return fBound; }; } // rAF polyfill (function() { var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; } if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; }()); // Identify browser based on useragent string (function( ua ) { ua = ua.toLowerCase(); var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || /(webkit)[ \/]([\w.]+)/.exec( ua ) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || /(msie) ([\w.]+)/.exec( ua ) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || []; var matched = { browser: match[ 1 ] || "", version: match[ 2 ] || "0" }; browser = {}; if ( matched.browser ) { browser[ matched.browser ] = true; browser.version = matched.version; } // Chrome is Webkit, but Webkit is also Safari. if ( browser.chrome ) { browser.webkit = true; } else if ( browser.webkit ) { browser.safari = true; } if (window.$) $.browser = browser; return browser; })( navigator.userAgent ); // Naive useragent detection pattern 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; var app_devicePixelRatio = is_mobile ? devicePixelRatio : 1; function selectElementContents(el) { if (window.getSelection && document.createRange) { var sel = window.getSelection(); var range = document.createRange(); range.selectNodeContents(el); sel.removeAllRanges(); sel.addRange(range); } else if (document.selection && document.body.createTextRange) { var textRange = document.body.createTextRange(); textRange.moveToElementText(el); textRange.select(); } } // manipulate text selection in an element function setSelectionRange(input, selectionStart, selectionEnd) { if (input.setSelectionRange) { input.focus(); input.setSelectionRange(selectionStart, selectionEnd); } else if (input.createTextRange) { var range = input.createTextRange(); range.collapse(true); range.moveEnd('character', selectionEnd); range.moveStart('character', selectionStart); range.select(); } } // place cursor at a specific point (usually the beginning) function setCaretToPos (input, pos) { setSelectionRange(input, pos, pos); }