pj
Version:
Create SQL strings for PostgreSQL by interfacing with a javascript API
1,195 lines (952 loc) • 26.2 kB
JavaScript
var defaults = require(__dirname+'/defaults');
/**
* class Postgres
**/
(function() {
/**
* private static:
**/
var __class = 'Postgres';
var __env_nodejs = false;
var __namespace, __exportee, __name;
// node
if(typeof module !== 'undefined' && module.exports) {
__namespace = global;
__exportee = module;
__name = 'exports';
__env_nodejs = true;
}
// browser
else {
__namespace = __exportee = window;
__name = __class;
}
var d_global_instance = false;
// escape string bits
var esc = function(s_value) {
return s_value
// .replace(/(['\\])/g, '\\$1')
.replace(/'/g,"''")
.replace(/\t/g, '\\t')
.replace(/\n/g, '\\n');
};
// value
var valufy = function(z_value) {
var s_type = typeof z_value;
if('string' == s_type) {
return "'"+esc(z_value)+"'";
}
else if('number' == s_type) {
return z_value;
}
else if('boolean' == s_type) {
return z_value? 'TRUE': 'FALSE';
}
else if('object' == s_type) {
// null
if(z_value === null) {
return null;
}
// raw sql
else if('string' === typeof z_value.raw) {
return z_value.raw;
}
else {
return esc(
JSON.stringify(z_value)
);
}
}
else if('function' == s_type) {
return z_value()+'';
}
else {
throw new Error('unable to valuefy "'+z_value+'"');
}
};
// helper method to renderers
var render_helper = function(a_results) {
return {
each: function(f_each) {
for(var i=a_results.length-1; i>=0; i--) {
f_each.apply({}, [a_results[i], i]);
}
},
};
};
var __construct = function(z_config) {
/**
* private:
**/
// for queueing pending queries
var b_ready = __env_nodejs? false: true;
var a_queries = [];
// client proxy
var y_proxy;
var f_close_proxy;
// user-defined specials
var h_fkeys = {};
var h_select_fns = {};
var h_renderers = {};
// configs
var s_connection = '';
var s_endpoint_url = '';
// connect to database using string
var connect_string = (function() {
// regex constant
var R_CONNECT = /^(?:(?:(?:(\w+):\/\/)?(\w+)@)?(\w+)\/)?(\w+)$/;
// defaults
var H_DEFAULTS = {
protocol: 'postgres',
user: 'root',
host: 'localhost',
};
// parse function
return function(s_connect) {
// parse connection string
var m_connect = R_CONNECT.exec(s_connect);
if(!m_connect) exports.fail('invalid connection string: "'+s_connect+'"');
return ''
+(m_connect[1] || H_DEFAULTS.protocol)+'://'
+(m_connect[2] || H_DEFAULTS.user)+'@'
+(m_connect[3] || H_DEFAULTS.host)+'/'
+m_connect[4];
};
})();
// setup
(function() {
var s_config_type = typeof z_config;
// config type
switch(s_config_type) {
// string
case 'string':
// just the connection string
s_connection = connect_string(z_config);
break;
// hash of config
case 'object':
// connect to database
if(z_config.connect) {
var z_connect = z_config.connect;
// simple string
if('string' == typeof z_connect) {
s_connection = connect_string(z_connect);
}
else if('object' == typeof z_connect && !(z_connect instanceof Array)) {
if(!z_connect.database) exports.fail('must specify a database');
s_connection = ''
+(z_connect.proto || 'postgres://')
+(z_connect.user || 'root')
+(z_connect.pass? ':'+z_connect.pass: '')
+(z_connect.host? '@'+z_connect.host: '@localhost')
+'/'+z_connect.database;
}
}
// set endpoint
if(z_config.endpoint) {
s_endpoint_url = z_config.endpoint;
}
// nodejs
if(__env_nodejs) {
// use proxy module
if(z_config.using) {
(new z_config.using(s_connection)).connect(function(err, y_client, f_close) {
if(err) exports.fail(err);
y_proxy = y_client;
f_close_proxy = f_close;
next_query(function() {
b_ready = true;
});
});
}
}
break;
}
})();
// process next query in queue
var next_query = function(f_okay) {
if(a_queries.length) {
a_queries.shift()();
setTimeout(function() {
next_query(f_okay)
}, 0);
}
else {
f_okay && f_okay();
}
};
// executes a query
var exec_query = (function() {
// nodejs
if(__env_nodejs) {
return function(s_query, f_okay, f_err) {
y_proxy.query(s_query, function(err, result) {
if(err) return (f_err && (false !== f_err(err))) || exports.error(err);
else f_okay && f_okay(result);
});
};
}
// browser
else {
return function(s_query, f_okay, f_err) {
exports.info('# '+s_query);
$.ajax({
url: s_endpoint_url,
method: 'POST',
data: {
connection: s_connection,
query: s_query,
},
dataType: 'json',
success: function(h_res) {
if(h_res.error) return (f_err && f_err(h_res.error)) || exports.error(h_res.error);
else f_okay && f_okay(h_res.rows);
},
});
};
}
})();
// submits a query
var submit_query = function(s_query, f_okay, f_err) {
if(!b_ready) a_queries.push(exec_query.bind({}, s_query, f_okay, f_err));
else exec_query.apply(this, arguments);
};
// generate a so-substituter
var f_so = function(h_how) {
return function(s_field) {
return h_how.pre+s_field+h_how.post;
};
};
//
var is_so = function(s_table, s_field, z_value) {
// prepare beginning of part
var s_part = '"'+s_table+'"."'+s_field+'"';
// depending on value type
var s_type = typeof z_value;
switch(s_type) {
case 'string':
case 'number':
case 'boolean':
return s_part+'='+valufy(z_value);
case 'function':
var z_ret = z_value.apply({}, [s_part]);
if('string' == typeof z_ret) return z_ret;
else return is_so(s_table, s_field, z_ret);
case 'object':
// array
if(z_value instanceof Array) {
var a_ors = [];
for(var i=z_value.length-1; i>=0; i--) {
a_ors.push(
is_so(s_table, s_field, z_value[i])
);
}
return '('+a_ors.join(' or ')+')';
}
// simple op-val hash
else if(z_value.op && z_value.val) {
return s_part+' '+z_value.op+' '+valufy(z_value.val);
}
default:
exports.error('value type "'+s_type+'" not supported');
throw 'invalid value type: '+s_type;
}
};
// adds the implicit join to another table
var add_join = function(h_query, s_from, s_to) {
// foreign-key rule?
var h_rule = h_fkeys[s_from+'='+s_to];
// no rules!
if(!h_rule) return exports.fail('must define an inter-table relation for an implicit join from "'+s_from+'" to "'+s_to+'"');
// establish inner join
h_query.joins[s_to] = 'inner join "'+s_to+'" on "'+s_from+'"."'+h_rule.local+'"="'+s_to+'"."'+h_rule.foreign+'"';
};
// construct where clause
var expand = function(h_query, h_where, s_from_override) {
// reference this table name
var s_from = s_from_override || h_query.from;
// local where clause
var a_clause = [];
// iterate
for(var s_key in h_where) {
var z_value = h_where[s_key];
// inner join
if('object' == typeof z_value) {
// array!
if(z_value instanceof Array) {
// array contains objects
if('object' == typeof z_value[0]) {
// foreign table has not been joined yet in this query
if(!h_query.joins[s_key]) {
// add join
add_join(h_query, s_from, s_key);
}
// iterate each 'or'
var a_ors = [];
for(var i=z_value.length-1; i>=0; i--) {
// expand each one
a_ors.push('('+expand(h_query, z_value[i], s_key)+')');
}
a_clause.push(a_ors.join(' or '));
}
// array contains values
else {
var s_ors = '';
for(var i=0; i<z_value.length; i++) {
s_ors += (i? ' or ': '')+is_so(s_from, s_key, z_value[i]);
}
a_clause.push(s_ors);
}
}
// plain object
else {
// foreign table has not been joined yet in this query
if(!h_query.joins[s_key]) {
// add join
add_join(h_query, s_from, s_key);
}
// add to clause
for(var s_ffield in z_value) {
// create conditional part
var s_part = is_so(s_key, s_ffield, z_value[s_ffield]);
// failed
if(!s_part) return exports.error('aborting query build');
// succeeded; continue
a_clause.push(s_part);
}
}
}
// regular
else {
// create conditional part
var s_part = is_so(s_from, s_key, z_value);
// failed
if(!s_part) return exports.error('aborting query build');
// succeeded; continue
a_clause.push(s_part);
}
}
// return top-level 'and's
return a_clause.join(' and ');
};
// convert hash query to string query
var select_to_sql = function(h_query) {
var b = 'select '+(h_query.select.join(',') || '*')
+' from "'+h_query.from+'"';
// ref joins, iterate
var h_joins = h_query.joins;
for(var e in h_joins) b += ' '+h_joins[e];
//
if(h_query.where.length) b += ' where '+h_query.where.join(' and ');
//
if(h_query.group.length) b += ' group by '+h_query.group.join(',');
if(h_query.order.length) b += ' order by '+h_query.order.join(',');
if(h_query.limit) b += ' limit '+h_query.limit;
if(h_query.offset) b += ' offset '+h_query.offset;
//
return b;
};
// convert hash query to string query
var insert_to_sql = function(h_query) {
var b = 'insert into "'+h_query.into+'"';
var h_ins = h_query.insert;
var a_keys = Object.keys(h_ins);
var s_keys = '', s_vals = '';
for(var i=a_keys.length-1; i>=0; i--) {
var si_key = a_keys[i];
s_keys += '"'+si_key+'"'+(i? ',': '');
s_vals += valufy(h_ins[si_key])+(i? ',': '');
}
// append keys and values
b += ' ('+s_keys+') values('+s_vals+')';
//
return b;
};
//
var R_SELECT = /^(?:(\w+)\s*=\s*)?([\^#]+)?(?:(\w*)\.)?(\w+|\*)(?:::(\w+)(?:\(([^\)]*)\))?)?$/;
var R_SELECT = /^(?:(\w+)\s*=\s*)?([\^#]+)?(?:(\w*)\.)?(\w+|\*)((?:\+(?:\w*\.)?\w+)*)(?:::(\w+)(?:\(([^\)]*)\))?)?$/;
var R_SELECT = /^(?:(\w+)\s*=\s*)?([\^#]+)?((?:\w*\.)?(?:\w+|\*)(?:\+(?:\w*\.)?\w+)*)(?:::(\w+)(?:\(([^\)]*)\))?)?$/;
// resolve field
var resolve_field = function(s_from, s_input) {
//
var i_dot = s_input.indexOf('.');
// full ident
if(i_dot != -1) {
var s_table = s_input.substr(0, i_dot);
return '"'+(s_table || s_from)+'"."'+s_input.substr(i_dot+1)+'"';
}
// semi-ident
else {
return '"'+s_input+'"';
}
};
//
var parse_field = function(h_query, s_input) {
//
var i_dot = s_input.indexOf('.');
var s_table, s_field = s_input;
// full ident
if(i_dot != -1) {
s_table = s_input.substr(0, i_dot);
s_field = s_input.substr(i_dot+1);
}
// wildcard
if(s_field == '*') s_field = '';
// full identifer: `table.field`
if(s_table) {
// external table specified and it's not linked
if((s_table != h_query.from) && !h_query.joins[s_table]) add_join(h_query, h_query.from, s_table);
}
// construct full identifier
var s_full = '"'+(s_table || h_query.from)+'".'+(s_field? '"'+s_field+'"': '*');
// return package
return {
alias: s_field,
ident: s_full,
};
};
//
var parse_fields = function(h_query, s_fields) {
// split fields by concat operator
var m_fields = s_fields.split(/\+/g);
// concatenation
if(m_fields.length > 1) {
var s_alias = '';
var s_ident = 'concat(';
for(var i=0; i<m_fields.length; i++) {
var h_parsed = parse_field(h_query, m_fields[i]);
s_alias += (i? '_': '')+h_parsed.alias;
s_ident += (i? ',': '')+h_parsed.ident;
}
s_ident += ')';
return {
alias: s_alias,
ident: s_ident,
};
}
// single field
else {
return parse_field(h_query, m_fields[0]);
}
};
// query-builder
var qb_select = function(h_query) {
// fix query hash
h_query = {
from: h_query.from,
joins: h_query.joins || {},
fields: h_query.fields || {},
select: h_query.select || [],
where: h_query.where || [],
group: h_query.group || [],
order: h_query.order || [],
limit: h_query.limit || 0,
offset: h_query.offset || 0,
};
// execute this query
var f_exec = function(f_okay, f_err) {
var s_query = select_to_sql(h_query);
submit_query(s_query, f_okay, f_err);
return d_self;
};
// builder object
var d_self = {
// select
select: function() {
// multiple selection arguments
for(var i=arguments.length-1; i>=0; i--) {
var s_arg = arguments[i];
//
var m_select = R_SELECT.exec(s_arg);
//
var s_alias = m_select[1] || '';
var s_fields = m_select[3];
//
var h_parsed = parse_fields(h_query, s_fields);
// function modifier
var s_fn = m_select[4];
if(s_fn) {
var f_fn = h_select_fns[s_fn];
if(!f_fn) throw exports.error('No such selector function defined: "'+s_fn+'"');
s_select = f_fn(h_parsed.ident, m_select[5]);
if(!s_alias) s_alias = h_parsed.alias;
}
// regular
else {
s_select = h_parsed.ident;
}
// special
if(m_select[2]) {
var s_special = m_select[2];
// count (& possibly distinct)
if(s_special[0] == '#') s_select = 'count('+(s_special.length==2? 'distinct ': '')+s_select+')';
// just distinct
else s_select = 'distinct '+s_select;
}
// as alias
if(s_alias) {
s_select += ' as "'+s_alias+'"';
h_query.fields['"'+s_alias+'"'] = s_alias;
}
// store this as a field used
h_query.fields[h_parsed.ident] = s_alias || h_parsed.alias;
// push
h_query.select.push(s_select);
}
return d_self;
},
//
where: function(z_where) {
if('object' == typeof z_where) {
// 'or'-ing clauses
if(z_where instanceof Array) {
// clauses
var a_clauses = [];
// iterate
for(var i=z_where.length-1; i>=0; i--) {
a_clauses.push(expand(h_query, z_where[i]));
}
// join
h_query.where.push('('+a_clauses.join(' or ')+')');
}
// 'and'-ing clause
else {
h_query.where.push('('+expand(h_query, z_where)+')');
}
}
return d_self;
},
//
count: function(s_alias) {
h_query.select.push('count(*) as "'+s_alias+'"');
return d_self;
},
//
join: function(s_table) {
if(!h_query.joins[s_table]) add_join(h_query, h_query.from, s_table);
return d_self;
},
//
group: function() {
// multiple group by arguments
for(var i=arguments.length-1; i>=0; i--) {
var s_field = arguments[i];
var s_full = resolve_field(h_query.from, s_field);
// this field had not been exlpicity selected
if(!h_query.fields[s_full]) {
// select field
h_query.select.push(s_full);
// add it to fields list using its alias
h_query.fields[s_full] = s_field;
}
// add full ident as group
h_query.group.push(s_full);
}
return d_self;
},
//
order: function(s_field, n_way) {
var s_dir = ((n_way && n_way<0)? 'desc': 'asc');
h_query.order.push(resolve_field(h_query.from, s_field)+' '+s_dir);
return d_self;
},
//
limit: function(n_limit) {
h_query.limit = n_limit;
return d_self;
},
//
offset: function(n_offset) {
h_query.offset = n_offset;
return d_self;
},
// output current sql
dump: function(f_dump) {
f_dump = f_dump || console.log.bind(console);
f_dump(select_to_sql(h_query));
return d_self;
},
//
clone: function() {
return qb_select(h_query);
},
// submit query and handle results directly
exec: f_exec,
results: function(f_okay, f_err) {
return f_exec(f_okay, f_err);
},
//
output: function(f_to) {
f_to = f_to || console.info.bind(console);
return f_exec(f_to);
},
// use predefined handler to render results
render: function(si_render, h_options) {
var k_render = h_renderers[si_render];
if(!k_render) return exports.error('no such renderer defined: "'+si_render+'"');
f_exec(function(a_results) {
k_render.apply(render_helper(a_results), [h_options, a_results]);
});
return d_self;
},
//
each: function(f_each, f_okay) {
f_exec(function(a_rows) {
for(var i=0,l=a_rows.length; i<l; i++) {
f_each.apply({}, [a_rows[i], i]);
}
f_okay && f_okay();
});
return d_self;
},
//
export: function() {
for(var e in h_query) {
if(typeof h_query[e] == 'string') {
h_query[e] = h_query[e].replace(/[\n\t]+/g,' ');
}
}
return h_query;
},
};
// extend these functions
d_self.select.raw = function(s_select) {
h_query.select.push(s_select);
return d_self;
};
return d_self;
};
// query-builder
var qb_insert = function(h_query) {
//
h_query = {
into: h_query.into,
insert: h_query.insert || {},
};
// execute this query
var f_exec = function(f_okay, f_err) {
var s_query = insert_to_sql(h_query);
submit_query(s_query, f_okay, f_err);
return d_self;
};
//
var d_self = {
//
insert: function(h_values) {
for(var e in h_values) {
h_query.insert[e] = h_values[e];
}
return d_self;
},
//
clone: function() {
return qb_insert(h_query);
},
// output current sql
dump: function(f_dump) {
f_dump = f_dump || console.log.bind(console);
f_dump(insert_to_sql(h_query));
return d_self;
},
//
exec: f_exec,
};
return d_self;
};
// for operator argument functions eg: `pg('&',7,'>',1)`
var collapse = function(a_args, i_start) {
// pre and post parts
var s_pre = '', s_post = '';
// iterate args
for(var i=(i_start || 0); i<a_args.length-1; i+=2) {
// multi-arguments
if(s_post) { s_pre += '('; s_post += ')'; }
// collapse
s_post += ' '+a_args[i]+' '+valufy(a_args[i+1]);
}
// return how
return {
pre: s_pre,
post: s_post,
};
};
var post_collapse = function(a_args) {
var h_how = collapse(a_args, 1);
h_how.prime = a_args[0];
return function(s_field) {
return this.pre+this.prime(s_field)+this.post;
}.bind(h_how);
};
/**
* public operator() ();
**/
var operator = function(z_prime) {
// dynamic
if('function' == typeof z_prime) {
return post_collapse(arguments);
}
// static
else {
return f_so(
collapse(arguments)
);
}
};
/**
* public:
**/
var R_FKEY = /^([^\.]+)\.([^=]+)=([^\.]+)\.(.+)$/;
// entry point for query-building
operator['connect'] = function(s_endpoint, s_connect) {
s_endpoint_url = s_endpoint;
s_connection = s_connect;
};
//
operator['define'] = function(s_relation) {
if((m_fkey=R_FKEY.exec(s_relation)) != null) {
var s_ta = m_fkey[1], s_ka = m_fkey[2];
var s_tb = m_fkey[3], s_kb = m_fkey[4];
// define directed relation
h_fkeys[s_ta+'='+s_tb] = {local: s_ka, foreign: s_kb};
// define inverse too (if bi-directional)
h_fkeys[s_tb+'='+s_ta] = {local: s_kb, foreign: s_ka};
}
};
//
operator['selector'] = function(s_key, z_fn) {
// simple mono-field function
if('string' == typeof z_fn) {
h_select_fns[s_key] = (function(s_field) {
return this.func+'('+s_field+')';
}).bind({func: z_fn});
}
// special functinon
else if('function' == typeof z_fn) {
h_select_fns[s_key] = f_fn;
}
// unsupported type
else {
expose.error('failed to set selector "'+s_key+'" using '+(typeof z_fn)+' type');
}
};
// entry point for query-building
operator['from'] = function(s_table) {
return qb_select({
from: s_table,
});
};
// entry point for query-building
operator['into'] = function(s_table) {
return qb_insert({
into: s_table,
});
};
// entry point for query-building
operator['use'] = function(si_render, f_render) {
h_renderers[si_render] = f_render;
};
// close connection
operator['close'] = function() {
if(y_proxy) y_proxy.end();
};
// execute raw sql
operator['exec'] = submit_query;
// pass sql string and other args through to proxy
operator['proxy'] = function() {
return y_proxy.query.apply(this, arguments);
};
return operator;
};
/**
* public static operator() ()
**/
var exports = __exportee[__name] = function() {
if(this !== __namespace) {
return __construct.apply(this, arguments);
}
else {
if(d_global_instance) {
if(arguments.length) {
return d_global_instance.apply(this, arguments);
}
return d_global_instance;
}
else {
return __construct.apply(this, arguments);
}
}
};
/**
* public static:
**/
//
exports['toString'] = function() {
return __class+'()';
};
// wrap public static declarations in an iiaf
(function() {
// ref Array.prototype.slice
var Aps = Array.prototype.slice;
// output a message to the console prefixed with this class's tag
var debug = function(channel) {
return function() {
var args = Aps.call(arguments);
args.unshift(__class+':');
console[channel].apply(console, args);
};
};
// open the various output channels
exports['log'] = debug('log');
exports['info'] = debug('info');
exports['warn'] = debug('warn');
exports['error'] = debug('error');
exports['fail'] = function(err) {
exports.error(err);
throw new Error(err);
};
})();
// wrap global instance calls in iiaf
(function() {
var global_instance = function(s_method) {
return function() {
return d_global_instance && d_global_instance[s_method].apply(this, arguments);
};
};
// various global transcends
exports['connect'] = global_instance('connect');
exports['close'] = global_instance('close');
exports['define'] = global_instance('define');
exports['selector'] = global_instance('selector');
exports['use'] = global_instance('use');
exports['from'] = global_instance('from');
exports['into'] = global_instance('into');
exports['exec'] = global_instance('exec');
exports['proxy'] = global_instance('proxy');
})();
// fn-val shortcuts
(function() {
var fnval = function(s_fn) {
return function(s_val) {
if(arguments.length > 1) {
for(var i=1; i<arguments.length; i++) {
s_val += ','+arguments[i];
}
}
return function(s_field) {
return s_fn+'('+s_field+','+s_val+')'
};
};
};
// geometry
exports['within'] = fnval('ST_Within');
exports['buffer'] = fnval('ST_Buffer');
exports['within_distance'] = fnval('ST_DWithin');
exports['distance'] = fnval('ST_Distance');
exports['distance_spheroid'] = fnval('ST_Distance_Spheroid');
// aggregate
exports['max'] = fnval('MAX');
})();
// static shortcuts
(function() {
// define constants
var H_CONST = {
WGS_84: valufy('SPHEROID["WGS 84",6378137,298.257223563]'),
};
// push all key/value pairs onto exports hash
for(var e in H_CONST) exports[e] = H_CONST[e];
})();
// geom shortcut
(function() {
var H_GEOJSON_CRS_4326 = {
type: 'name',
properties: {
'name': 'EPSG:4326',
},
};
exports['geom'] = function(z_geom, n_srid) {
var s_geom = '';
if('object' == typeof z_geom) {
if(z_geom instanceof Array && z_geom.length) {
s_geom += "ST_GeomFromText('";
if(z_geom[0] instanceof Array) {
s_geom += 'POLYGON(', s_close = '';
for(var i=0; i<z_geom.length; i++) {
var a_crd = z_geom[i];
if(i) s_geom += ',';
var s_pts = a_crd[0]+' '+a_crd[1]+(a_crd.lenth==3? ' '+a_crd[2]:'');
if(!i) s_close = s_pts;
s_geom += s_pts;
}
s_geom += ','+s_close+')';
}
else {
s_geom += 'POINT('+z_geom[0]+' '+z_geom[1]+(z_geom.length==3? ' '+z_geom[2]:'')+')';
}
s_geom += "',"+(n_srid || 4326)+")";
}
else if(typeof z_geom.type == 'string') {
switch(z_geom.type.toLowerCase()) {
case 'point':
case 'polyline':
case 'polygon':
if(!z_geom.crs) z_geom.crs = H_GEOJSON_CRS_4326;
s_geom += "ST_GeomFromGeoJSON('"+JSON.stringify(z_geom)+"')";
break;
}
}
}
else if('string' == typeof z_geom) {
s_geom += "ST_GeomFromText('"+z_geom+"',"+(n_srid || 4326)+")";
}
// return {raw: s_geom};
return (function() {
return this.geom;
}).bind({geom: s_geom});
};
})();
// simple shortcuts
(function() {
exports['time'] = function(z_time) {
// milliseconds
if('number' == typeof z_time) {
return {raw: 'to_timestamp('+(z_time / 1000)+')'};
}
// date object
else if('object' == typeof z_time) {
if(z_time instanceof Date) {
return {raw: 'to_timestamp('+(z_time.getTime() / 1000)+')'};
}
}
else {
exports.fail('cannot create time using ['+(typeof z_time)+']: ',z_time);
}
};
exports['now'] = function(n_milliseconds_adjust) {
return {raw: 'to_timestamp('+((Date.now()+(n_milliseconds_adjust||0))/1000)+')'};
};
})();
// configure
exports['config'] = function(h_config) {
// global mode
if(h_config.global) {
// create global instance
d_global_instance = exports.apply({}, [h_config.global]);
// load defaults
defaults(d_global_instance);
// export alias to namespace
var d_static = exports.bind(__namespace);
// an alias was given
if(h_config.alias) {
__exportee[h_config.alias] = d_static;
}
// along with exportsd methods
for(var e in exports) {
d_static[e] = exports[e];
}
return d_static;
}
};
//
exports[''] = function() {
};
})();