1
0
forked from sent/waves
waves/public/assets/g/iwbtc/util.js
2025-04-09 17:11:14 -05:00

405 lines
7.0 KiB
JavaScript

"use strict";
Math.sign = function(x)
{
return (x > 0) - (x < 0);
};
// round away from zero, opposite of truncation
Math.roundInfinity = function(x)
{
return x > 0 ? Math.ceil(x) : Math.floor(x);
};
Math.floatToRandom = function(x)
{
var floor = Math.floor(x)
return floor + (Math.random() > x - floor);
}
/**
* Return the triangle wave function between -1 and 1 with the given frequency a
*/
Math.triangle = function(a)
{
return function(t)
{
var r = t / a;
return -1 + 4 * Math.abs(r + .25 - Math.floor(r + .75));
}
};
/**
* Return a rectangle wave function between -1 and 1 (can also yield 0) with the
* given frequency a
*/
Math.rectangle = function(a)
{
var triangle = Math.triangle(a);
return function(t)
{
return Math.sign(triangle(t));
};
};
// return 1 if x > y, -1 if y > x, 0 otherwise
Math.compare = function(x, y)
{
return Math.sign(x - y);
};
/**
* index, n.:
* Alphabetical list of words of no possible interest where an
* alphabetical list of subjects with references ought to be.
*/
Array.prototype.findIndex = function(f)
{
var result;
this.some(function(value, index)
{
if(f(value))
{
result = index;
return true;
}
});
return result;
};
Array.prototype.find = function(f)
{
var index = this.findIndex(f);
if(index === undefined)
{
return undefined;
}
else
{
return this[index];
}
};
// delete one element by value
Array.prototype.delete = function(v)
{
var index = this.indexOf(v);
if(index !== -1)
{
return this.slice(0, index).concat(this.slice(index + 1));
}
return this;
};
// concatMap :: (a -> [b]) -> [a] -> [b]
// Map a function over a list and concatenate the results.
Array.prototype.concatMap = function(f)
{
var result = [];
this.forEach(function(x)
{
result = result.concat(f(x));
});
return result;
};
Array.prototype.deleteList = function(xs)
{
return this.filter(function(x)
{
return xs.indexOf(x) === -1;
});
};
Array.replicate = function(n, x)
{
var xs = [];
for(var i = 0; i < n; i++)
{
xs[i] = x;
}
return xs;
}
// partition :: (a -> Bool) -> [a] -> ([a], [a])
// The partition function takes a predicate a list and returns the pair of lists
// of elements which do and do not satisfy the predicate, respectively
Array.prototype.partition = function(f)
{
return this.reduce(function(result, x)
{
if(f(x))
{
result[0].push(x);
}
else
{
result[1].push(x);
}
return result;
}, [[], []]);
};
Array.toArray = function(xs)
{
return [].slice.call(xs);
};
Function.byIndex = function(index, value)
{
return function(obj)
{
return obj[index] === value;
};
}
// not well tested, works for everything that we need
Object.deepcopy = function clone(obj)
{
if(typeof obj === "object")
{
if(obj instanceof Array)
{
return obj.map(clone);
}
else if(obj.__proto__)
{
var result = {
__proto__: obj.__proto__
},
keys = Object.keys(obj);
for(var i = 0; i < keys.length; i++)
{
result[keys[i]] = obj[keys[i]];
}
}
else
{
var result = {};
for(var k in obj)
{
result[k] = clone(obj[k]);
}
}
return result;
}
else
{
return obj;
}
};
Object.isArray = function(x)
{
return x instanceof Array;
}
Function.not = function(f)
{
return function(x) { return !f(x); };
}
function range(min, max, step)
{
var result = [];
step = step || 1;
dbg_assert(step > 0);
if(max === undefined)
{
max = min;
min = 0;
}
for(var i = min; i < max; i += step)
{
//yield i; // fuck you
result.push(i);
}
return result;
}
/**
* Hook obj[name], so when it gets called, func will get called too
*/
Function.hook = function(obj, name, func)
{
var old = obj[name];
obj[name] = function()
{
old.apply(this, arguments);
func.apply(this, arguments);
};
}
Object.extend = function(o1, o2)
{
var keys = Object.keys(o2),
key;
for(var i = 0; i < keys.length; i++)
{
key = keys[i];
o1[key] = o2[key];
}
return o1;
};
Object.deleteByValue = function(obj, value)
{
var keys = Object.keys(obj),
key
for(var i = 0; i < keys.length; i++)
{
key = keys[i];
if(obj[keys[i]] === value)
{
delete obj[keys[i]];
}
}
}
Object.merge = function(o1, o2)
{
return Object.extend(Object.extend({}, o1), o2);
};
Object.values = function(obj)
{
var keys = Object.keys(obj),
result = [];
for(var i = 0; i < keys.length; i++)
{
result.push(obj[keys[i]]);
}
return result;
};
function dbg_log(str)
{
document.getElementById("debug").textContent = str;
}
function dbg_warn(str)
{
document.getElementById("warn").textContent += str + "\n";
}
/**
* @param {string=} msg
*/
function dbg_assert(cond, msg)
{
if(!cond)
{
//console.log("assert failed");
//console.log(msg || "");
console.trace();
throw "Assert failed: " + msg;
}
}
/**
* @param {function(string,number)=} onerror
*/
function http_get(url, onready, onerror)
{
var http = new XMLHttpRequest();
http.onreadystatechange = function()
{
if(http.readyState === 4)
{
if(http.status === 200)
{
onready(http.responseText, url);
}
else
{
if(onerror)
{
onerror(http.responseText, http.status);
}
}
}
};
http.open("get", url, true);
http.send("");
return {
cancel : function()
{
http.abort();
}
};
}
// Given a list of objects and a list of keys that should exist on the objects,
// get the cartesian product of the values and return objects with the result of
// each product
function cartesianProductOnObjects(list, keys)
{
if(!Object.isArray(list))
{
list = [list];
}
return keys.reduce(singleProduct, list);
function singleProduct(list, key)
{
return list.concatMap(function(obj)
{
var values = obj[key];
if(!Object.isArray(values))
{
return [obj];
}
else
{
return values.map(function(val)
{
var x = Object.deepcopy(obj);
x[key] = val;
return x;
});
}
});
}
}