"use strict" define([ "bacon" ], function (Bacon) { function get(url) { return Bacon.fromBinder(function(sink) { var req = new XMLHttpRequest() req.open("GET", url) req.onload = function() { if (req.status === 200) sink(new Bacon.Next(req.response)) else sink(new Bacon.Error(req.statusText)) sink(new Bacon.End()) } req.onerror = function() { sink(new Bacon.Error("network error")) sink(new Bacon.End()) } req.send() return function () {} }) } function getJSON(url) { return get(url).map(JSON.parse) } function buildUrl(ip, object, param) { var url = "http://[" + ip + "]/cgi-bin/" + object if (param) url += "?" + param return url } function request(ip, object, param) { return getJSON(buildUrl(ip, object, param)) } function dictGet(dict, key) { var k = key.shift() if (!(k in dict)) return null if (key.length === 0) return dict[k] return dictGet(dict[k], key) } function localizeNumber(d) { var sep = ',' return d.replace('.', sep) } function formatNumberFixed(d, digits) { return localizeNumber(d.toFixed(digits)) } function formatNumber(d, digits) { digits-- for (var v = d; v >= 10 && digits > 0; v /= 10) digits-- // avoid toPrecision as it might produce strings in exponential notation return formatNumberFixed(d, digits) } function haversine() { var radians = Array.prototype.map.call(arguments, function(deg) { return deg / 180.0 * Math.PI }) var lat1 = radians[0], lon1 = radians[1], lat2 = radians[2], lon2 = radians[3] var R = 6372.8 // km var dLat = lat2 - lat1 var dLon = lon2 - lon1 var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2) var c = 2 * Math.asin(Math.sqrt(a)) return R * c } return { buildUrl: buildUrl , request: request , getJSON: getJSON , dictGet: dictGet , formatNumber: formatNumber , formatNumberFixed: formatNumberFixed , haversine: haversine } })