Massive directory cleanup, more reliable transport
@ -1,3 +0,0 @@
|
||||
For information about action hooks supported by OpenShift, consult the documentation:
|
||||
|
||||
http://openshift.github.io/documentation/oo_user_guide.html#the-openshift-directory
|
@ -1,23 +0,0 @@
|
||||
Run scripts or jobs on a periodic basis
|
||||
=======================================
|
||||
Any scripts or jobs added to the minutely, hourly, daily, weekly or monthly
|
||||
directories will be run on a scheduled basis (frequency is as indicated by the
|
||||
name of the directory) using run-parts.
|
||||
|
||||
run-parts ignores any files that are hidden or dotfiles (.*) or backup
|
||||
files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved}
|
||||
|
||||
The presence of two specially named files jobs.deny and jobs.allow controls
|
||||
how run-parts executes your scripts/jobs.
|
||||
jobs.deny ===> Prevents specific scripts or jobs from being executed.
|
||||
jobs.allow ===> Only execute the named scripts or jobs (all other/non-named
|
||||
scripts that exist in this directory are ignored).
|
||||
|
||||
The principles of jobs.deny and jobs.allow are the same as those of cron.deny
|
||||
and cron.allow and are described in detail at:
|
||||
http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/ch-Automating_System_Tasks.html#s2-autotasks-cron-access
|
||||
|
||||
See: man crontab or above link for more details and see the the weekly/
|
||||
directory for an example.
|
||||
|
||||
PLEASE NOTE: The Cron cartridge must be installed in order to run the configured jobs.
|
0
.openshift/cron/daily/.gitignore
vendored
0
.openshift/cron/hourly/.gitignore
vendored
0
.openshift/cron/minutely/.gitignore
vendored
0
.openshift/cron/monthly/.gitignore
vendored
@ -1,16 +0,0 @@
|
||||
Run scripts or jobs on a weekly basis
|
||||
=====================================
|
||||
Any scripts or jobs added to this directory will be run on a scheduled basis
|
||||
(weekly) using run-parts.
|
||||
|
||||
run-parts ignores any files that are hidden or dotfiles (.*) or backup
|
||||
files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} and handles
|
||||
the files named jobs.deny and jobs.allow specially.
|
||||
|
||||
In this specific example, the chronograph script is the only script or job file
|
||||
executed on a weekly basis (due to white-listing it in jobs.allow). And the
|
||||
README and chrono.dat file are ignored either as a result of being black-listed
|
||||
in jobs.deny or because they are NOT white-listed in the jobs.allow file.
|
||||
|
||||
For more details, please see ../README.cron file.
|
||||
|
@ -1 +0,0 @@
|
||||
Time And Relative D...n In Execution (Open)Shift!
|
@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "`date`: `cat $(dirname \"$0\")/chrono.dat`"
|
@ -1,12 +0,0 @@
|
||||
#
|
||||
# Script or job files listed in here (one entry per line) will be
|
||||
# executed on a weekly-basis.
|
||||
#
|
||||
# Example: The chronograph script will be executed weekly but the README
|
||||
# and chrono.dat files in this directory will be ignored.
|
||||
#
|
||||
# The README file is actually ignored due to the entry in the
|
||||
# jobs.deny which is checked before jobs.allow (this file).
|
||||
#
|
||||
chronograph
|
||||
|
@ -1,7 +0,0 @@
|
||||
#
|
||||
# Any script or job files listed in here (one entry per line) will NOT be
|
||||
# executed (read as ignored by run-parts).
|
||||
#
|
||||
|
||||
README
|
||||
|
741
deps/discrete.js
vendored
@ -1,741 +0,0 @@
|
||||
module.exports=require('theory')((function(){
|
||||
var discrete = {};
|
||||
discrete.name = 'discrete';
|
||||
discrete.author = 'Mark';
|
||||
discrete.version = 1.2;
|
||||
root.opts.discrete = root.opts.discrete||{};
|
||||
discrete.dep = [];
|
||||
window.jQuery? '': root.opts.discrete.jquery?
|
||||
discrete.dep.push(root.opts.discrete.jquery) : console.log('Error: Needs jQuery! Include it or assign a path to `root.opts.discrete.jquery`');
|
||||
discrete.init = (function(a){
|
||||
console.log('discrete.init');
|
||||
function the(){ return the };
|
||||
the.os = (function(){
|
||||
function os(){ return os };
|
||||
var ua = navigator.userAgent, lua = a.text.low(ua);
|
||||
os.is = (function(){
|
||||
function is(q){
|
||||
return (q)?(is.win||is.lin||is.mac||is.and||is.ios||"unknown"):is;
|
||||
} if(root.page){
|
||||
is.win = (ua.search("Win") >= 0)? "Windows":false;
|
||||
is.lin = (ua.search("Linux") >= 0)? "Linux":false;
|
||||
is.mac = (ua.search("Mac") >= 0)? "Macintosh":false
|
||||
is.and = (lua.search("android") >= 0)? "Android":false
|
||||
is.ios = (lua.search('ipod') >= 0
|
||||
|| lua.search('iphone') >= 0
|
||||
|| lua.search('ipad') >= 0)? "iOS":false
|
||||
} else {
|
||||
is.node = true;
|
||||
} return is;
|
||||
})();
|
||||
os.wkv = a.num.dec(a.list(ua.match(/AppleWebKit\/([\d\.]+)/)).at(-1));
|
||||
if(os.is.and){
|
||||
var s = '', v = a.list(ua.match(/Android\s+([\d\.]+)/)).at(-1);
|
||||
a.list(a.num(v).ify([])).each(function(v,i){
|
||||
s += (v*100+'').slice(0,3);
|
||||
});
|
||||
os.version = os.V = a.num.ify(s);
|
||||
} return os;
|
||||
})();
|
||||
the.device = (function(){
|
||||
function device(){ return device };
|
||||
device.is = (function(){
|
||||
function is(){ return is };
|
||||
is.touch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch); // via Modernizer
|
||||
is.oriented = ('onorientationchange' in window) || ('orientation' in window);
|
||||
return is;
|
||||
})();
|
||||
device.size = (function(){
|
||||
function size(){ return size };
|
||||
size.x = size.width = screen.width;
|
||||
size.y = size.height = screen.height;
|
||||
return size;
|
||||
})();
|
||||
device.rotate = (function(fn){
|
||||
if(a.fns.is(fn)){
|
||||
return a.on('discrete-rotate').event(fn);
|
||||
}
|
||||
device.vertical = ($(window).height() > $(document).width())? true : false;
|
||||
device.horizontal = !device.vertical;
|
||||
a.on('discrete-rotate').emit();
|
||||
});
|
||||
return device;
|
||||
})();
|
||||
the.event = (function(){ // TODO: MARK: RE-EXAMINE NOW THAT THEORY SUPPORTS EVENTS.
|
||||
var event = {}, events = [];
|
||||
event.arg = (function(args,w,h){
|
||||
var m = {way:w,how:h};
|
||||
var jq = a.list(args.o).at(1);
|
||||
if(jq){
|
||||
m.where = jq.jquery? jq : $(jq);
|
||||
m.what = a.text.caps(a.list(args.t).at(1));
|
||||
}else{
|
||||
if(args.t.length == 2){
|
||||
m.what = a.text.caps(a.list(args.t).at(1));
|
||||
m.where = $(a.list(args.t).at(2));
|
||||
}else{
|
||||
m.where = $(a.list(args.t).at(1));
|
||||
}
|
||||
}
|
||||
m.cb = a.list(args.f).at(1);
|
||||
events.push(m);
|
||||
return m;
|
||||
});
|
||||
event.emit = (function(e){
|
||||
//console.log("--");
|
||||
a.list(events).each(function(v,i){
|
||||
if(v.way && e.way != v.way){
|
||||
return;
|
||||
}
|
||||
if(v.how && e.how != v.how){
|
||||
return;
|
||||
}
|
||||
if(v.what && a.text.caps(e.what) != v.what){
|
||||
return;
|
||||
}
|
||||
//console.log(e.way +" == "+ v.way +" :: "+ e.how +" == "+ v.how +" :: "+ e.what +" == "+ v.what);
|
||||
if(
|
||||
v.where[0] == window || v.where.is(document) ||
|
||||
$(e.where).closest(v.where.selector||v.where).length
|
||||
){
|
||||
v.cb(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
return event;
|
||||
})();
|
||||
the.mouse = (function(){
|
||||
function mouse(){ return mouse; }
|
||||
mouse.x = 0;
|
||||
mouse.y = 0;
|
||||
mouse.left = false;
|
||||
mouse.right = false;
|
||||
mouse.move = (function(e){
|
||||
var m = the.event.arg(a.fns.sort(a.list.slit.call(arguments, 0)),mouse.name,'move');
|
||||
});
|
||||
mouse.down = (function(e){
|
||||
var m = the.event.arg(a.fns.sort(a.list.slit.call(arguments, 0)),mouse.name,'down');
|
||||
});
|
||||
mouse.up = (function(h,fn,e){
|
||||
var m = the.event.arg(a.fns.sort(a.list.slit.call(arguments, 0)),mouse.name,'up');
|
||||
});
|
||||
mouse.click = (function(e){
|
||||
var m = the.event.arg(a.fns.sort(a.list.slit.call(arguments, 0)),mouse.name,'click');
|
||||
});
|
||||
mouse.dbl = (function(e){
|
||||
var m = the.event.arg(a.fns.sort(a.list.slit.call(arguments, 0)),mouse.name,'dbl');
|
||||
});
|
||||
mouse.point = (function(s,h,v){ // WARNING! This uses some potentially dangerous tricks which might not work for your page.
|
||||
var stack = [], d = [], c = 0, e, e_, b = $('body'), scroll = b.scrollTop(), x = true;
|
||||
if(document.elementFromPoint){
|
||||
while(x
|
||||
&& (e=the.mouse.at(h||the.mouse.horizontal,v||the.mouse.vertical))
|
||||
&& e.style && e.nodeName != 'HTML'
|
||||
){
|
||||
if(s && $ && $(e).is(s)){
|
||||
x = false;
|
||||
} if(e == e_){
|
||||
e.style.display = 'none';
|
||||
} else {
|
||||
w = e.style.cssText;
|
||||
e.style.width = e.style.maxWidth = e.style.minWidth =
|
||||
e.style.paddingLeft = e.style.paddingRight =
|
||||
e.style.marginLeft = e.style.marginRight =
|
||||
e.style.mouseStacker = 0;
|
||||
stack.push(e_=e);
|
||||
d.push(w)
|
||||
}
|
||||
}
|
||||
} else if(window.event) {
|
||||
stack.push(window.event.target);
|
||||
}
|
||||
a.list(stack).each(function(e,i){
|
||||
e.style.cssText = d[--i];
|
||||
});
|
||||
b.scrollTop(scroll);
|
||||
return stack;
|
||||
});
|
||||
mouse.poke = (function(e,t,c){
|
||||
if(!e.time && !t){ return 0 }
|
||||
if(e.time && e.time.scroll != $(document).scrollTop()){ return 0 } // TODO: BUG: Potential? HACK: if scroll pos changed since down, then no go.
|
||||
c = c || [];
|
||||
c[0] = c[0] || c[0] === 0? c[0] : the.mouse._x;
|
||||
c[1] = c[1] || c[1] === 0? c[1] : the.mouse._y;
|
||||
if(a.time.is() - (t||e.time.up) < the.touch.opt.dbl && (
|
||||
Math.abs(the.mouse.x - c[0]) <= the.touch.opt.radius
|
||||
&& Math.abs(the.mouse.y - c[1]) <= the.touch.opt.radius
|
||||
)){ return 2 }
|
||||
if(a.time.is() - (t||e.time.down) < the.touch.opt.click && (
|
||||
Math.abs(the.mouse.x - c[0]) <= the.touch.opt.radius
|
||||
&& Math.abs(the.mouse.y - c[1]) <= the.touch.opt.radius
|
||||
)){ return 1 }
|
||||
return 0;
|
||||
});
|
||||
mouse.hold = (function(e,r){
|
||||
if(!e.time){ return 0 }
|
||||
if(e.time.scroll != $(document).scrollTop()){ return 0 } // TODO: BUG: Potential? HACK: if scroll pos changed since down, then no go.
|
||||
if(Math.abs(the.mouse.x - the.mouse._x) <= (r||the.touch.opt.radius)
|
||||
&& Math.abs(the.mouse.y - the.mouse._y) <= (r||the.touch.opt.radius)
|
||||
){
|
||||
return a.time.is() - e.time.down;
|
||||
} return 0;
|
||||
});
|
||||
mouse.which = (function(e){
|
||||
if(e.way != 'mouse'){ return 'left' }
|
||||
function left(e){
|
||||
if (e.which) {
|
||||
if(e.which == 3) return false;
|
||||
else if(e.which == 1) return true;
|
||||
} else if (e.button) {
|
||||
if(e.button == 2) return false;
|
||||
else if(e.button == 1) return true;
|
||||
}
|
||||
}
|
||||
function right(e){
|
||||
return !left(e);
|
||||
}
|
||||
if(left(e)) {
|
||||
mouse.left = true;
|
||||
return "left";
|
||||
} else if(right(e)) {
|
||||
mouse.right = true;
|
||||
return "right";
|
||||
}
|
||||
});
|
||||
mouse.on = (function(){
|
||||
var on = {};
|
||||
on.time = {down:0,up:0};
|
||||
on.down = (function(e){
|
||||
if(!e) return false;
|
||||
e.way = mouse.name;
|
||||
e.how = 'down';
|
||||
e.where = e.target;
|
||||
e.what = mouse.which(e);
|
||||
e[e.what] = true;
|
||||
mouse._x = mouse.x;
|
||||
mouse._y = mouse.y;
|
||||
mouse.horizontal = e.clientX;
|
||||
mouse.vertical = e.clientY;
|
||||
on.time.down = a.time.is();
|
||||
on.time.scroll = $(document).scrollTop();
|
||||
the.event.emit(e);
|
||||
return true; // DETERMINE EXCEPTIONS
|
||||
});
|
||||
on.up = (function(e){
|
||||
if(!e) return false;
|
||||
e.way = mouse.name;
|
||||
e.where = e.target;
|
||||
e.what = mouse.which(e);
|
||||
e[e.what] = true;
|
||||
on.poke(e,on.time);
|
||||
e.how = 'up';
|
||||
e.time = on.time;
|
||||
the.event.emit(e,on.time);
|
||||
on.time.up = a.time.is();
|
||||
mouse[e.what] = false;
|
||||
return true;
|
||||
});
|
||||
on.move = (function(e){
|
||||
if(!e) return false;
|
||||
e.way = mouse.name;
|
||||
e.how = 'move';
|
||||
e.where = e.target;
|
||||
mouse.x_ = mouse.x;
|
||||
mouse.y_ = mouse.y;
|
||||
mouse.horizontal = e.clientX;
|
||||
mouse.vertical = e.clientY;
|
||||
if(e.pageX || e.pageY){
|
||||
mouse.x = e.pageX;
|
||||
mouse.y = e.pageY;
|
||||
mouse.target = e.target;
|
||||
} else if(e.clientX || e.clientY){
|
||||
mouse.x = e.clientX + document.body.scrollLeft
|
||||
+ document.documentElement.scrollLeft;
|
||||
mouse.y = e.clientY + document.body.scrollTop
|
||||
+ document.documentElement.scrollTop;
|
||||
mouse.target = e.srcElement;
|
||||
}
|
||||
the.event.emit(e);
|
||||
});
|
||||
on.poke = (function(e,t){ return });
|
||||
on.click = (function(e,p){
|
||||
if(!e) return false;
|
||||
e.how = 'click';
|
||||
e.where = e.where||e.target;
|
||||
e.what = mouse.which(e);
|
||||
e[e.what] = true;
|
||||
e.way = p? mouse.name : e.way||mouse.name;
|
||||
the.event.emit(e);
|
||||
mouse[e.what] = false;
|
||||
return true;
|
||||
});
|
||||
on.dbl = (function(e){
|
||||
if(!e) return false;
|
||||
e.way = e.way||mouse.name;
|
||||
e.how = 'dbl';
|
||||
e.where = e.where||e.target;
|
||||
e.what = mouse.which(e);
|
||||
e[e.what] = true;
|
||||
the.event.emit(e);
|
||||
mouse[e.what] = false;
|
||||
return true;
|
||||
});
|
||||
return on;
|
||||
})();
|
||||
return mouse;
|
||||
})();
|
||||
the.key = (function(){
|
||||
function key($){
|
||||
key.$ = $ !== undefined? $ : undefined;
|
||||
return key;
|
||||
}
|
||||
key.e = window.event;
|
||||
key.is = '';
|
||||
key._is = '';
|
||||
key.combo = [];
|
||||
key.trail = [];
|
||||
key.opt = {forget:1000};
|
||||
key.down = (function(h,fn,e){
|
||||
var m = key.on.arg(key.$, a.fns.sort(a.list.slit.call(arguments, 0)));
|
||||
m.down = m.cb;
|
||||
key.on.arch(m,key.on.down_,'-'); // this makes '-' unusuable if we're splitting on it, need to add option for this and handle runs, combos, etc.
|
||||
});
|
||||
key.hold = (function(h,fn,e){
|
||||
var m = key.on.arg(key.$, a.fns.sort(a.list.slit.call(arguments, 0)));
|
||||
m.hold = m.cb;
|
||||
key.on.arch(m,key.on.hold_,'-'); // same as above
|
||||
});
|
||||
key.up = (function(h,fn,e){
|
||||
var m = key.on.arg(key.$, a.fns.sort(a.list.slit.call(arguments, 0)));
|
||||
m.up = m.cb;
|
||||
key.on.arch(m,key.on.up_,'-'); // same as above
|
||||
});
|
||||
key.on = (function(m){
|
||||
var on = {}, level = [], arch;
|
||||
on.arg = (function(k, args){
|
||||
var m = {};
|
||||
m.key = k || a.text.caps(a.list(args.t).at(1));
|
||||
m.key = (m.key === '')? 'all' : m.key;
|
||||
m.cb = a.list(args.f).at(1);
|
||||
var jq = a.text.caps(a.list(args.o).at(1));
|
||||
if(jq){
|
||||
m.jq = jq.jquery? jq : $(jq);
|
||||
}else{
|
||||
jq = a.text.caps(a.list(args.t).at(2));
|
||||
jq = (jq === 'DOCUMENT')? window.document : (jq === 'WINDOW')? window : '';
|
||||
m.jq = $(jq);
|
||||
}
|
||||
return m;
|
||||
});
|
||||
on.down = (function(e){
|
||||
if(!e) return false;
|
||||
e.way = key.name;
|
||||
e.where = e.target;
|
||||
e.code = e.keyCode;
|
||||
e.tag = e.key = key._is = a.text.caps(key.tag(e));
|
||||
key.e = e;
|
||||
e.how = 'hold';
|
||||
key.on.emit(e,key.on.hold_);
|
||||
if(key.on[key._is]) return a("key.tame->")();
|
||||
key.e.how = e.how = 'down';
|
||||
key.on[key.is = key._is] = true;
|
||||
key.on.emit(e,key.on.down_);
|
||||
key.combo.push(key.is);
|
||||
key.trail.push(key.is);
|
||||
key.trail = key.trail.slice(-12);
|
||||
return a(the,"key.tame->")(e);
|
||||
});
|
||||
on.up = (function(e){
|
||||
if(!e) return false;
|
||||
e.way = key.name;
|
||||
e.how = 'up';
|
||||
e.where = e.target;
|
||||
e.code = e.keyCode;
|
||||
e.tag = e.key = key.is_ = a.text.caps(key.tag(e));
|
||||
key.e = e;
|
||||
key.on[key.is_] = false;
|
||||
key.combo = a.list(key.combo).each(function(v,i,t){
|
||||
if(v === key.is_){ return }
|
||||
t(v);
|
||||
})||[];
|
||||
key.on.emit(e,key.on.up_);
|
||||
key.is = '';
|
||||
return true; // DETERMINE EXCEPTIONS
|
||||
});
|
||||
on.arch = (function(m,w,s){
|
||||
var arch = w, al;
|
||||
m.key = a.text.caps(m.key);
|
||||
al = m.key.split(s);
|
||||
a.list(al).each(function(u,h){
|
||||
if(!a.obj.get(arch,u)){
|
||||
if(al.length == h){
|
||||
arch[u] = {map:m};
|
||||
}else{
|
||||
arch[u] = {};
|
||||
}
|
||||
}
|
||||
arch = arch[u];
|
||||
});
|
||||
});
|
||||
on.emit = (function(e,w){
|
||||
var r;
|
||||
a(w,'ALL.map.'+e.how+'->')(e);
|
||||
arch = a.list(level).at(-1)||w;
|
||||
if(r = arch[e.tag]){
|
||||
a.time.stop(on.forget);
|
||||
a(r,'map.'+e.how+'->')(e);
|
||||
if(a.obj(r).each(function(v,i){
|
||||
if(a.obj.is(v) && i != 'map') return true;
|
||||
})){
|
||||
level.push(r);
|
||||
}
|
||||
on.forget = a.time.wait(function(){
|
||||
level = [];
|
||||
},key.opt.forget);
|
||||
return;
|
||||
}
|
||||
});
|
||||
on.forget;
|
||||
on.down_ = {};
|
||||
on.hold_ = {};
|
||||
on.up_ = {};
|
||||
return on;
|
||||
})();
|
||||
key.tag = (function(code){
|
||||
if(!code) return false;
|
||||
code = (code.keyCode)?code.keyCode:code;
|
||||
code = (typeof code == 'number')? 'kc'+code:code;
|
||||
return key.special[code] || String.fromCharCode(a.num.ify(code.substring(2)));
|
||||
});
|
||||
key.code = (function(tag){
|
||||
if(!tag) return false;
|
||||
return (key.special[tag.toLowerCase()])? key.special[tag.toLowerCase()] : a.text.caps(tag).charCodeAt(0);
|
||||
});
|
||||
key.tame = function(){return !(key._is in key.strange)};
|
||||
key.strange = {' ':1,ERASE:1};
|
||||
key.reserved = {Z:1,X:1,C:1,V:1,R:1,T:1,N:1,F12:1,F11:1,PU:1,PD:1,pu:1,pd:1}; // reserved keys
|
||||
key.special = {
|
||||
'esc':27
|
||||
,'kc27': 'esc'
|
||||
,'tab':9
|
||||
,'kc9':'tab'
|
||||
,' ':32
|
||||
,'kc32':' '
|
||||
,'enter':13
|
||||
,'kc13':'enter'
|
||||
,'erase':8
|
||||
,'kc8': 'erase'
|
||||
|
||||
,'kc92':'\\'
|
||||
,'\\':92
|
||||
|
||||
,'scroll':145
|
||||
,'kc145':'scroll'
|
||||
,'caps':20
|
||||
,'kc20':'caps'
|
||||
,'num':144
|
||||
,'kc144':'num'
|
||||
|
||||
,'pause':19
|
||||
,'kc19':'pause'
|
||||
|
||||
,'insert':45
|
||||
,'kc45':'insert'
|
||||
,'home':36
|
||||
,'kc36':'home'
|
||||
,'delete':46
|
||||
,'kc46':'del'
|
||||
,'end':35
|
||||
,'kc35':'end'
|
||||
|
||||
,'pu':33
|
||||
,'kc33':'pu'
|
||||
|
||||
,'pd':34
|
||||
,'kc34':'pd'
|
||||
|
||||
,'left':37
|
||||
,'kc37':'left'
|
||||
|
||||
,'up':38
|
||||
,'kc38':'up'
|
||||
|
||||
,'right':39
|
||||
,'kc39':'right'
|
||||
|
||||
,'down':40
|
||||
,'kc40':'down'
|
||||
|
||||
,'shift':16
|
||||
,'kc16':'shift'
|
||||
,'ctrl':17
|
||||
,'kc17':'ctrl'
|
||||
,'alt':18
|
||||
,'kc18':'alt'
|
||||
,'¤':91
|
||||
,'cmd':91
|
||||
,'kc91':((the.os.is.win||the.os.is.lin||the.os.is.and)?'¤':'cmd')
|
||||
|
||||
,'kc91':'['
|
||||
,'[':91
|
||||
,'kc93':']'
|
||||
,']':93
|
||||
,'kc126':'`'
|
||||
,'`':126
|
||||
,'kc95':'-'
|
||||
,'-':95
|
||||
,'kc61':'='
|
||||
,'=':61
|
||||
,'kc59':';'
|
||||
,';':59
|
||||
,'kc222':"'"
|
||||
,"'":222
|
||||
,'kc47':'/'
|
||||
,'/':47
|
||||
,'kc62':'.'
|
||||
,'.':62
|
||||
,'kc44':','
|
||||
,',':44
|
||||
|
||||
,'f1':112
|
||||
,'kc112':'F1'
|
||||
,'f2':113
|
||||
,'kc113':'F2'
|
||||
,'f3':114
|
||||
,'kc114':'F3'
|
||||
,'f4':115
|
||||
,'kc115':'F4'
|
||||
,'f5':116
|
||||
,'kc116':'F5'
|
||||
,'f6':117
|
||||
,'kc117':'F6'
|
||||
,'f7':118
|
||||
,'kc118':'F7'
|
||||
,'f8':119
|
||||
,'kc119':'F8'
|
||||
,'f9':120
|
||||
,'kc120':'F9'
|
||||
,'f10':121
|
||||
,'kc121':'F10'
|
||||
,'f11':122
|
||||
,'kc122':'F11'
|
||||
,'f12':123
|
||||
,'kc123':'F12'
|
||||
};
|
||||
return key;
|
||||
})();
|
||||
the.touch = (function(){
|
||||
var touch = {};
|
||||
a.log(touch.name = 'touch');
|
||||
touch.opt = {
|
||||
click: 250
|
||||
,dbl: 500
|
||||
,radius: 50
|
||||
,mouse: true
|
||||
,react: true
|
||||
}
|
||||
touch.count = 0;
|
||||
touch.point = [{},{},{},{},{},{},{},{},{},{},{}];
|
||||
touch.move = (function(e){
|
||||
var m = the.event.arg(a.fns.sort(a.list.slit.call(arguments, 0)),touch.name,'move');
|
||||
});
|
||||
touch.down = (function(e){
|
||||
var m = the.event.arg(a.fns.sort(a.list.slit.call(arguments, 0)),touch.name,'down');
|
||||
});
|
||||
touch.up = (function(e){
|
||||
var m = the.event.arg(a.fns.sort(a.list.slit.call(arguments, 0)),touch.name,'up');
|
||||
});
|
||||
touch.gest = (function(b,c,fn){
|
||||
var gest = {};
|
||||
a.log(gest.name = 'gest');
|
||||
gest.angle = 0;
|
||||
gest.scale = 1.0;
|
||||
gest.start = (function(e){
|
||||
|
||||
});
|
||||
gest.morph = (function(e){
|
||||
gest.angle = e.rotation;
|
||||
gest.scale = e.scale;
|
||||
$(document).trigger('touch/gest/morph');
|
||||
});
|
||||
gest.end = (function(e){
|
||||
|
||||
});
|
||||
return gest;
|
||||
})();
|
||||
touch.time = {down:0,up:0};
|
||||
touch.on = (function(){
|
||||
var on = {};
|
||||
on.down = (function(e){
|
||||
the.mouse.target = false;
|
||||
var multi = e.touches || [{}], on = e.changedTouches;
|
||||
the.mouse._x = the.mouse.x_ = the.mouse.x = multi[0].pageX;
|
||||
the.mouse._y = the.mouse.y_ = the.mouse.y = multi[0].pageY;
|
||||
the.mouse.horizontal = multi[0].clientX;
|
||||
the.mouse.vertical = multi[0].clientY;
|
||||
touch.count = multi.length;
|
||||
a.list(multi).each(function(v,i){
|
||||
v._x = v.x_ = v.x = v.pageX;
|
||||
v._y = v.y_ = v.y = v.pageY;
|
||||
touch.point[v.id = i] = v||{};
|
||||
});
|
||||
e.way = touch.name;
|
||||
e.what = touch.count;
|
||||
e.where = multi[0].target;
|
||||
e.stun = jQuery.Event.stun;
|
||||
e.stop = jQuery.Event.stop;
|
||||
e.how = 'down';
|
||||
touch.time.down = a.time.is();
|
||||
touch.time.scroll = $(document).scrollTop();
|
||||
the.event.emit(e);
|
||||
});
|
||||
on.move = (function(e){
|
||||
var multi = e.touches || [{}];
|
||||
the.mouse.x = the.mouse.x_ = multi[0].pageX;
|
||||
the.mouse.y = the.mouse.y_ = multi[0].pageY;
|
||||
the.mouse.horizontal = multi[0].clientX;
|
||||
the.mouse.vertical = multi[0].clientY;
|
||||
a.list(multi).each(function(v,i){
|
||||
v.x = v.x_ = v.pageX;
|
||||
v.y = v.y_ = v.pageY;
|
||||
if(!v.id) touch.point[v.id = i] = v||{}; // Android does not update without this.
|
||||
});
|
||||
e.way = touch.name;
|
||||
e.how = 'move';
|
||||
e.where = multi[0].target;
|
||||
e.what = touch.count;
|
||||
e.stun = jQuery.Event.stun;
|
||||
e.stop = jQuery.Event.stop;
|
||||
the.event.emit(e);
|
||||
});
|
||||
on.up = (function(e){
|
||||
var t = a.time.is(), multi = e.changedTouches;
|
||||
e.what = touch.count;
|
||||
if((touch.count = multi.length) == 0){
|
||||
touch.point = [{},{},{},{},{},{},{},{},{},{},{}];
|
||||
}
|
||||
e.way = touch.name;
|
||||
e.where = multi[0].target;
|
||||
e.stun = jQuery.Event.stun;
|
||||
e.stop = jQuery.Event.stop;
|
||||
if(touch.count === 1){ the.mouse.on.poke(e,touch.time) }
|
||||
e.how = 'up';
|
||||
e.time = touch.time;
|
||||
the.event.emit(e);
|
||||
touch.time.up = a.time.is();
|
||||
});
|
||||
return on;
|
||||
})();
|
||||
touch.feel = (function(e){
|
||||
touch.opt.react = e = a.bi.is(e)?e:!touch.opt.react;
|
||||
if(e){
|
||||
try{
|
||||
document.addEventListener("touchmove", touch.on.move, true);
|
||||
document.addEventListener('touchstart', touch.on.down, true);
|
||||
document.addEventListener('touchend', touch.on.up, true);
|
||||
document.addEventListener("gesturechange", touch.gest.morph, true);
|
||||
document.addEventListener('gesturestart', touch.gest.start, true);
|
||||
document.addEventListener('gestureend', touch.gest.end, true);
|
||||
}catch(e){
|
||||
}
|
||||
} else {
|
||||
console.log('touchless ?');
|
||||
try{
|
||||
document.removeEventListener("touchmove", touch.on.move, true);
|
||||
document.removeEventListener('touchstart', touch.on.down, true);
|
||||
document.removeEventListener('touchend', touch.on.up, true);
|
||||
document.removeEventListener("gesturechange", touch.gest.morph, true);
|
||||
document.removeEventListener('gesturestart', touch.gest.start, true);
|
||||
document.removeEventListener('gestureend', touch.gest.end, true);
|
||||
}catch(e){
|
||||
}
|
||||
}
|
||||
});
|
||||
return touch;
|
||||
})();
|
||||
the.drag = (function(){
|
||||
var drag = {};
|
||||
a.log(drag.name = 'drag');
|
||||
drag.enter = (function(e){
|
||||
$(document).trigger('dragenter',[e]);
|
||||
});
|
||||
drag.over = (function(e){
|
||||
$(document).trigger('dragover',[e]);
|
||||
});
|
||||
drag.drop = (function(e){
|
||||
$(document).trigger('mousemove',[e]);
|
||||
$(document).trigger('dragdrop',[e]);
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
drag.change = (function(e){
|
||||
$(document).trigger('dragchange',[e]);
|
||||
});
|
||||
return drag;
|
||||
})();
|
||||
the.doc = doc = {}
|
||||
/** -------- INITIATE JQUERY BINDINGS -------- **/
|
||||
if(root.page){
|
||||
$(document).ready(function(){
|
||||
jQuery.Event.stun = (function(e){(e||this).preventDefault();return (e||this)});
|
||||
jQuery.Event.stop = (function(e){(e||this).stopPropagation();return (e||this)});
|
||||
jQuery.Event.prototype.stun = jQuery.Event.stun;
|
||||
jQuery.Event.prototype.stop = jQuery.Event.stop;
|
||||
$(document).scroll(function(e){
|
||||
//the.touch.scroll = a.time.is(); iOS calls scroll after touch/mouse events.
|
||||
}).mousemove(function(e,el){
|
||||
if(el) e = el;
|
||||
if(!e) var e = window.event;
|
||||
e.stopPropagation();e.preventDefault();
|
||||
the.mouse.on.move(e);
|
||||
}).mousedown(function(e){
|
||||
if(!e) var e = window.event;
|
||||
if(the.mouse.on.down(e)){
|
||||
return true;
|
||||
}
|
||||
e.stopPropagation();e.preventDefault();
|
||||
}).mouseup(function(e){
|
||||
if(!e) var e = window.event;
|
||||
if(the.mouse.on.up(e)){
|
||||
return true;
|
||||
}
|
||||
e.stopPropagation();e.preventDefault();
|
||||
}).click(function(e){ // iOS only emits on clickable elements
|
||||
the.mouse.on.click(e);
|
||||
}).dblclick(function(e){
|
||||
the.mouse.on.dbl(e);
|
||||
}).keydown(function(e){
|
||||
if(the.key.on.down(e)){ return true }
|
||||
}).keyup(function(e){
|
||||
if(the.key.on.up(e)){ return true }
|
||||
});
|
||||
/** -- DEFAULT SETTINGS -- **/
|
||||
$(document).on('focus',"textarea, input, [contenteditable=true]",function(){
|
||||
the.key.combo = []; // iOS not trigger 'keyup' sometimes on input exits, so clear combo manually.
|
||||
the.key.tame = function(){return true};
|
||||
}).on('blur',"textarea, input, [contenteditable=true]",function(){
|
||||
the.key.combo = []; // iOS not trigger 'keyup' sometimes on input exits, so clear combo manually.
|
||||
the.key.tame = function(){return false}; // PREVENT UNLOAD & SCROLL BOTTOM
|
||||
});
|
||||
(document.body||{}).onorientationchange = the.device.rotate;
|
||||
});
|
||||
(function(window){
|
||||
the.touch.feel(the.touch.opt.react);
|
||||
try{
|
||||
document.addEventListener('dragenter', the.drag.enter, false);
|
||||
document.addEventListener("change", the.drag.change, false);
|
||||
document.addEventListener('drop', the.drag.drop, false);
|
||||
document.addEventListener('dragover', the.drag.over, false);
|
||||
}catch(e){console.log("drag fail", e);};
|
||||
function afocus(e){
|
||||
if(e) if(e.target != window) return true;
|
||||
the.key.combo = [];
|
||||
};
|
||||
document.onfocusin = afocus;
|
||||
window.onfocus = afocus;
|
||||
})(window);
|
||||
}
|
||||
return the;
|
||||
});
|
||||
return discrete;
|
||||
})());
|
2
deps/jquery.js
vendored
30
deps/key/LTIE9.css
vendored
@ -1,30 +0,0 @@
|
||||
/* IE6 POSITON: FIXED; FLICKER: NONE; */
|
||||
*html body,*html html{background-image:url(about:blank);background-attachment:fixed;}
|
||||
|
||||
*html #keys-top{
|
||||
position: absolute;
|
||||
top:expression(eval(document.compatMode&&document.compatMode=='CSS1Compat')?
|
||||
documentElement.scrollTop+((0))
|
||||
:document.body.scrollTop+((0)));
|
||||
}
|
||||
*html #keys-main{
|
||||
position: absolute;
|
||||
top:expression(eval(document.compatMode&&document.compatMode=='CSS1Compat')?
|
||||
documentElement.scrollTop+((documentElement.clientHeight-this.clientHeight))
|
||||
:document.body.scrollTop+((document.body.clientHeight-this.clientHeight)));
|
||||
}
|
||||
*html #keyboard {
|
||||
position: fixed;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
.keyboard li {
|
||||
background: black;
|
||||
background: white;
|
||||
}
|
151
deps/key/key.css
vendored
@ -1,151 +0,0 @@
|
||||
#keyface{
|
||||
z-index: 99999999;
|
||||
}
|
||||
#keyput {
|
||||
display: none;
|
||||
text-align: center;
|
||||
width: 240px;
|
||||
margin-left: -120px;
|
||||
padding: .5em 0;
|
||||
border: none;
|
||||
z-index: 9999;
|
||||
|
||||
background-color: rgba(100%,100%,100%,.65);
|
||||
border-radius: 7px;
|
||||
-moz-border-radius: 7px;
|
||||
-webkit-border-radius: 7px;
|
||||
-moz-box-shadow: #6FA1D9 0px 0px 10px -2px inset;
|
||||
-webkit-box-shadow: #6FA1D9 0px 0px 10px -2px inset;
|
||||
box-shadow: #6FA1D9 0px 0px 10px -2px inset;
|
||||
}#keyput:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#keyboard, .keyboard {
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
width: 0px;
|
||||
bottom: 0px;
|
||||
left: 50%;
|
||||
right: 50%;
|
||||
z-index: 99999999;
|
||||
font-family: 'Trebuchet MS', sans-serif;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
.key-a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.punc {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.key-offset {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.keyboard ul {
|
||||
position:relative;
|
||||
list-style-type: none;
|
||||
clear: both;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
d-isplay: none;
|
||||
}
|
||||
.keyboard li, .keyboard .key {
|
||||
display: none;
|
||||
float:left;
|
||||
min-width: 2em;
|
||||
padding: .4em .4em;
|
||||
margin: .2em;
|
||||
text-align: center;
|
||||
text-shadow: none;
|
||||
border-radius: 7px;
|
||||
-moz-border-radius: 7px;
|
||||
-webkit-border-radius: 7px;
|
||||
-moz-box-shadow: #6FA1D9 0px 0px 10px -2px;
|
||||
-webkit-box-shadow: #6FA1D9 0px 0px 10px -2px;
|
||||
box-shadow: #6FA1D9 0px 0px 10px -2px;
|
||||
|
||||
color: white;
|
||||
background-color: rgba(0,0,0,.75);
|
||||
|
||||
color: #999;
|
||||
background-color: rgba(100%,100%,100%,.65);
|
||||
}
|
||||
|
||||
#keys-top {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
overflow: visible;
|
||||
b-ackground: rgba(0,0,0,.5);
|
||||
}
|
||||
|
||||
#keys-main {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: visible;
|
||||
b-ackground: rgba(0,0,0,.5);
|
||||
max-height: 150px; /* Bug? Prevent Jumpyness */
|
||||
}
|
||||
|
||||
#keys-left {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 0;
|
||||
b-ackground: green;
|
||||
}
|
||||
|
||||
#keys {
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
b-ackground: blue;
|
||||
}
|
||||
|
||||
#keys-right {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 0;
|
||||
b-ackground: red;
|
||||
}
|
||||
.key-rowR {
|
||||
float: right;
|
||||
}
|
||||
.key-bumpL {
|
||||
margin-left: -35px;
|
||||
}
|
||||
.key-mtextc {
|
||||
margin: 0px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#instr {
|
||||
text-align: center;
|
||||
font-family: 'Trebuchet MS', sans-serif;
|
||||
text-rendering: optimizeLegibility;
|
||||
text-shadow: 10px 10px 25px rgba(100%,100%,100%,.9)
|
||||
,-5px -5px 25px rgba(100%,100%,100%,.9)
|
||||
,-5px 10px 25px rgba(100%,100%,100%,.9)
|
||||
,10px -5px 25px rgba(100%,100%,100%,.9);
|
||||
box-shadow: none;
|
||||
color: white;
|
||||
color: black;
|
||||
background: rgba(0,0,0,.25);
|
||||
background: transparent;
|
||||
font-size: 12pt;
|
||||
padding: 2px 0px;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
.show {
|
||||
display: block;
|
||||
}
|
131
deps/key/key.html
vendored
@ -1,131 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div id="keyboard" class="keyboard" style="display: none;">
|
||||
<!--[if lt IE 9]>
|
||||
<link rel="stylesheet" href="/+/key/LTIE9.css">
|
||||
<![endif]-->
|
||||
<div id="keys-top">
|
||||
<ul id="kt1">
|
||||
<li id="kc27" class="alphanum lhand">esc</li>
|
||||
<li id="kc112" class="alphanum lhand">F1</li>
|
||||
<li id="kc113" class="alphanum lhand">F2</li>
|
||||
<li id="kc114" class="alphanum lhand">F3</li>
|
||||
<li id="kc115" class="alphanum lhand">F4</li>
|
||||
<li id="kc116" class="alphanum lhand">F5</li>
|
||||
<li id="kc117" class="alphanum lhand">F6</li>
|
||||
<li id="kc118" class="alphanum rhand">F7</li>
|
||||
<li id="kc119" class="alphanum rhand">F8</li>
|
||||
<li id="kc120" class="alphanum rhand">F9</li>
|
||||
<li id="kc121" class="alphanum rhand">F10</li>
|
||||
<li id="kc122" class="alphanum rhand">F11</li>
|
||||
<li id="kc123" class="alphanum rhand">F12</li>
|
||||
</ul>
|
||||
<ul id="kt2" class="key-bumpL">
|
||||
<li style="min-width: 1.9em;" id="kc126">`</li>
|
||||
<li id="kc49" class="alphanum lhand">1</li>
|
||||
<li id="kc50" class="alphanum lhand">2</li>
|
||||
<li id="kc51" class="alphanum lhand">3</li>
|
||||
<li id="kc52" class="alphanum lhand">4</li>
|
||||
<li id="kc53" class="alphanum lhand">5</li>
|
||||
<li id="kc54" class="alphanum lhand">6</li>
|
||||
<li id="kc55" class="alphanum rhand">7</li>
|
||||
<li id="kc56" class="alphanum rhand">8</li>
|
||||
<li id="kc57" class="alphanum rhand">9</li>
|
||||
<li id="kc48" class="alphanum rhand">0</li>
|
||||
<li id="kc95" class="alphanum rhand">-</li>
|
||||
<li id="kc61" class="alphanum rhand">=</li>
|
||||
<li class="mod" style="text-align: right; min-width: 3.5em;" id="kc8">erase</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="keys-main">
|
||||
<div id="keys-left">
|
||||
<ul id="kl1">
|
||||
<li class="mod" style="text-align: left; min-width: 3.2em;" id="kc9">tab</li>
|
||||
</ul>
|
||||
|
||||
<ul id="kl2">
|
||||
<li class="mod" style="text-align: left; min-width: 3.75em;" id="kc20">caps</li>
|
||||
</ul>
|
||||
<ul id="kl3">
|
||||
<li class="mod" style="text-align: left; min-width: 5.3em;" id="kc16">shift</li>
|
||||
</ul>
|
||||
<ul id="kl4">
|
||||
<li class="mod" style="text-align: left; min-width:50px" id="kc17">ctrl</li>
|
||||
<li class="mod" style="min-width: 3.2em;" id="kc91">¤</li>
|
||||
<li class="mod" style="min-width: 3.2em;" id="kc18">alt</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="instr" class="key-mtextc">
|
||||
<span class="instr"></span>
|
||||
</div>
|
||||
<div id="keys">
|
||||
<ul id="kp1">
|
||||
<li id="kc81" class="alphanum lhand">Q</li>
|
||||
<li id="kc87" class="alphanum lhand">W</li>
|
||||
<li id="kc69" class="alphanum lhand">E</li>
|
||||
<li id="kc82" class="alphanum lhand">R</li>
|
||||
<li id="kc84" class="alphanum lhand">T</li>
|
||||
<li id="kc89" class="alphanum rhand">Y</li>
|
||||
<li id="kc85" class="alphanum rhand">U</li>
|
||||
<li id="kc73" class="alphanum rhand">I</li>
|
||||
<li id="kc79" class="alphanum rhand">O</li>
|
||||
<li id="kc80" class="alphanum rhand">P</li>
|
||||
<li id="kc91" class="alphanum rhand punc">[</li>
|
||||
<li id="kc93" class="alphanum rhand punc">]</li>
|
||||
<li id="kc92" class="alphanum rhand punc">\</li>
|
||||
</ul>
|
||||
<ul id="kp2">
|
||||
<li class="key-offset" style="min-width:8px;padding:1px;margin:0px;"></li>
|
||||
<li id="kc65" class="alphanum lhand">A</li>
|
||||
<li id="kc83" class="alphanum lhand">S</li>
|
||||
<li id="kc68" class="alphanum lhand">D</li>
|
||||
<li id="kc70" class="alphanum lhand">F</li>
|
||||
<li id="kc71" class="alphanum lhand">G</li>
|
||||
<li id="kc72" class="alphanum rhand">H</li>
|
||||
<li id="kc74" class="alphanum rhand">J</li>
|
||||
<li id="kc75" class="alphanum rhand">K</li>
|
||||
<li id="kc76" class="alphanum rhand">L</li>
|
||||
<li id="kc59" class="alphanum rhand punc">;</li>
|
||||
<li id="kc222" class="alphanum rhand punc">'</li>
|
||||
</ul>
|
||||
<ul id="kp3">
|
||||
<li class="key-offset" style="min-width:33px;padding:1px;margin:0px;"></li>
|
||||
<li id="kc90" class="alphanum lhand">Z</li>
|
||||
<li id="kc88" class="alphanum lhand">X</li>
|
||||
<li id="kc67" class="alphanum lhand">C</li>
|
||||
<li id="kc86" class="alphanum lhand">V</li>
|
||||
<li id="kc66" class="alphanum lhand">B</li>
|
||||
<li id="kc78" class="alphanum rhand">N</li>
|
||||
<li id="kc77" class="alphanum rhand">M</li>
|
||||
<li id="kc44" class="alphanum rhand punc">,</li>
|
||||
<li id="kc62" class="alphanum rhand punc">.</li>
|
||||
<li id="kc47" class="alphanum rhand punc">/</li>
|
||||
</ul>
|
||||
<input id="keyput"/>
|
||||
</div>
|
||||
<div id="keys-right">
|
||||
<ul id="kr1" class="key-rowR">
|
||||
<li class="mod rhand" style="text-align: right; min-width: 4.5em;" id="kc13">enter</li>
|
||||
</ul>
|
||||
<ul id="kr2" class="key-rowR">
|
||||
<li class="mod rhand" style="text-align: right; min-width: 5.9em; float: none;" id="kc16">shift</li>
|
||||
<li id="kc38" class="arrow">↑</li>
|
||||
<!--
|
||||
-->
|
||||
</ul>
|
||||
<ul id="kr3" class="key-rowR">
|
||||
<li class="mod" style="min-width: 3.2em;" id="kc18">alt</li>
|
||||
<li class="mod" style="min-width: 3.2em;" id="kc91">¤</li>
|
||||
<li class="mod" style="min-width: 3.2em;" id="kc17">ctrl</li>
|
||||
<li id="kc37" class="arrow">←</li>
|
||||
<li id="kc40" class="arrow">↓</li>
|
||||
<li id="kc39" class="arrow">→</li>
|
||||
<!--
|
||||
-->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
185
deps/key/key.js
vendored
@ -1,185 +0,0 @@
|
||||
module.exports=require('theory')((function(){
|
||||
var key = {};
|
||||
key.name = 'key';
|
||||
key.author = 'Mark';
|
||||
key.version = 4;
|
||||
root.opts.kiwi = root.opts.kiwi||{};
|
||||
key.deps = ['../discrete'];
|
||||
key.init = (function(a){
|
||||
var the = a.discrete || theory.discrete;
|
||||
$(document).ready(function(){
|
||||
root.opts.key = root.opts.key || {};
|
||||
var kf = $("#keyface"), h = root.opts.key.host||'';
|
||||
if(!kf.length){
|
||||
$("body").append("<div id='keyface'></div>");
|
||||
$('head').append('<link rel="stylesheet" href="'+h+'/key/key.css">');
|
||||
kf = $('#keyface').load(h+"/key/key.html",function(){
|
||||
r.init();
|
||||
});
|
||||
} else {
|
||||
r.init();
|
||||
}
|
||||
});
|
||||
var doc = {
|
||||
skin: {
|
||||
a: {color:'#000'}
|
||||
,on: {}
|
||||
,dull: {color:'#999'}
|
||||
,scale: {
|
||||
touch: {'font-size':'1.25em'}
|
||||
,key: {'font-size':'1em'}
|
||||
}
|
||||
,slide: {
|
||||
up: 175
|
||||
,down: 200
|
||||
}
|
||||
}
|
||||
}, realboard = (function(){ return !the.device.is.oriented })
|
||||
layout = (function(doc){
|
||||
var lo = {};
|
||||
lo.doc = doc||{};
|
||||
lo.size = {};
|
||||
lo.kb = $("#keyboard");
|
||||
lo.kt = $("#keys-top");
|
||||
lo.km = $("#keys-main");
|
||||
lo.kl = $("#keys-left");
|
||||
lo.kr = $("#keys-right");
|
||||
lo.k = $("#keys");
|
||||
lo.widths = (function(){
|
||||
var r = {};
|
||||
r.lx = lo.width(lo.kl,{max:true,out:true})||0;
|
||||
r.kx = lo.width(lo.k,{max:true,out:true})||0;
|
||||
r.rx = lo.width(lo.kr,{max:true,out:true})||0;
|
||||
r.tx = lo.width(lo.kt,{max:true,out:true})||0;
|
||||
return r;
|
||||
});
|
||||
lo.set = function(e,c){
|
||||
lo.size.x = $(document).width();
|
||||
lo.size.o = lo.size.x/2;
|
||||
lo.size.max = lo.widths();
|
||||
lo.k.css({ width: lo.size.max.kx, 'margin-left': 'auto', 'margin-right':'auto' });
|
||||
lo.kt.css({ width: lo.size.max.tx, left: lo.size.o - lo.size.max.tx/2 });
|
||||
//console.log(lo.size.max.kx);
|
||||
var bk = lo.k.find("ul.key-row-a").last().find("li:visible").not(".key-offset")
|
||||
,bkflp = (bk.first().position()||{left:0}).left
|
||||
,bkfl = (lo.k.offset()||{left:0}).left + bkflp;
|
||||
//console.log(bkfl +" < "+ lo.size.max.lx);
|
||||
if(bkfl < lo.size.max.lx){
|
||||
if(!c && realboard()){
|
||||
if(lo.size.x <= (lo.size.max.lx - bkflp) + lo.size.max.kx || lo.size.x <= lo.size.max.tx
|
||||
|| lo.size.x - lo.size.max.rx <= ((bk.last().offset()||{left:0}).left + bk.last().outerWidth(true))
|
||||
){
|
||||
lo.kb.find("li:not(.key-a)").hide();
|
||||
return lo.set(e,true);
|
||||
}
|
||||
}
|
||||
lo.k.css({'margin-left': lo.size.max.lx - bkflp });
|
||||
}
|
||||
};
|
||||
lo.width = function(a,b){
|
||||
var x = 1, aa = a.children("ul.key-row-a").first(), b = b||{};
|
||||
b.out = b.out||false;
|
||||
b.max = b.max||false;
|
||||
b.filter = b.filter||':visible';
|
||||
a.children("ul.key-row-a").each(function(){
|
||||
aa = (aa.children('li'+b.filter).length < $(this).children('li'+b.filter).length)?
|
||||
((b.max)? $(this) : aa) : ((b.max)? aa : $(this));
|
||||
});
|
||||
aa.children('li'+b.filter).each(function(){
|
||||
x += Math.ceil($(this).outerWidth(b.out)||1);
|
||||
});
|
||||
return ++x;
|
||||
}
|
||||
lo.track = function(i){
|
||||
lo.set();
|
||||
lo.doc.initset = true;
|
||||
$(window).resize(lo.set);
|
||||
}
|
||||
return lo;
|
||||
}),
|
||||
r = (function(m){
|
||||
var k = {};
|
||||
k.map = (function(o){
|
||||
var tag, code, s, j, x = 1, d, row, rowi, ul = {}, punc = {}, uls = {}
|
||||
,npunc = ":not(.punc)", w = $(document).width();
|
||||
k.go = true;
|
||||
k.wipe(function(){
|
||||
k.go = false;
|
||||
a.obj(o).each(function(v,i){
|
||||
if(!v || v.key || i === 'tag'){ return }
|
||||
tag = a.text.caps(i);
|
||||
code = the.key.code(tag);
|
||||
tag = $.isFunction(v.tag)? v.tag() : (v.tag||v||undefined);
|
||||
j = $("#kc"+code).show().addClass('key-a').css(doc.skin.a).html(tag);
|
||||
//console.log(" - "+j.outerWidth(true));
|
||||
row = j.closest('ul').addClass('key-row-a');
|
||||
d = d || row;
|
||||
rowi = row.attr('id');
|
||||
ul[rowi] = row;
|
||||
if(j.is('.punc')){
|
||||
npunc = "";
|
||||
}
|
||||
});
|
||||
if(realboard()){
|
||||
//x = layout.width(,{out:true,filter: npunc});
|
||||
a.obj(ul).each(function(v,i){
|
||||
d = (d.children('li'+npunc).length < v.children('li'+npunc).length)?
|
||||
v : d;
|
||||
});
|
||||
(d||$()).children("li"+npunc).each(function(){ // + npunc possibly wrong! actually most def is.
|
||||
x += Math.ceil($(this).outerWidth(true)||1);
|
||||
});
|
||||
}
|
||||
a.obj(ul).each(function(v,i){
|
||||
if(realboard() && x < w){
|
||||
v.children('li'+npunc).show();
|
||||
}
|
||||
v.slideDown(doc.skin.slide.down);
|
||||
});
|
||||
k.layout();
|
||||
});
|
||||
return true;
|
||||
});
|
||||
k.wipe = (function(fn){
|
||||
if(!k || !k.b){ return }
|
||||
if(!k.on){ k.on = k.b.show() }
|
||||
k.$put.blur().hide().val('');
|
||||
var c = 0, l;
|
||||
l = k.$rows.stop(true,true).removeClass('key-row-a').removeAttr('style').length;
|
||||
k.$rows.slideUp(doc.skin.slide.up,function(){
|
||||
$(this).empty().append(k.row[$(this).attr('id')].clone());
|
||||
}).promise().done(fn);
|
||||
});
|
||||
k.instr = (function(s){
|
||||
if(!s) return false;
|
||||
k.$instr.stop(true,true).slideUp(function(){
|
||||
k.$instr.slideDown().children('.instr').html(s).show();
|
||||
});
|
||||
return;
|
||||
});
|
||||
k.row = {};
|
||||
k.clone = (function(){
|
||||
k.$rows.each(function(){
|
||||
k.row[$(this).attr('id')] = $(this).contents().clone();
|
||||
});
|
||||
});
|
||||
k.init = (function(){
|
||||
k.on = false;
|
||||
k.b = $("#keyboard");
|
||||
k.$rows = $("#keyboard ul");
|
||||
k.$instr = $("#instr");
|
||||
k.$put = $("#keyput");
|
||||
$(document).trigger('keyboard');
|
||||
k.clone();
|
||||
k.lo = layout(doc);
|
||||
k.lo.track();
|
||||
});
|
||||
k.layout = (function(){
|
||||
k.lo && k.lo.set && k.lo.set();
|
||||
});
|
||||
return k;
|
||||
});r=r();
|
||||
return r;
|
||||
});
|
||||
return key;
|
||||
})());
|
928
deps/theory.js
vendored
@ -1,928 +0,0 @@
|
||||
/** THEORY **/
|
||||
;var theory=theory||null;if(theory){root.init()}else{
|
||||
theory=(function(b,c,fn){
|
||||
function theory(b,c){
|
||||
var a = (function(b,c){
|
||||
var a = a||theory, l = arguments.length;
|
||||
if(l == 1){
|
||||
if(a.text.is(b)){
|
||||
return a.obj.get(a,b);
|
||||
}
|
||||
} if(l == 2){
|
||||
if(a.text.is(c)){
|
||||
return a.obj.get(b,c);
|
||||
}
|
||||
}
|
||||
});
|
||||
if(this && theory.bi.is(this)){ return theorize(a) }
|
||||
return a(b,c);
|
||||
} var $, _;
|
||||
function theorize(a){
|
||||
var $=undefined,_=undefined;
|
||||
a.log = (function(s){
|
||||
//console.log(s);
|
||||
return a.log;
|
||||
});
|
||||
a.fns = (function(){
|
||||
function fns($){
|
||||
fns.$_ = $ !== undefined? $ : _;
|
||||
return fns;
|
||||
} var $;
|
||||
fns.is = (function(fn){
|
||||
$ = fns.$_;fns.$_=_;fn = $||fn;
|
||||
return (fn instanceof Function)? true : false;
|
||||
});
|
||||
fns.flow = (function(s,f){ // TODO: BUG: Seriously reconsider then().done() because they fail on .end() after a synchronous callback, provide no doc or support for it until you do.
|
||||
var t = (function(){
|
||||
var args = a.list.slit.call(arguments,0), n;
|
||||
args.push(t);
|
||||
n = (function(){
|
||||
(t.list[t.i++] || t.end).apply(t,args);
|
||||
})();
|
||||
return t;
|
||||
}), list = a.list.is(s)? s : a.list.is(f)? f : 0;
|
||||
f = a.fns.is(f)? f : a.fns.is(s)? s : function(){};
|
||||
t.end = list? f : function(){}; // TODO: Receives `next` as param, is this desirable?
|
||||
t.then = (function(fn){
|
||||
if(a.fns.is(fn)){ t.list.push(fn) }
|
||||
return t;
|
||||
});
|
||||
t.done = (function(fn){
|
||||
t.end = a.fns.is(fn)? fn : t.end;
|
||||
return t;
|
||||
});
|
||||
t.list = list || [];
|
||||
t.i = 0;
|
||||
if(list){ t() }
|
||||
else{ f(t) }
|
||||
return t;
|
||||
});
|
||||
fns.sort = (function(args){
|
||||
if(!args){ return {e:"Empty"} }
|
||||
var args = a.list.slit.call(args, 0), r = {b:[],n:[],t:[],l:[],o:[],f:[]};
|
||||
for(var i = 0; i < args.length; i++){
|
||||
if (fns.is(args[i])){
|
||||
r.f.push(args[i]);
|
||||
} else if(a.list.is(args[i])){
|
||||
r.l.push(args[i]);
|
||||
} else if(a.obj.is(args[i])){
|
||||
r.o.push(args[i]);
|
||||
} else if(a.num.is(args[i])){
|
||||
r.n.push(args[i]);
|
||||
} else if(a.text.is(args[i])){
|
||||
r.t.push(args[i]);
|
||||
} else if(a.bi.is(args[i])){
|
||||
r.b.push(args[i]);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
});
|
||||
fns.$ = (function(t,v){
|
||||
v = t.$;
|
||||
t.$=_;
|
||||
return v;
|
||||
});
|
||||
fns.pass = (function(fn,o){
|
||||
$ = fns.$_;fns.$_=_;if($){ o=fn;fn=$ }
|
||||
if(a.text.is(o)){ var tmp = a(fn,o); o = fn; fn = tmp }
|
||||
if(!fns.is(fn)){ return _ }
|
||||
return (function(){
|
||||
return fn.apply(o, a.list.slit.call(arguments));
|
||||
});
|
||||
});
|
||||
return fns;
|
||||
})();
|
||||
a.list = (function(){
|
||||
function list($){
|
||||
list.$ = $ !== undefined? $ : _;
|
||||
return list;
|
||||
} var $;
|
||||
list.is = (function(l){
|
||||
l = a.fns.$(list)||l;
|
||||
return (l instanceof Array)? true : false;
|
||||
});
|
||||
list.slit = Array.prototype.slice;
|
||||
list.at = (function(l,i,opt){
|
||||
var r;
|
||||
if($=a.fns.$(list)){ opt=i;i=l;l=$ }
|
||||
if(!l||!i){ return undefined }
|
||||
if(a.text.is(l)){ l = l.split('') }
|
||||
if(i < 0){
|
||||
r = l.slice().reverse();
|
||||
i = Math.abs(i);
|
||||
} opt = opt || {};
|
||||
if(opt.ebb){
|
||||
for(--i; 0 <= i; i--){ // upgrade to functionalize
|
||||
if(r && r[i] !== undefined){ return r[i] }
|
||||
else if(l[i] !== undefined){ return l[i] }
|
||||
} return undefined;
|
||||
}
|
||||
return (r||l)[--i];
|
||||
});
|
||||
list.ify = (function(l,opt){
|
||||
if($=a.fns.$(list)){ opt=l;l=$ }
|
||||
opt=opt||{};
|
||||
opt.wedge = opt.wedge||':';
|
||||
opt.split = opt.split||',';
|
||||
var r = [];
|
||||
if(a.list.is(l)){
|
||||
return l;
|
||||
} else
|
||||
if(a.text.is(l)){
|
||||
var r = new RegExp("\\s*\\"+opt.split+"\\s*",'ig');
|
||||
return l.split(r);
|
||||
} else
|
||||
if(a.obj.is(l)){
|
||||
a.obj(l).each(function(v,i){
|
||||
r.push(i+opt.wedge+(a.obj.is(v)? a.text.ify(v) : v));
|
||||
});
|
||||
}
|
||||
return r;
|
||||
});
|
||||
list.fuse = (function(l){
|
||||
var args = a.list.slit.call(arguments, 0), ll;
|
||||
l = ($=a.fns.$(list))||l;
|
||||
ll = $? a.fns.sort(args).l : a.fns.sort(args).l.slice(1);
|
||||
return Array.prototype.concat.apply(l,ll);
|
||||
});
|
||||
list.union = list.u = (function(l,ll){ //[1,2,3,4,5] u [3,5,6,7,8] = [1,2,3,4,5,6,7,8]
|
||||
return not_implemented_yet;
|
||||
if($=a.fns.$(list)){ ll=l;l=$ }
|
||||
// yeaaah, try again.
|
||||
return r;
|
||||
});
|
||||
list.intersect = list.n = (function(l,ll){ //[1,2,3,4,5] n [3,5,6,7,8] = [3,5]
|
||||
return not_implemented_yet;
|
||||
if($=a.fns.$(list)){ ll=l;l=$ }
|
||||
// yeaah, try again.
|
||||
});
|
||||
list.less = (function(l,s){ // ToDo: Add ability to use a function to determine what is removed.
|
||||
var args = a.list.slit.call(arguments, 0), sl = s, ls = l;
|
||||
l = ($=a.fns.$(list))||l;
|
||||
s = $? args : args.slice(1);
|
||||
if($ === args.length){ l=ls;s=sl }
|
||||
sl = s.length;
|
||||
return a.list(l).each(function(v,i,t){
|
||||
if(1 == sl && a.test.is(v,s[0])){ return } else
|
||||
if(a.list(s).each(function(w,j){
|
||||
if(a.test.is(v,w)){ return true }
|
||||
})){ return }
|
||||
t(v);
|
||||
})||[];
|
||||
});
|
||||
list.each = list.find = (function(l,c,t){
|
||||
if($=a.fns.$(list)){ t=c;c=l;l=$ }
|
||||
return a.obj.each(l,c,t);
|
||||
});
|
||||
list.copy = (function(l){
|
||||
return a.obj.copy( ($=a.fns.$(list))||l );
|
||||
});
|
||||
list.index = 1;
|
||||
return list;
|
||||
})();
|
||||
a.obj = (function(){
|
||||
function obj($){
|
||||
obj.$ = $ !== undefined? $ : _;
|
||||
return obj;
|
||||
} var $;
|
||||
obj.is = (function(o){
|
||||
o = a.fns.$(obj)||o;
|
||||
return (o instanceof Object && !a.list.is(o) && !a.fns.is(o))? true : false;
|
||||
});
|
||||
obj.ify = (function(o){
|
||||
o = a.fns.$(obj)||o;
|
||||
if(a.obj.is(o)){ return o }
|
||||
try{
|
||||
o = JSON.parse(o);
|
||||
}catch(e){o={}};
|
||||
return o;
|
||||
});
|
||||
obj.empty = (function(o){
|
||||
if(!(o = a.fns.$(obj)||o)){ return true }
|
||||
return obj.each(o,function(v,i){
|
||||
if(i){ return true }
|
||||
})? false : true;
|
||||
});
|
||||
obj.copy = (function(o,r,l){
|
||||
if(!r){
|
||||
o = a.fns.$(obj) || o;
|
||||
} l = a.list.is(o);
|
||||
if(r && !a.obj.is(o) && !l){ return o }
|
||||
r = {}; o = a.obj.each(o,function(v,i,t){
|
||||
l? t(obj.copy(v,true)) : (r[i] = obj.copy(v,true));
|
||||
})||[];
|
||||
return l? o : r;
|
||||
});
|
||||
obj.union = obj.u = (function(x,y){
|
||||
var args = a.list.slit.call(arguments, 0), r = {};
|
||||
if($=a.fns.$(obj)){ y=x;x=$ }
|
||||
if(a.list.is(x)){ y = x } else
|
||||
if(a.list.is(y)){ } else {
|
||||
y = $? args : args.slice(1);
|
||||
y.splice(0,0,x);
|
||||
}
|
||||
a.list(y).each(function(v,i){
|
||||
a.obj(v).each(function(w,j){
|
||||
if(a.obj(r).has(j)){ return }
|
||||
r[j] = w;
|
||||
});
|
||||
});
|
||||
return r;
|
||||
});
|
||||
obj.has = (function(o,k){
|
||||
if($=a.fns.$(obj)){ k=o;o=$ }
|
||||
return Object.prototype.hasOwnProperty.call(o, k);
|
||||
});
|
||||
obj.each = (function(l,c,_){
|
||||
if($=a.fns.$(obj)){ _=c;c=l;l=$ }
|
||||
var i = 0, ii = 0, x, r, rr, f = a.fns.is(c),
|
||||
t = (function(k,v){
|
||||
if(v !== undefined){
|
||||
rr = rr || {};
|
||||
rr[k] = v;
|
||||
return;
|
||||
} rr = rr || [];
|
||||
rr.push(k);
|
||||
});
|
||||
if(a.list.is(l)){
|
||||
x = l.length;
|
||||
for(;i < x; i++){
|
||||
ii = (i + a.list.index);
|
||||
if(f){
|
||||
r = _? c.call(_, l[i], ii, t) : c(l[i], ii, t);
|
||||
if(r !== undefined){ return r }
|
||||
} else {
|
||||
if(a.test.is(c,l[i])){ return ii }
|
||||
}
|
||||
}
|
||||
} else if(a.obj.is(l)){
|
||||
for(i in l){
|
||||
if(f){
|
||||
if(a.obj(l).has(i)){
|
||||
r = _? c.call(_, l[i], i, t) : c(l[i], i, t);
|
||||
if(r !== undefined){ return r }
|
||||
}
|
||||
} else {
|
||||
if(a.test.is(c,l[i])){ return i }
|
||||
}
|
||||
}
|
||||
}
|
||||
return f? rr : a.list.index? 0 : -1;
|
||||
});
|
||||
obj.get = (function(o,l,opt,f){
|
||||
if($=a.fns.$(obj)){ l=o;o=$ }
|
||||
if(a.num.is(l)){ l = a.text.ify(l) }
|
||||
if(a.list.is(l)){ l = l.join('.') }
|
||||
if(a.text.is(l)){
|
||||
f = (l.length == (l = l.replace(a.text.find.__.fn,'')).length)?
|
||||
undefined : function(){}; l = l.split(a.text.find.__.dot);
|
||||
} if(!l){ return }
|
||||
var x = (l||[]).length, r,
|
||||
deep = (function(o,v){
|
||||
return a.list(o).each(function(w,j){
|
||||
if(a.obj(w||{}).has(v)){ return w }
|
||||
if(a.list.is(w)){ return deep(w,v) }
|
||||
});
|
||||
}), get = (function(v,i,t,n){
|
||||
if(a.list.is(o)){
|
||||
if(/^\-?\d+$/.test(v)){
|
||||
n = a.list.index;
|
||||
v = a.num.ify(v);
|
||||
} else {
|
||||
o = deep(o,v);
|
||||
}
|
||||
}
|
||||
if(n || a.obj(o||{}).has(v)){
|
||||
o = n? a.list(o).at(v) : o[v];
|
||||
if(i === x - (a.list.index? 0 : 1)){
|
||||
return f? a.fns.is(o)? o : f : o;
|
||||
} return;
|
||||
}
|
||||
return f || a.test.nil;
|
||||
}); r = a.list(l).each(get);
|
||||
return r === a.test.nil? undefined : r;
|
||||
});
|
||||
return obj;
|
||||
})();
|
||||
a.text = (function(){
|
||||
function text($){
|
||||
text.$ = $ !== undefined? $ : _;
|
||||
return text;
|
||||
} var $;
|
||||
text.is = (function(t){
|
||||
t = (($=a.fns.$(text))!==_)?$:t;
|
||||
return typeof t == 'string'?true:false;
|
||||
});
|
||||
text.get = (function(q){ return });
|
||||
text.ify = (function(t){
|
||||
t = (($=a.fns.$(text))!==_)?$:t;
|
||||
if(JSON){ return JSON.stringify(t) }
|
||||
return t.toString? t.toString():t;
|
||||
});
|
||||
text.random = text.r = (function(l,c){
|
||||
if($=a.fns.$(text)){ c=l;l=$ } var $ = $||l, s = '';
|
||||
l = a.num.is($)? $ : a.num.is(c)? c : 16;
|
||||
c = a.text.is($)? $ : a.text.is(c)? c : '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz';
|
||||
while(l>0){ s += c.charAt(Math.floor(Math.random()*c.length)); l-- }
|
||||
return s;
|
||||
});
|
||||
text.clip = (function(t,r,s,e){
|
||||
if($=a.fns.$(text)){ e=s;s=r;r=t;t=$ } // IE6 fails if e === undefined with Mocha
|
||||
return t = (t||'').split(r), t=a.num.is(e)?t.slice(s,e):t.slice(s), t.join(r);
|
||||
});
|
||||
text.find = (function(t){
|
||||
var regex = {};
|
||||
a.log(regex.name = t.name+'.find');
|
||||
regex.is = /[\.\\\?\*\[\]\{\}\(\)\^\$\+\|\,]/ig
|
||||
regex.special = {'.':1,'\\':1,'?':1,'*':1,'[':1,']':1,'{':1,'}':1,'(':1,')':1,'^':1,'$':1,'+':1,'|':1,',':1}
|
||||
regex.mail = /^(("[\w-\s]+")|([\w-]+(?:[\.\+][\w-]+)*)|("[\w-\s]+")([\w-]+(?:[\.\+][\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i;
|
||||
regex.base64 = new RegExp("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$");
|
||||
regex.list = /(,\s|;\s|,|;|\s)/ig;
|
||||
regex.css = /(.+?):(.+?);/ig;
|
||||
regex.url = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
|
||||
regex.ext = /\.([^\.]+)$/i;
|
||||
regex.ws_ = /\-/ig;
|
||||
regex.space = /\s/ig;
|
||||
regex.num = /(\-\d+\.\d+|\d+\.\d+|\-\d+|\d+)/g;
|
||||
regex['int'] = /(\-\d+|\d+)/g;
|
||||
regex.__ = { fn: /\-\>$/, dot: /\./ };
|
||||
return regex;
|
||||
})(text);
|
||||
text.caps = (function(t){
|
||||
t = a.fns.$(text)||t;
|
||||
t = (text.is(t))?t:"";
|
||||
return t.toUpperCase();
|
||||
});
|
||||
text.low = (function(t){
|
||||
t = a.fns.$(text)||t;
|
||||
t = (text.is(t))?t:"";
|
||||
return t.toLowerCase();
|
||||
});
|
||||
return text;
|
||||
})();
|
||||
a.num = (function(){
|
||||
function num($){
|
||||
num.$ = ($ !== undefined? $ : _);
|
||||
return num;
|
||||
} var $;
|
||||
num.is = (function(n){
|
||||
n = (($=a.fns.$(num))!==_)?$:n;
|
||||
return ( (n===0)? true : (!isNaN(n) && !a.bi.is(n) && !a.list.is(n) && !a.text.is(n))? true : false);
|
||||
});
|
||||
num.i = (function(n){return parseInt(a.fns.$(num)||n,10)});
|
||||
num.dec = (function(n){return parseFloat(a.fns.$(num)||n)});
|
||||
num.ify = (function(n,o){
|
||||
if(($=a.fns.$(num))!==_){ o=n;n=$ }
|
||||
var r, l = a.list.is(o);
|
||||
if(a.list.is(o)){
|
||||
if(a.num.is(n)){
|
||||
return [n];
|
||||
} if(a.text.is(n)){
|
||||
r = n.match(a.text.find.num) || [];
|
||||
return a.list(r).each(function(v,i,t){
|
||||
t(a.num.ify(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
r = num.dec(n);
|
||||
if(a.num.is(r)){ return r }
|
||||
if(!n){ return }
|
||||
if(a.text.is(n)){
|
||||
return a.num.ify( (n.match(a.text.find.num)||[])[0] );
|
||||
}
|
||||
});
|
||||
num.random = num.r = (function(l){
|
||||
l = ((($=a.fns.$(num))!==_)?$:l)||6;
|
||||
if(a.list.is(l)){ return (Math.floor(Math.random() * (l[1] - l[0] + 1)) + l[0]) }
|
||||
l = (l<=14)? l : 14;
|
||||
var n = '9';
|
||||
for(var i = 0; i < l-1; i++){ n += '0' }
|
||||
n = a.num.ify(n);
|
||||
var r = function(){return Math.floor(Math.random()*10)||(l==1?0:r())};
|
||||
n = Math.floor(r() + Math.pow(Math.random(),Math.random()) * (n));
|
||||
if(n.toString().length != l){ return num.r(l) }
|
||||
return n;
|
||||
});
|
||||
return num;
|
||||
})();
|
||||
a.bi = (function(){
|
||||
function bi($){
|
||||
bi.$ = $ !== undefined? $ : _;
|
||||
return bi;
|
||||
} var $;
|
||||
bi.is = (function(b){
|
||||
b = (($=a.fns.$(bi))!==_)?$:b;
|
||||
return (b instanceof Boolean || typeof b == 'boolean')?true:false;
|
||||
});
|
||||
return bi;
|
||||
})();
|
||||
a.on = (function(){
|
||||
function on($){
|
||||
on.$ = $ !== undefined? $ : _;
|
||||
return on;
|
||||
} var $, events = {}, sort = (function(A,B){
|
||||
if(!A || !B){ return 0 } A = A.i; B = B.i;
|
||||
if(A < B){ return -1 }else if(A > B){ return 1 }
|
||||
else { return 0 }
|
||||
});
|
||||
on.emit = (function(){
|
||||
if(!a.text.is($ = a.fns.$(on))) return;
|
||||
var e = events[$] = events[$] || (events[$] = []), args = arguments;
|
||||
if(!(events[$] = a.list(e).each(function(hear, i, t){
|
||||
if(!hear.fn) return; t(hear);
|
||||
hear.fn.apply(hear, args);
|
||||
}))){ delete events[$]; }
|
||||
});
|
||||
on.event = (function(fn, i){
|
||||
if(!a.text.is($ = a.fns.$(on))) return;
|
||||
var $ = events[$] = events[$] || (events[$] = [])
|
||||
, e = {fn: fn, i: i || 0, off: function(){ return !(e.fn = false); }};
|
||||
return $.push(e), $.sort(sort), e;
|
||||
});
|
||||
return on;
|
||||
})();
|
||||
a.time = (function(){
|
||||
function time($){
|
||||
time.$ = $ !== undefined? $ : _;
|
||||
return time;
|
||||
}
|
||||
time.is = (function(t){
|
||||
t = ($=a.fns.$(time))||t;
|
||||
return t? t instanceof Date : (+new Date().getTime());
|
||||
});
|
||||
time.now = (function(){
|
||||
var n = a.num.ify((a.time.is().toString())+'.'+a.num.r(4));
|
||||
return (theory.time.now.last||0) < n? (theory.time.now.last = n) : time.now();
|
||||
});
|
||||
time.loop = (function(fn,d){
|
||||
var args = a.fns.sort(a.list.slit.call(arguments, 0));
|
||||
return (args.f.length)?setInterval(a.list(args.f).at(1),a.list(args.n).at(1)):_;
|
||||
});
|
||||
time.wait = (function(fn,d){
|
||||
var args = a.fns.sort(a.list.slit.call(arguments, 0));
|
||||
return (args.f.length)?setTimeout(a.list(args.f).at(1),a.list(args.n).at(1)):_;
|
||||
});
|
||||
time.stop = (function(i){
|
||||
i = ($=a.fns.$(time))||i;
|
||||
return (clearTimeout(i)&&clearInterval(i))||true;
|
||||
});
|
||||
return time;
|
||||
})();
|
||||
a.com = (function($){
|
||||
var com = a.com;
|
||||
com.$ = $ !== undefined? $ : _;
|
||||
com.way = com.way||$;$=_;
|
||||
com.queue = [];
|
||||
theory.com.queue = theory.com.queue||[];
|
||||
com.dc = [theory.time.now()];
|
||||
com.node = (function(opt){
|
||||
if(!process._events){ process._events = {} }
|
||||
if(process.send && !process._events.theory){
|
||||
process._events.theory = (function(m){
|
||||
com.msg(a.obj.ify(m));
|
||||
}); process.on('message',process._events.theory);
|
||||
process.send({onOpen:{readyState:(process.readyState = 1)},mod:module.theory[opt.way]});
|
||||
com.wire = process;
|
||||
return;
|
||||
}
|
||||
});
|
||||
com.page = (function(){
|
||||
com.src = com.src||(window.location.protocol +'//'+ window.location.hostname)
|
||||
+ ((window.location.port)?':'+window.location.port:'')
|
||||
+ (com.path||'/com');
|
||||
var municate = (function(){
|
||||
if(!window.SockJS){ return }
|
||||
theory.com.wire = new window.SockJS(com.src);
|
||||
theory.com.wire.onopen = function(){
|
||||
theory.com.open&&theory.com.open();
|
||||
console.log("Communication initiated at "+com.src+" with "+com.wire.protocol+".");
|
||||
com.drain();
|
||||
};
|
||||
theory.com.wire.onmessage = theory.com.municate||function(m){
|
||||
var fn, m = a.obj.ify(m.data||m);
|
||||
if(fn = theory.com.asked[m.when]){
|
||||
if(a.fns.is(fn)){ fn(m) }
|
||||
delete theory.com.asked[m.when];
|
||||
return;
|
||||
}
|
||||
com.msg(m);
|
||||
};
|
||||
theory.com.wire.onclose = function(m){
|
||||
console.log('close');
|
||||
theory.com.close&&theory.com.close(m);
|
||||
};
|
||||
});
|
||||
if(theory.com.off || root.opts.com === false){ return }
|
||||
if(window.SockJS){
|
||||
municate();
|
||||
} else {
|
||||
module.ajax.load(com.url||(location.local+'//cdn.sockjs.org/sockjs-0.3.min.js')
|
||||
,function(d){municate()});
|
||||
}
|
||||
});
|
||||
com.drain = (function(){
|
||||
while(theory.com.queue.length > 0){
|
||||
com.write(theory.com.queue.shift());
|
||||
}
|
||||
});
|
||||
com.write = (function(m,c){
|
||||
c = c||theory.com.wire;
|
||||
if(!c || c.readyState !== 1){
|
||||
theory.com.queue.push(m);
|
||||
return;
|
||||
}
|
||||
if(a.obj.is(m)){
|
||||
m = a.text(m).ify();
|
||||
}
|
||||
//console.log("send --> "+m);
|
||||
c.send(m);
|
||||
});
|
||||
com.init = (function(c){
|
||||
if(root.node){ com.node({way:c}) }
|
||||
if(c){ return }
|
||||
if(root.page){ com.page() }
|
||||
return com;
|
||||
});
|
||||
/** Helpers **/
|
||||
com.msg = (function(m,c){
|
||||
theory.obj.get(theory,theory.obj.get(m,'how.way')+'->')(m,c);
|
||||
});
|
||||
com.ways = (function(m,w){
|
||||
var way = w||a.obj.get(m,'how.way')||com.way;
|
||||
if($=a.fns.$(com)){
|
||||
way = ($.charAt(0)=='.')?com.way+$:$;
|
||||
} return m = com.meta(m,way);
|
||||
});
|
||||
com.ask = (function(m,f){
|
||||
if(!a.fns.is(f)){ return }
|
||||
m = com.ways(m);
|
||||
delete m.where;
|
||||
theory.com.asked[m.when] = f;
|
||||
com.write(m);
|
||||
});theory.com.asked = theory.com.asked||{};
|
||||
com.reply = (function(m){
|
||||
m = com.ways(m);
|
||||
if(m.how.web){
|
||||
m.how.way = 'web.reply';
|
||||
} m.who = m.who||{};
|
||||
m.who.to = m.who.to||m.who.tid;
|
||||
com.write(m);
|
||||
});
|
||||
com.send = (function(m){
|
||||
m = com.ways(m);
|
||||
com.write(m);
|
||||
});
|
||||
com.meta = (function(m,opt){
|
||||
if(!a.obj.is(m)){ m = {what:m} }
|
||||
var n = {what: (m.what = m.what||{}) };
|
||||
opt = opt||{c:{}};
|
||||
if(a.text.is(opt)){ opt = {w:opt,c:{}} }
|
||||
if(opt.protocol){ opt.c = opt }
|
||||
a.obj(m).each(function(v,i){
|
||||
if( i == 'how' || i == 'who' || i == 'what' ||
|
||||
i == 'when'|| i == 'where'){ return }
|
||||
n.what[i] = m.what[i] = v; delete m[i];
|
||||
});
|
||||
if(!m.how){ n.how={way: opt.w||com.way} }else{
|
||||
n.how = m.how;
|
||||
n.how.way = opt.w||m.how.way||com.way;
|
||||
delete m.how;
|
||||
} m.how = n.how;
|
||||
if(!m.when){ n.when=a.time.now() }else{
|
||||
n.when = m.when;
|
||||
delete m.when;
|
||||
} m.when = n.when;
|
||||
if(!m.who){
|
||||
if(root.page && !com.who){
|
||||
n.who = { tid: (com.who=root.who) }
|
||||
} if(root.node){ n.who = {} }
|
||||
}else{
|
||||
if(a.obj.is(m.who)){ n.who=m.who }else{
|
||||
n.who = {to: m.who}
|
||||
} if(root.node){
|
||||
} if(root.page && !com.who){
|
||||
n.who.tid = com.who = root.who;
|
||||
} delete m.who;
|
||||
} m.who = n.who;
|
||||
if(!m.where){
|
||||
if(root.page){ if(a.text.is(m.where)){}else{};
|
||||
} if(root.node){ n.where={pid: process.pid} }
|
||||
}else{
|
||||
if(a.obj.is(m.where)){ n.where = m.where }else{
|
||||
n.where = {at: m.where};
|
||||
} if(root.node){
|
||||
if(!a.obj(m.where).has('pid')){ n.where.pid=process.pid }
|
||||
} delete m.where;
|
||||
} m.where = n.where;
|
||||
return n;
|
||||
}); /** END HELPERS **/
|
||||
return com;
|
||||
});
|
||||
a.test = (function(){
|
||||
function test($){
|
||||
if($===undefined && a.fns.is(test.$)){ try{return test.$()}catch(e){return e} }
|
||||
test.$ = arguments.length? $ : test.nil;
|
||||
return test;
|
||||
} test.nil = test.$ = 'ThEoRy.TeSt.NiL-VaLuE';
|
||||
test._ = (function(r){ r = a.fns.$(test); test.$ = test.nil; return r; });
|
||||
test.of = (function(t,f){
|
||||
if(($=test._()) !== test.nil){ f=t;t=$ }
|
||||
return t instanceof f;
|
||||
});
|
||||
test.is = (function(a, b, aStack, bStack){ // modified Underscore's to fix flaws
|
||||
if(($=test._()) !== test.nil){ b=a;a=$ }
|
||||
var _ = {isFunction:theory.fns.is
|
||||
,has:theory.obj.has}, eq = test.is;
|
||||
aStack = aStack||[]; bStack = bStack||[];
|
||||
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
||||
if(a === b){ return a !== 0 || 1 / a == 1 / b }
|
||||
if(a == null || b == null){ return a === b }
|
||||
var className = Object.prototype.toString.apply(a);
|
||||
if(className != Object.prototype.toString.apply(b)){ return false }
|
||||
switch(className){
|
||||
case '[object String]': return a == String(b);
|
||||
case '[object Number]': return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
|
||||
case '[object Function]': return a.name === b.name && a.toString() === b.toString();
|
||||
case '[object Date]':
|
||||
case '[object Boolean]': return +a == +b;
|
||||
case '[object RegExp]': return a.source == b.source && a.global == b.global &&
|
||||
a.multiline == b.multiline && a.ignoreCase == b.ignoreCase;
|
||||
}
|
||||
if(typeof a != 'object' || typeof b != 'object'){ return false }
|
||||
var length = aStack.length;
|
||||
while(length--){ if(aStack[length] == a){ return bStack[length] == b} }
|
||||
aStack.push(a); bStack.push(b);
|
||||
var size = 0, result = true;
|
||||
if(className == '[object Array]'){
|
||||
size = a.length; result = size == b.length;
|
||||
if(result){
|
||||
while(size--){
|
||||
if(!(result = eq(a[size], b[size], aStack, bStack))){ break }
|
||||
}
|
||||
}
|
||||
}else{
|
||||
var aCtor = a.constructor, bCtor = b.constructor;
|
||||
if(aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
|
||||
_.isFunction(bCtor) && (bCtor instanceof bCtor))){ return false }
|
||||
for(var key in a){
|
||||
if(_.has(a, key)){
|
||||
size++;
|
||||
if(!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))){ break }
|
||||
}
|
||||
} if(result){
|
||||
for(key in b){
|
||||
if(_.has(b, key) && !(size--)){ break }
|
||||
} result = !size;
|
||||
}
|
||||
}
|
||||
aStack.pop(); bStack.pop();
|
||||
return result;
|
||||
});
|
||||
return test;
|
||||
})();
|
||||
return a;
|
||||
}
|
||||
theory.Name = 'theory';
|
||||
theory.version = 2.5;
|
||||
theorize(theory);
|
||||
return theory;
|
||||
})(true);
|
||||
|
||||
/**
|
||||
BASE
|
||||
**/
|
||||
(function(r){
|
||||
var root = root||{}, a = theory;
|
||||
root.opts = root.opts || {};
|
||||
root.deps = {loaded:{},alias:{},all:{},wait:{}};
|
||||
root.pollute = ((typeof GLOBAL !== 'undefined' && GLOBAL.global && GLOBAL.process &&
|
||||
GLOBAL.process.env && GLOBAL.process.pid && GLOBAL.process.execPath)?
|
||||
(function(){
|
||||
global.node = root.node = true;
|
||||
global.opts = root.opts;
|
||||
global.theory = theory;
|
||||
module.theory = module.theory||{}
|
||||
process.env.totheory = __filename;
|
||||
if(process.env.NODE_ENV==='production'){process.env.LIVE = true};
|
||||
module.path = require('path');
|
||||
require.sep = module.path.sep;
|
||||
module.exports=(function(cb,deps,name){
|
||||
if(!arguments.length) return theory;
|
||||
var args = a.fns.sort(a.list.slit.call(arguments, 0)), r
|
||||
,m = util.require.apply({},arguments);
|
||||
args.file = root.submodule||(module.parent||{}).filename;
|
||||
global.aname = global.aname||m.name;
|
||||
a.obj(util.deps(m.dependencies,{flat:{},src:args.file})).each(function(name,path){
|
||||
var p = require(root.submodule=path=util.resolve(path,path));
|
||||
m.theory[name] = (theory.obj.is(p) && theory.obj.empty(p))? undefined : p;
|
||||
});
|
||||
module.theory[m.name] = a.obj.ify(a.text.ify(m));
|
||||
var mod = (theory[m.name] = m.init(m.theory));
|
||||
if(global.aname === m.name && theory.com) theory.com(theory.Name).init(m.name);
|
||||
return mod;
|
||||
});
|
||||
return;
|
||||
}) : (function(){
|
||||
root = window.root = window.root||root;
|
||||
root.page = true;
|
||||
root.who = root.who||a.list((document.cookie+';').match(/tid=(.+?);/)||[]).at(-1)||'';
|
||||
window.console = window.console||{log:function(s){return s}};
|
||||
console.saw = (function(s){console.log(a.text(s).ify())});
|
||||
location.local=(location.protocol==='file:'?'http:':'');
|
||||
var noConflict={__dirname: window.__dirname,module:window.module,exports:window.exports,require:window.require};
|
||||
window.__dirname = '';
|
||||
window.module = {exports: (window.exports = {})};
|
||||
window.module.ajax = {load:(function(b,c){
|
||||
var d=document,j="script",s=d.createElement(j); module.sync=(s.onload===null||!s.readyState)?0:1; // IE6+
|
||||
var e=2166136261,g=b.length,h=c,i=/=\?/,w=window.setTimeout,x,y,a=function(z){
|
||||
document.body&&(z=z||x)&&s&&document.body[z]?document.body[y=z](s):w(a,0);
|
||||
};if(i.test(b)){for(;g--;)e=e*16777619^b.charCodeAt(g);
|
||||
window[j+=e<0?-e:e]=function(){h.apply(h,arguments);delete window[j]};b=b.replace(i,"="+j);c=0
|
||||
};s.onload=s.onreadystatechange=function(){if(y&&/de|m/.test(s.readyState||"m")){
|
||||
c&&c();a(x='removeChild');try{for(c in s)delete s[c]}catch(b){}
|
||||
}};s.src=b;c&&a(x='appendChild');
|
||||
})};module.ajax.load('#');
|
||||
window.module.ajax.code = util.load;
|
||||
window.onerror = (function(e,w,l){
|
||||
console.log(e + " at line "+ l +" on "+ w);
|
||||
//if(theory.com){ theory.com.send({e:e,url:w,line:l}) }
|
||||
});
|
||||
window.require = module.require = function require(p){
|
||||
if(!p){ return require }
|
||||
if(util.stripify(p) == util.stripify(theory.Name)){
|
||||
return util.require;
|
||||
} var fn, c = 0, cb = function(f){ fn = f; };
|
||||
theory.list((p = theory.list.is(p)? p : [p])).each(function(v){
|
||||
window.module.ajax.code(v,function(d){++c && (p.length <= c) && fn && fn(d)});
|
||||
}); return cb;
|
||||
}; window.require.sep = '/'; require.resolve = util.resolve; require.cache = {};
|
||||
util.init();
|
||||
if(root.opts.amd === false){theory.obj(noConflict).each(function(v,i){window[i]=v});}
|
||||
if(theory.com){ theory.com(theory.Name).init() }
|
||||
})
|
||||
);
|
||||
var util = {};
|
||||
util.theorize = (function(mod){
|
||||
mod.theory = theory.call(true);
|
||||
if(mod.theory.com){ mod.theory.com(mod.name) }
|
||||
return mod.theory;
|
||||
});
|
||||
util.require = (function(){
|
||||
var mod, args = a.fns.sort(a.list.slit.call(arguments,0))
|
||||
, fail = {name:'fail',init:(function(){console.log('module failed to load')})};
|
||||
if(args.o.length === 1 && !args.t.length && !args.l.length){
|
||||
mod = a.list(args.o).at(1);
|
||||
} else {
|
||||
if(args.f.length){
|
||||
mod = {
|
||||
name: a.list(args.t).at(1)
|
||||
,init: a.list(args.f).at(1)
|
||||
,dependencies: a.list(args.l).at(1) || a.list(args.o).at(1)
|
||||
}
|
||||
}
|
||||
} mod.name = mod.name||fail.name;
|
||||
mod.init = mod.init||mod.main||mod.start||mod.boot||mod.cb||mod.fn||fail.init;
|
||||
mod.dependencies = mod.dependencies||mod.require||mod.deps||mod.dep;
|
||||
mod.dependencies = a.list.is(mod.dependencies)?
|
||||
a.list(mod.dependencies).each(function(v,i,t){t(v,1)}) : mod.dependencies;
|
||||
mod.theory = util.theorize(mod);
|
||||
if(root.node){ return mod }
|
||||
args = {cb:function(p, opt){
|
||||
if(args.launched
|
||||
|| a.list(util.deps(mod.dependencies,{flat:{}})).each(function(v,j){
|
||||
if(!(i = root.deps.loaded[j])){ return true }
|
||||
if(i === 2){ return true }
|
||||
if(i && i.launch && a.text.is(v) && mod.theory[v] === undefined){ mod.theory[v] = i.launch; }
|
||||
})){ return }
|
||||
args.on.off();
|
||||
args.launched = {launch: (theory[mod.name] = mod.init(mod.theory||theory)), n:mod.name};
|
||||
module.exports = exports = args.launched.launch;
|
||||
if(mod.src){
|
||||
root.deps.loaded[mod.src] = args.launched;
|
||||
theory.on('ThEoRy_DePs').emit();
|
||||
} return args.launched.launch;
|
||||
}}; args.on = theory.on('ThEoRy_DePs').event(args.cb);
|
||||
args.start = function(){util.deps(mod.dependencies,args); return args.cb()}
|
||||
args.name = function(src){
|
||||
module.on = args.name = false;
|
||||
root.deps.alias[args.src = mod.src = src] = mod.name;
|
||||
if((root.deps.all[src] = mod.dependencies)){
|
||||
root.deps.loaded[src] = 2;
|
||||
} if(!window.JSON){module.ajax.load(root.opts.JSON||location.local // JSON shim when needed
|
||||
+"//ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js",args.start)
|
||||
} else { return args.start() };
|
||||
}; module.on = (!(require||{}).ing)? args.name(util.src(1))||false : args.name;
|
||||
});
|
||||
util.deps = (function(deps, opt){
|
||||
opt = opt || {};
|
||||
a.obj(deps).each(function(v,i){
|
||||
var path = i, dopt = {p:i};
|
||||
if(opt.src){
|
||||
delete deps[i];
|
||||
deps[path = util.resolve(opt.src, util.pathify(path))] = v;
|
||||
} if(a.list.is(v)){
|
||||
delete deps[i];
|
||||
v = deps[path] = a.list(v).each(function(w,i,t){t(util.resolve(opt.src,util.pathify(w)),1)})
|
||||
} if(a.obj.is(v)){
|
||||
dopt.defer = v;
|
||||
opt.flat && util.deps(v,{flat: opt.flat});
|
||||
} if(v && a.text.is(v)){
|
||||
dopt.name = v;
|
||||
} if(opt.flat){
|
||||
var url = util.urlify(util.pathify(path));
|
||||
if((i = opt.flat[url]) && i !== 1){ return }
|
||||
opt.flat[url] = (opt.sub? 1 : dopt.name) || util.stripify(path);
|
||||
if(i !== 1 && url && a.text.is(url) && (v = root.deps.all[url])){
|
||||
(a.obj.is(v) || a.list.is(v)) && util.deps(v,{flat: opt.flat, sub:1});
|
||||
} return;
|
||||
} return util.load(path, dopt);
|
||||
});
|
||||
return opt.flat;
|
||||
});
|
||||
util.urlify = (function(url){ // via SO, IE6+ safe
|
||||
if(!root.page){ return url; }
|
||||
var el= document.createElement('div');
|
||||
el.innerHTML= '<a href="'+url+'">x</a>';
|
||||
return el.firstChild.href;
|
||||
});
|
||||
util.pathify = (function(p){
|
||||
if(!root.page){ return p; }
|
||||
return p = (/\.js$/i.test(p))? p : p+'.js';
|
||||
});
|
||||
util.stripify = (function(p){
|
||||
if(!a.text.is(p)){ return ''; } p=p.replace(/^\./,'');
|
||||
return (p.split(require.sep).reverse()[0]).replace(/\.js$/i,'');
|
||||
});
|
||||
util.resolve = (function(p1, p2){ // via browserify
|
||||
if('.' != p2.charAt(0)){ return p2.replace('/',require.sep) }
|
||||
var path = p1.replace('/',require.sep).split(require.sep)
|
||||
, segs = p2.replace('/',require.sep).split(require.sep)
|
||||
path.pop();
|
||||
for(var i=0;i<segs.length;i++){
|
||||
var seg = segs[i];
|
||||
if('..' == seg){ path.pop() }
|
||||
else if('.' != seg){ path.push(seg) }
|
||||
} return path.join(require.sep);
|
||||
});
|
||||
util.load = (function(p, opt ,z){
|
||||
if(util.stripify(p) == util.stripify(theory.Name)){
|
||||
return util.require;
|
||||
} opt = opt || {};
|
||||
{var w=root.deps.wait;if(module.sync){if(!z && !a.obj.empty(w)){
|
||||
w[p] = opt;if(opt.defer){w=root.deps.wait = a.obj(w).u(opt.defer)}return;
|
||||
}w[p] = opt;if(opt.defer){w=root.deps.wait = a.obj(w).u(opt.defer)}}}
|
||||
var path = util.pathify(p), url = util.urlify(path)
|
||||
, cb = (function(d){
|
||||
if(false !== d){
|
||||
console.log(opt.p||p, ' loaded');
|
||||
root.deps.loaded[url] = 1;
|
||||
module.on && module.on(url);
|
||||
theory.fns.is(opt) && opt(d);
|
||||
} theory.on('ThEoRy_DePs').emit();
|
||||
!module.sync && opt.defer && util.deps(opt.defer, opt);
|
||||
{if(module.sync){delete w[p];if(!a.obj(w).each(function(v,i,t){
|
||||
delete w[i];util.load(i,v,1);return 1;})){w=root.deps.wait = false}}}
|
||||
}); if(root.deps.loaded[url]
|
||||
|| root.deps.loaded[url] === 0){
|
||||
return cb(false);
|
||||
} root.deps.loaded[url] = 0;
|
||||
(require||{}).ing=true;
|
||||
try{window.module.ajax.load(path,cb);}
|
||||
catch(e){console.log("Network error.")};
|
||||
console.log('loading', opt.p||p);
|
||||
});
|
||||
util.sandbox = (function(s,n){
|
||||
try{ // via jQuery
|
||||
(window.execScript || function(s){
|
||||
window["eval"].call(window, s);
|
||||
})(s);
|
||||
}catch(e){
|
||||
console.log("sandbox fail: "+n);
|
||||
console.log(e, s);
|
||||
}
|
||||
});
|
||||
util.theorycount = 0;
|
||||
util.src = (function(){
|
||||
var s = document.getElementsByTagName('script');
|
||||
s = (s[s.length-1]||{}).src;
|
||||
return util.stripify(s) === theory.Name? location : s||location;
|
||||
});
|
||||
util.init = (function(r){
|
||||
if(!root.page){ return }
|
||||
var z='', s = document.getElementsByTagName('script'), t;
|
||||
for(var i in s){var v = s[i]; // IE6 fails on each, use for instead
|
||||
r = v.src||r;
|
||||
if(v.id || !v.innerHTML || util.stripify(v.src)
|
||||
!== util.stripify(theory.Name)){ false;
|
||||
} else { t = v }
|
||||
} if(t){
|
||||
util.sandbox(t.innerHTML,'Theory Configuration');
|
||||
t.id = "theory"+util.theorycount++;
|
||||
}
|
||||
return r;
|
||||
});
|
||||
root.init = (function(){
|
||||
root.pollute();
|
||||
return util.init;
|
||||
})();
|
||||
})()};
|
1
examples/Procfile
Normal file
@ -0,0 +1 @@
|
||||
web: node all.js
|
@ -59,7 +59,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
<script>
|
||||
var gun = Gun([location + 'gun']);
|
||||
var gun = Gun([location.origin + '/gun']);
|
||||
angular.module('admin', []).controller('editor', function($scope){
|
||||
$scope.data = {};
|
||||
$scope.$data = gun.load('blob/data').get(function(data){
|
||||
|
1062
examples/admin/old_gun_for_slinger.js
Normal file
@ -4,7 +4,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="https://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
|
||||
<script src="../../gun.js"></script>
|
||||
<script src="old_gun_for_slinger.js"></script>
|
||||
</head>
|
||||
<body><center>
|
||||
<style>
|
||||
|
15
examples/all.js
Normal file
@ -0,0 +1,15 @@
|
||||
console.log("If modules not found, run `npm install` in /example folder!"); // git subtree push -P examples heroku master
|
||||
var port = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || 8888;
|
||||
|
||||
var express = require('express');
|
||||
var app = express();
|
||||
|
||||
var Gun = require('gun');
|
||||
var gun = Gun({
|
||||
s3: (process.env.NODE_ENV === 'production')? null : require('../test/shotgun') // replace this with your own keys!
|
||||
});
|
||||
|
||||
gun.attach(app);
|
||||
app.use(express.static(__dirname)).listen(port);
|
||||
|
||||
console.log('Server started on port ' + port + ' with /gun');
|
76
examples/angular/index.html
Normal file
@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html>
|
||||
<html ng-app="admin">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="https://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>
|
||||
<script src="../../gun.js"></script>
|
||||
</head>
|
||||
<body ng-controller="editor">
|
||||
<style>
|
||||
html, body {
|
||||
font-family: Verdana, Geneva, sans-serif;
|
||||
}
|
||||
a {
|
||||
color: skyblue;
|
||||
text-decoration: none;
|
||||
cursor: poiner;
|
||||
}
|
||||
ul, li {
|
||||
list-style-type: none;
|
||||
}
|
||||
ul:hover, li:hover {
|
||||
list-style-type: inherit;
|
||||
}
|
||||
input {
|
||||
border: none;
|
||||
border-bottom: dashed 1px gainsboro;
|
||||
}
|
||||
.none {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<h3>Admin JSON Editor</h3>
|
||||
This is a live view of your data, you can edit it in realtime or add new key/values.
|
||||
<ul name="list">
|
||||
<li ng-repeat="(key, val) in data">
|
||||
<div ng-if="key != '_'">
|
||||
<b>{{key}}</b>:
|
||||
<span contenteditable="true" gun>{{val}}</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<form ng-submit="add()">
|
||||
<label>
|
||||
<input ng-model="field" placeholder="key" ng-submit="add()">
|
||||
<a ng-click="add()">add</a>
|
||||
<input type="submit" class="none"/>
|
||||
</label>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
<script>
|
||||
var gun = Gun(location.origin + '/gun');
|
||||
angular.module('admin', []).controller('editor', function($scope){
|
||||
$scope.data = {};
|
||||
$scope.$data = gun.load('blob/data').on(function(data){
|
||||
Gun.obj.map(data, function(val, field){
|
||||
if(val === $scope.data[field]){ return }
|
||||
$scope.data[field] = val;
|
||||
});
|
||||
$scope.$apply();
|
||||
});
|
||||
$scope.add = function(a,b,c){
|
||||
$scope.$data.path($scope.field).set( $scope.data[$scope.field] = 'value' );
|
||||
$scope.field = '';
|
||||
};
|
||||
}).directive('gun', function(){
|
||||
return function(scope, elem){
|
||||
elem.on('keyup', function(){
|
||||
scope.$data.path(scope.key).set( scope.data[scope.key] = elem.text() );
|
||||
});
|
||||
};
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -2,7 +2,7 @@ var gun = require('gun')({
|
||||
s3: (process.env.NODE_ENV === 'production')? null : require('../../test/shotgun') // replace this with your own keys!
|
||||
});
|
||||
|
||||
gun.load('email/mark@gundb.io', function(Mark){
|
||||
gun.load('email/mark@gundb.io').get(function(Mark){
|
||||
console.log("Hello ", Mark);
|
||||
this.path('username').set('amark'); // because we hadn't saved it yet!
|
||||
this.path('cat').get(function(Hobbes){ // `this` is context of the nodes you explore via path
|
||||
|
18
examples/hello-world.js
Normal file
@ -0,0 +1,18 @@
|
||||
var Gun = require('gun');
|
||||
var gun = Gun({
|
||||
s3: {
|
||||
key: '', // AWS Access Key
|
||||
secret: '', // AWS Secret Token
|
||||
bucket: '' // The bucket you want to save into
|
||||
}
|
||||
});
|
||||
gun.set({ hello: 'world' }).key('my/first/data');
|
||||
|
||||
var http = require('http');
|
||||
http.createServer(function (req, res) {
|
||||
gun.load('my/first/data', function(err, data){
|
||||
res.writeHead(200, {'Content-Type': 'application/json'});
|
||||
res.end(JSON.stringify(data));
|
||||
});
|
||||
}).listen(1337, '127.0.0.1');
|
||||
console.log('Server running at http://127.0.0.1:1337/');
|
2
examples/node_modules/gun/index.js
generated
vendored
@ -1 +1 @@
|
||||
module.exports = require(__dirname + '/../../../shots');
|
||||
module.exports = require(__dirname + '/../../../index');
|
17
examples/package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "examples",
|
||||
"main": "all.js",
|
||||
"description": "Example gun apps"
|
||||
, "version": "0.0.1"
|
||||
, "engines": {
|
||||
"node": "~>0.6.6"
|
||||
}
|
||||
, "dependencies": {
|
||||
"express": "~>4.9.0",
|
||||
"gun": "~>0.0.8"
|
||||
}
|
||||
, "scripts": {
|
||||
"start": "node all.js",
|
||||
"test": "mocha"
|
||||
}
|
||||
}
|
15
examples/todo/index.html
Normal file
@ -0,0 +1,15 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>ToDo</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
Todo List
|
||||
</h1>
|
||||
<form name="sign" action="http://localhost:8888/gun">
|
||||
<input name="email" placeholder="email">
|
||||
<input name="password" type="password" placeholder="password">
|
||||
<input type="submit" name="it" value="sign in or up">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -1,4 +0,0 @@
|
||||
```
|
||||
curl http://randomuser.coolaj86.com/api?seed=rohkevus&results=50000 \
|
||||
-o users.json
|
||||
```
|
@ -1,43 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var users = require('./users.json').results
|
||||
, Chance = require('chance')
|
||||
, chance = new Chance(1234)
|
||||
, b
|
||||
, d = Date.now()
|
||||
, num = 50
|
||||
;
|
||||
|
||||
users = users.map(function(user){
|
||||
user = user.user;
|
||||
user._ = user._ || {};
|
||||
user._['#'] = user.sha1;
|
||||
user.first = user.name.first;
|
||||
user.last = user.name.last;
|
||||
user.title = user.name.title;
|
||||
delete user.name;
|
||||
user.zip = user.location.zip;
|
||||
user.street = user.location.street;
|
||||
user.city = user.location.city;
|
||||
user.state = user.location.state;
|
||||
delete user.location;
|
||||
return user;
|
||||
})
|
||||
users = chance.shuffle(users).slice(0, num);
|
||||
b = chance.shuffle(users.slice(0));
|
||||
b.forEach(function (user, i) {
|
||||
if (0 === (i % 100)) {
|
||||
console.log((Date.now() - d) / 1000, i);
|
||||
d = Date.now();
|
||||
}
|
||||
user.friends = chance.shuffle(users).slice(chance.integer({ min: 20, max: (num < 120)? num : 120 }));
|
||||
});
|
||||
|
||||
var gun = require('gun')({
|
||||
s3: require('../test/shotgun') // replace this with your own keys!
|
||||
});
|
||||
|
||||
gun.set(b[0]);
|
||||
|
||||
console.log(b[1], b[1].friends.length);
|
||||
console.log((Date.now() - d) / 1000, num);
|
1550004
fixtures/users.json
@ -1,10 +0,0 @@
|
||||
/*!
|
||||
* Amplify Store - Persistent Client-Side Storage 1.1.0
|
||||
*
|
||||
* Copyright 2011 appendTo LLC. (http://appendto.com/team)
|
||||
* Dual licensed under the MIT or GPL licenses.
|
||||
* http://appendto.com/open-source-licenses
|
||||
*
|
||||
* http://amplifyjs.com
|
||||
*/
|
||||
(function(a,b){function e(a,e){c.addType(a,function(f,g,h){var i,j,k,l,m=g,n=(new Date).getTime();if(!f){m={},l=[],k=0;try{f=e.length;while(f=e.key(k++))d.test(f)&&(j=JSON.parse(e.getItem(f)),j.expires&&j.expires<=n?l.push(f):m[f.replace(d,"")]=j.data);while(f=l.pop())e.removeItem(f)}catch(o){}return m}f="__amplify__"+f;if(g===b){i=e.getItem(f),j=i?JSON.parse(i):{expires:-1};if(j.expires&&j.expires<=n)e.removeItem(f);else return j.data}else if(g===null)e.removeItem(f);else{j=JSON.stringify({data:g,expires:h.expires?n+h.expires:null});try{e.setItem(f,j)}catch(o){c[a]();try{e.setItem(f,j)}catch(o){throw c.error()}}}return m})}var c=a.store=function(a,b,d,e){var e=c.type;d&&d.type&&d.type in c.types&&(e=d.type);return c.types[e](a,b,d||{})};c.types={},c.type=null,c.addType=function(a,b){c.type||(c.type=a),c.types[a]=b,c[a]=function(b,d,e){e=e||{},e.type=a;return c(b,d,e)}},c.error=function(){return"amplify.store quota exceeded"};var d=/^__amplify__/;for(var f in{localStorage:1,sessionStorage:1})try{window[f].getItem&&e(f,window[f])}catch(g){}if(window.globalStorage)try{e("globalStorage",window.globalStorage[window.location.hostname]),c.type==="sessionStorage"&&(c.type="globalStorage")}catch(g){}(function(){if(!c.types.localStorage){var a=document.createElement("div"),d="amplify";a.style.display="none",document.getElementsByTagName("head")[0].appendChild(a);try{a.addBehavior("#default#userdata"),a.load(d)}catch(e){a.parentNode.removeChild(a);return}c.addType("userData",function(e,f,g){a.load(d);var h,i,j,k,l,m=f,n=(new Date).getTime();if(!e){m={},l=[],k=0;while(h=a.XMLDocument.documentElement.attributes[k++])i=JSON.parse(h.value),i.expires&&i.expires<=n?l.push(h.name):m[h.name]=i.data;while(e=l.pop())a.removeAttribute(e);a.save(d);return m}e=e.replace(/[^-._0-9A-Za-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u37f-\u1fff\u200c-\u200d\u203f\u2040\u2070-\u218f]/g,"-");if(f===b){h=a.getAttribute(e),i=h?JSON.parse(h):{expires:-1};if(i.expires&&i.expires<=n)a.removeAttribute(e);else return i.data}else f===null?a.removeAttribute(e):(j=a.getAttribute(e),i=JSON.stringify({data:f,expires:g.expires?n+g.expires:null}),a.setAttribute(e,i));try{a.save(d)}catch(o){j===null?a.removeAttribute(e):a.setAttribute(e,j),c.userData();try{a.setAttribute(e,i),a.save(d)}catch(o){j===null?a.removeAttribute(e):a.setAttribute(e,j);throw c.error()}}return m})}})(),function(){function e(a){return a===b?b:JSON.parse(JSON.stringify(a))}var a={},d={};c.addType("memory",function(c,f,g){if(!c)return e(a);if(f===b)return e(a[c]);d[c]&&(clearTimeout(d[c]),delete d[c]);if(f===null){delete a[c];return null}a[c]=f,g.expires&&(d[c]=setTimeout(function(){delete a[c],delete d[c]},g.expires));return f})}()})(this.amplify=this.amplify||{})
|
577
gun0.js
@ -1,577 +0,0 @@
|
||||
/**** The Abstact Structure
|
||||
|
||||
A JSON graph structure that is lightweight and flexible to describe anything.
|
||||
The current goal, however, is limited to encompassing HTML and CSS for starters.
|
||||
Immediately after that is describing code as a state.
|
||||
|
||||
A node is something which has relationships and or value.
|
||||
Relationships and values aren't any different, other than that
|
||||
a relationship is a reference and a value is embedded.
|
||||
|
||||
*****/
|
||||
module.exports = require('theory')
|
||||
('gun',function(a){
|
||||
a.gun = (function(){
|
||||
function gun(p,v,w){
|
||||
var args = arguments.length
|
||||
, cb = a.fns.is(v)? v : null
|
||||
, g, n, b, w = w || a.time.now();
|
||||
if(gun.is(this)){
|
||||
n = this;
|
||||
g = n._.clip || function(){ return {} };
|
||||
if(a.text.is(p)){
|
||||
if(args >= 2){ // set
|
||||
var u, ref = {}
|
||||
, val = gun.at(n,p,ref);
|
||||
if(!ref.cartridge || !ref.cartridge._ || !ref.cartridge._[gun._.id]){
|
||||
return;
|
||||
} ref.id = ref.cartridge._[gun._.id] +'.'+ ref.path;
|
||||
v = gun.ify.be(v);
|
||||
b = gun.bullet(ref.path,v,w);
|
||||
console.log("after:", v, b);
|
||||
if(a.gun.ham){
|
||||
v = a.gun.ham(ref.cartridge,b,v,w); // TODO: BUG! Need to update when also!
|
||||
if(v === u){
|
||||
console.log("HAM REJECTION", p, v, val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.log("HAM set", p, v);
|
||||
if(ref.at){
|
||||
if(v === null){
|
||||
if(a.list.is(ref.at)){
|
||||
t = o.val || t;
|
||||
var j = ref.at.indexOf(ref.prop);
|
||||
if(0 <= j){
|
||||
ref.at.splice(j,1);
|
||||
} else {
|
||||
j = a.list(ref.at).find(gun.id(ref.prop));
|
||||
if(j){
|
||||
ref.at.splice(--j,1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
delete ref.at[ref.prop];
|
||||
}
|
||||
var del = {}; del[ref.id] = null;
|
||||
gun.fire(del, g[gun._.id], w);
|
||||
v = ref.at;
|
||||
} else {
|
||||
if(a.fns.is(v) && v[gun._.id]){ // then it is a clip!
|
||||
v = {};
|
||||
}
|
||||
v = gun.at(v);
|
||||
if(gun.is(v)){
|
||||
v = gun.id(v._[gun._.id]); // update this to handle clip#cart
|
||||
} else {
|
||||
v = gun.ify.be(v);
|
||||
}
|
||||
if(a.obj.is(v)){
|
||||
ref.at[ref.prop] = v;
|
||||
//ref.tmp = ref.at[ref.prop] = gun.ify.obj(v, val);
|
||||
} else
|
||||
if(a.list.is(v)){
|
||||
ref.tmp = ref.at[ref.prop] = gun.ify.list(v, val);
|
||||
} else {
|
||||
ref.at[ref.prop] = v;
|
||||
}
|
||||
var diff = {}; diff[ref.id] = v;
|
||||
gun.fire(diff, g[gun._.id], w);
|
||||
v = ref.tmp || v;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(args >= 1){ // get
|
||||
v = gun.at(n,p);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
n = a.obj.is(v)? v : a.obj.is(p)? p : null;
|
||||
p = a.text.is(p)? p : gun.id();
|
||||
if(a.obj.is(n)){ // create a clip from this object
|
||||
var c;
|
||||
g = gun.ify(n);
|
||||
if((c = gun.magazine[p]) && a.fns.is(c)){
|
||||
console.log("clip already exists in magazine,", p);
|
||||
a.obj(g).each(function(n,id){
|
||||
if(!gun.is(n)){ return }
|
||||
c(id,n);
|
||||
});
|
||||
return gun.magazine[p];
|
||||
}
|
||||
var clip = gun.magazine[p] = function(p,v,w){
|
||||
var args, id, path, n, w = w || a.time.now();
|
||||
if(a.text.is(p)){
|
||||
id = a.text(p).clip('.',0,1);
|
||||
path = a.text(p).clip('.',1);
|
||||
if(a.obj(g).has(id) && gun.is(g[id])){
|
||||
n = g[id];
|
||||
p = path;
|
||||
}
|
||||
}
|
||||
args = a.list.slit.call(arguments);
|
||||
if(!args.length){
|
||||
return g;
|
||||
}
|
||||
if(path){
|
||||
if(n){
|
||||
n._.clip = n._.clip || clip;
|
||||
return gun.apply(n, args);
|
||||
}
|
||||
return;
|
||||
}
|
||||
var fn = function(p,v,w){
|
||||
if(!n){ return }
|
||||
var args = a.list.slit.call(arguments);
|
||||
return !args.length? n : gun.apply(n,args);
|
||||
}
|
||||
if(n){
|
||||
if(args.length === 1){
|
||||
n._.clip = n._.clip || clip;
|
||||
return fn;
|
||||
}
|
||||
if(gun.is(v) && gun.ham){
|
||||
var h = v._[gun._.ham] || {};
|
||||
a.obj(v).each(function(v,p){
|
||||
if(p === '_'){ return }
|
||||
console.log('-------------->', p, h[p], h, 1); // Wait! This isn't correct because it should be '>' not '.'!
|
||||
fn(p, v, h[p] || (a.num.is(h)? h : 1)); // Wait! This isn't correct because it should be '>' not '.'!
|
||||
});
|
||||
return fn;
|
||||
}
|
||||
if(v === null){
|
||||
delete g[n._[gun._.id]];
|
||||
var del = {}; del[n._[gun._.id]] = n = null;
|
||||
gun.fire(del, g[gun._.id], w); // TODO: BUG! HAM UPDATES!
|
||||
return null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(a.text.is(p) && a.obj.is(v)){
|
||||
v = v;
|
||||
v._ = gun.id(p);
|
||||
} else
|
||||
if(a.obj.is(p)){
|
||||
v = p;
|
||||
}
|
||||
if(a.obj.is(v)){
|
||||
n = gun.ify(v,u,{}); // a clip cannot be created from this, only a single cartridge
|
||||
n._ = n._ || gun.id({});
|
||||
n._.clip = clip; // JSONifying excludes functions.
|
||||
var add = {}; add[n._[gun._.id]] = g[n._[gun._.id]] = n;
|
||||
gun.fire(add, clip[gun._.id], w); // TODO: BUG! HAM UPDATES!
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
clip[gun._.id] = p;
|
||||
return clip;
|
||||
}
|
||||
} var u;
|
||||
gun._ = {
|
||||
id: '#' // do not change this!
|
||||
}
|
||||
gun.is = function(o){
|
||||
return (o && o._ && o._[gun._.id])? true : false;
|
||||
}
|
||||
gun.id = function(t){
|
||||
if(t){
|
||||
var _ = {};_[gun._.id] = a.text.is(t)? t : gun.id();
|
||||
return _;
|
||||
}
|
||||
return a.text.r(9);
|
||||
}
|
||||
gun.at = function(n,p,ref){
|
||||
if(a.fns.is(n)){
|
||||
n = n();
|
||||
}
|
||||
if(!p){
|
||||
return n;
|
||||
}
|
||||
ref = ref || {};
|
||||
var pp = a.list.is(p)? p : (p||'').split('.')
|
||||
, g = a.fns.is(n._.clip)? n._.clip() : this
|
||||
, i = 0, l = pp.length, v = n
|
||||
, x, y, z;
|
||||
ref.cartridge = n;
|
||||
ref.prop = pp[l-1];
|
||||
ref.path = pp.slice(i).join('.');
|
||||
while(i < l && v !== u){
|
||||
x = pp[i++];
|
||||
if(a.obj.is(v) && a.obj(v).has(x)){
|
||||
ref.at = v;
|
||||
v = v[x];
|
||||
if(v && v[gun._.id]){
|
||||
v = a.obj(g).has(v[gun._.id])? g[v[gun._.id]] : u;
|
||||
if(v){
|
||||
return gun.at.call(g,v,pp.slice(i),ref);
|
||||
}
|
||||
}
|
||||
} else
|
||||
if(a.list.is(v)){
|
||||
ref.at = v;
|
||||
return a.list(v).each(function(w,j){
|
||||
if(!w) return;
|
||||
if(!p) return;
|
||||
w = a.obj(g).has(w[gun._.id]||w)? g[w[gun._.id]||w] : u;
|
||||
if(!w) return;
|
||||
if(w._ && x === w._[gun._.id]){
|
||||
i += 1;
|
||||
p = false;
|
||||
}
|
||||
return gun.at.call(g,w,pp.slice(i-1),ref);
|
||||
});
|
||||
} else {
|
||||
ref.at = v;
|
||||
v = u;
|
||||
}
|
||||
}
|
||||
if(a.list.is(v)){
|
||||
ref.at = v;
|
||||
v = a.list(v).each(function(w,j,t){
|
||||
if(w){
|
||||
if(a.obj(g).has(w[gun._.id]||w)) t(g[w[gun._.id]||w]);
|
||||
}
|
||||
}) || [];
|
||||
}
|
||||
return i < l? u : v;
|
||||
}
|
||||
gun.ify = function(o, opt, n){
|
||||
var g = {};
|
||||
opt = opt || {};
|
||||
opt.seen = opt.seen || [];
|
||||
if(!a.obj.is(o)){ return g }
|
||||
function ify(o,i,f,n,p){
|
||||
if(gun.ify.is(o)){
|
||||
f[i] = o;
|
||||
return
|
||||
}
|
||||
if(a.obj.is(o)){
|
||||
var seen;
|
||||
if(seen = ify.seen(o)){
|
||||
ify.be(seen);
|
||||
return;
|
||||
}
|
||||
if(gun.is(o)){
|
||||
f[i] = gun.id(o._[gun._.id]);
|
||||
g[o._[gun._.id]] = n;
|
||||
} else {
|
||||
f[i] = n;
|
||||
}
|
||||
opt.seen.push({cartridge: n, prop: i, from: f, src: o});
|
||||
a.obj(o).each(function(v,j){
|
||||
ify(v,j,n,{},f);
|
||||
});
|
||||
if(gun.is(n)){
|
||||
g[n._[gun._.id]] = n;
|
||||
f[i] = gun.id(n._[gun._.id]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(a.list.is(o)){
|
||||
f[i] = a.list(o).each(function(v,j,t){
|
||||
var seen;
|
||||
if(a.fns.is(v)){
|
||||
v = gun.at(v);
|
||||
}
|
||||
if(a.obj.is(v)){
|
||||
if(seen = ify.seen(v)){
|
||||
ify.be(seen);
|
||||
if(gun.is(seen.cartridge)){ t(seen.cartridge._[gun._.id]) }
|
||||
} else {
|
||||
gun.ify(v, opt, n);
|
||||
if(gun.is(n)){
|
||||
t(n._[gun._.id]);
|
||||
}
|
||||
}
|
||||
} else
|
||||
if(a.text.is(v)){
|
||||
if(a.obj(g).has(v)){
|
||||
t(v);
|
||||
} else {
|
||||
t(v); // same as above :/ because it could be that this ID just hasn't been indexed yet.
|
||||
}
|
||||
}
|
||||
}) || [];
|
||||
return;
|
||||
}
|
||||
}
|
||||
ify.be = function(seen){
|
||||
var n = seen.cartridge;
|
||||
n._ = n._||{};
|
||||
n._[gun._.id] = n._[gun._.id]||gun.id();
|
||||
g[n._[gun._.id]] = n;
|
||||
if(seen.from){
|
||||
seen.from[seen.prop] = gun.id(n._[gun._.id]);
|
||||
}
|
||||
}
|
||||
ify.seen = function(o){
|
||||
return a.list(opt.seen).each(function(v){
|
||||
if(v && v.src === o){ return v }
|
||||
}) || false;
|
||||
}
|
||||
var is = true, cartridge = n || {};
|
||||
a.obj(o).each(function(v,i){
|
||||
if(!gun.is(v)){ is = false }
|
||||
ify(v, i, cartridge, {});
|
||||
});
|
||||
if(!is){
|
||||
ify.be({cartridge: cartridge});
|
||||
g[cartridge._[gun._.id]] = cartridge;
|
||||
}
|
||||
if(n){
|
||||
return n;
|
||||
}
|
||||
return g;
|
||||
}
|
||||
gun.ify.be = function(v,g){ // update this to handle externals!
|
||||
var r;
|
||||
g = g || {};
|
||||
if(gun.ify.is(v)){
|
||||
r = v;
|
||||
} else
|
||||
if(a.obj.is(v)){
|
||||
r = {};
|
||||
a.obj(v).each(function(w,i){
|
||||
w = gun.ify.be(w);
|
||||
if(w === u){ return }
|
||||
r[i] = w;
|
||||
});
|
||||
} else
|
||||
if(a.list.is(v)){ // references only
|
||||
r = a.list(v).each(function(w,i,t){
|
||||
if(!w){ return }
|
||||
w = gun.at(w);
|
||||
if(gun.is(w)){
|
||||
t(w._[gun._.id]);
|
||||
} else
|
||||
if(w[gun._.id]){
|
||||
t(w[gun._.id]);
|
||||
} else
|
||||
if(a.obj(g).has(w)){
|
||||
t(w);
|
||||
}
|
||||
}) || [];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
gun.ify.is = function(v){ // null, binary, number (!Infinity), text, or a ref.
|
||||
if(v === null){ return true } // deletes
|
||||
if(v === Infinity){ return false }
|
||||
if(a.bi.is(v)
|
||||
|| a.num.is(v)
|
||||
|| a.text.is(v)){
|
||||
return true; // simple values
|
||||
}
|
||||
if(a.obj.is(v) && a.text.is(v[gun._.id])){ // ref
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
gun.ify.obj = function(v, val){
|
||||
if(a.obj.is(val) && a.obj.is(v)){
|
||||
a.obj(v).each(function(d, i){
|
||||
if(a.gun.ham && a.gun.ham.call(g,n,p,v,w,val)){
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
return v;
|
||||
}
|
||||
gun.ify.list = function(v, val){
|
||||
var r;
|
||||
r = a.list.is(val)? val.concat(v) : v;
|
||||
r = a.list(r).each(function(r,i,t){t(r,1)})||{};
|
||||
r = a.obj(r).each(function(w,r,t){t(r)})||[]; // idempotency of this over latency? TODO! INVESTIGATE!!
|
||||
return r;
|
||||
}
|
||||
gun.duel = function(old,now){
|
||||
a.obj(now).each(function(g,id){
|
||||
if(!gun.is(g)){ return }
|
||||
var c;
|
||||
if(a.obj(old).has(id) && gun.is(c = old[id])){
|
||||
a.obj(g).each(function(v,i){
|
||||
|
||||
});
|
||||
} else {
|
||||
old[id] = g;
|
||||
}
|
||||
});
|
||||
}
|
||||
gun.bullet = function(p,v,w){
|
||||
var b = {};
|
||||
b[p] = v;
|
||||
if(gun.ham && gun._.ham){
|
||||
b._ = {};
|
||||
b._[gun._.ham] = w || a.time.now();
|
||||
}
|
||||
return b;
|
||||
}
|
||||
gun.fire = function(bullet,c,w,op){
|
||||
bullet = bullet.what? bullet : {what: bullet};
|
||||
bullet.where = c || bullet.where;
|
||||
bullet.when = w || bullet.when;
|
||||
if(!a.obj.is(bullet.what)){ return gun.fire.jam("No ammo.", bullet) }
|
||||
if(!a.num.is(bullet.when)){ return gun.fire.jam("No time.", bullet) }
|
||||
if(!a.text.is(bullet.where)){ return gun.fire.jam("No location.", bullet) }
|
||||
bullet.how = bullet.how || {};
|
||||
bullet.how.gun = op || 1;
|
||||
theory.on(gun.event).emit(bullet);
|
||||
}
|
||||
gun.fire.jam = function(s,b){ if(b){ return console.log("Gun jam:",s,b) } console.log("Gun jam:",s) }
|
||||
gun.shots = function(hear,s){ return theory.on(gun.event+(s?'.'+s:'')).event(hear) }
|
||||
gun.event = 'gun';
|
||||
gun.magazine = {};
|
||||
return gun;
|
||||
})();
|
||||
/* Hypothetical Amnesia Machine
|
||||
|
||||
A thought experiment in efficient cause, linear time, and knowledge.
|
||||
Suppose everything you will ever know in your life was already be stored
|
||||
in your brain. Now suppose we have some machine, which delicately traverses
|
||||
your mind and gives you amnesia about all these facts. You now no longer can
|
||||
recall any of this knowledge because that information is disconnected from
|
||||
all other pieces of knowledge - making it impossible for your mind to then
|
||||
associate and thus remember things. But the curious fact is that all this
|
||||
knowledge is still stored within your mind, it is just inaccessible.
|
||||
|
||||
Now suppose, this amnesia machine is designed to unlock various bits of
|
||||
that knowledge, making it connected again to other related tidbits and thus
|
||||
making it accessible to you. This unlocking process is activated at some pre-
|
||||
determined value, such as a timestamp. Can it really be said that this is
|
||||
indistinguishable from the supposed flow of past, present, and future?
|
||||
|
||||
Such that future information is not just unknown, but fundamentally does
|
||||
not exist, and then by actions taken in the present is caused to be. As a
|
||||
result of your senses, you then experience this effect, and thus 'learning'
|
||||
that knowledge. Could we truly build a proof that reality is one way or the
|
||||
other? But if we did, wouldn't that scurrying little machine just race across
|
||||
our minds and assure it induces amnesia into our remembrance of its existence?
|
||||
Nay, we cannot. We can only hypothesize about the existence of this crafty
|
||||
device. For the blindness that it does shed upon us captivates our perception
|
||||
of how the world really is, us forever duped into thinking time is linear.
|
||||
|
||||
And here, in write and code, is this machine used and exploited. Holding
|
||||
in its power the ability to quarantine and keep secret, until upon some
|
||||
value, some condition, some scheme or rendition, does it raise its mighty
|
||||
clutch of deception and expose the truth, shining in its radiance and glory,
|
||||
all at the ease of making a single connection. Whereupon we do assure that
|
||||
all conscious actors are agreed upon in a unified spot, synchronized in the
|
||||
capacity to realize such beautiful information.
|
||||
*/
|
||||
a.gun._.ham = '>';
|
||||
a.gun.ham = function(n,p,v,w){
|
||||
if(!n){ return }
|
||||
console.log("HAM:", n, p, v, w);
|
||||
if(!a.text.is(p)){
|
||||
if(a.obj.is(p) && p._){
|
||||
a.obj(p).each(function(sv,i){
|
||||
if(i === '_'){ return }
|
||||
v = sv = a.gun.ham(n,i,sv, a.gun.ham.when(p._, i) || w); // works for now, but may not on other non-bullet objects
|
||||
if(sv === u){
|
||||
delete p[i];
|
||||
} else {
|
||||
p[i] = sv;
|
||||
}
|
||||
});
|
||||
return v;
|
||||
}
|
||||
return;
|
||||
}
|
||||
var val = a.gun.at(n,p)
|
||||
, when, age, now, u, q;
|
||||
q = p.replace('.',a.gun._.ham);
|
||||
n._ = n._ || {};
|
||||
n._[a.gun._.ham] = n._[a.gun._.ham] || {};
|
||||
age = function(q){
|
||||
if(!q){ return 0 }
|
||||
var when = n._[a.gun._.ham][q];
|
||||
if(when || when === 0){
|
||||
return when;
|
||||
}
|
||||
return age(a.text(q).clip(a.gun._.ham,0,-1));
|
||||
}
|
||||
when = age(q);
|
||||
v = (function(){
|
||||
if(a.gun.ify.is(v)){ // simple values are directly resolved
|
||||
return v;
|
||||
} else
|
||||
if(a.obj.is(v)){
|
||||
if(a.obj.is(val)){ // resolve sub-values
|
||||
var change = false;
|
||||
a.obj(v).each(function(sv,i){
|
||||
sv = a.gun.ham(n, (p+'.'+i), sv, w, val[i]); // TODO: BUG! Still need to deal with sub-value bullets resolving to container's age.
|
||||
if(sv === u){ return }
|
||||
change = true;
|
||||
val[i] = sv;
|
||||
});
|
||||
if(change){
|
||||
return v = val;
|
||||
} else {
|
||||
return;; // nothing new
|
||||
}
|
||||
}
|
||||
a.obj(v).each(function(sv,i){
|
||||
sv = a.gun.ham(n, (p+'.'+i), sv, w, (val||{})[i]);
|
||||
if(sv === u){ delete v[i] }
|
||||
});
|
||||
return v;
|
||||
} else
|
||||
if(a.list.is(v)){
|
||||
if(!a.list.is(val)){ // TODO: deal with this later.
|
||||
return v;
|
||||
}
|
||||
return v;
|
||||
} else { // unknown matches are directly resolved
|
||||
return;
|
||||
}
|
||||
})();
|
||||
if(v === u){ return }
|
||||
if(w < when){
|
||||
console.log("new < old");
|
||||
return;
|
||||
} else
|
||||
if(w === when){ // this needs to be updated also!
|
||||
if(val === v || a.test.is(val,v) || a.text.ify(val) < a.text.ify(v)){
|
||||
console.log("new === old");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
if((now = a.time.now() + 1) < w){ // tolerate a threshold of 1ms.
|
||||
console.log("amnesia", Math.ceil(w - now));
|
||||
/* Amnesia Quarantine */
|
||||
a.time.wait(function(){
|
||||
console.log("run again");
|
||||
a.gun.call(n,p,v,w);
|
||||
}, Math.ceil(w - now)); // crude implementation for now.
|
||||
return;
|
||||
}
|
||||
v = (function(){
|
||||
if(a.obj.is(v)){
|
||||
w = when; // objects are resolved relative to their previous values.
|
||||
}
|
||||
return v;
|
||||
})();
|
||||
n._[a.gun._.ham][q] = w; // if properties get deleted it may be nice to eventually delete the HAM, but that could cause problems so we don't for now.
|
||||
// ps. It may be possible to delete simple values if they are not proceeded by an object?
|
||||
return v;
|
||||
}
|
||||
a.gun.ham.when = function(w, i){
|
||||
var h;
|
||||
if(w && w._){
|
||||
w = w._;
|
||||
}
|
||||
if(w && (h = w[a.gun._.ham])){
|
||||
if(a.obj(h).has(i)){
|
||||
return h[i];
|
||||
}
|
||||
if(a.num.is(h)){
|
||||
return h;
|
||||
}
|
||||
}
|
||||
}
|
||||
return a.gun;
|
||||
});
|
@ -1,17 +0,0 @@
|
||||
var Gun = require('gun');
|
||||
var gun = Gun({
|
||||
s3: {
|
||||
key: '', // AWS Access Key
|
||||
secret: '', // AWS Secret Token
|
||||
bucket: '' // The bucket you want to save into
|
||||
}});
|
||||
gun.set({ hello: 'world' }).key('my/first/data')
|
||||
|
||||
var http = require('http');
|
||||
http.createServer(function (req, res) {
|
||||
gun.load('my/first/data', function(data){
|
||||
res.writeHead(200, {'Content-Type': 'application/json'});
|
||||
res.end(JSON.stringify(data));
|
||||
});
|
||||
}).listen(1337, '127.0.0.1');
|
||||
console.log('Server running at http://127.0.0.1:1337/');
|
@ -4,7 +4,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
|
||||
<style>
|
||||
body {
|
||||
background-image: url(./img/kimber.jpg);
|
||||
background-image: url(./web/img/kimber.jpg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: left top;
|
||||
font-family: Arial;
|
||||
|
2
index.js
@ -1 +1 @@
|
||||
module.exports = require('./shots');
|
||||
module.exports = require('./lib/server');
|
31
init.js
@ -1,31 +0,0 @@
|
||||
(function(){
|
||||
|
||||
process.env.rootdir = __dirname;
|
||||
var LIVE = process.env.LIVE || (process.env.NODE_ENV === 'production'), web, opt = {};
|
||||
opt.port = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT;
|
||||
opt.host = process.env.OPENSHIFT_NODEJS_IP;
|
||||
if(opt.port || opt.host){ LIVE = true }
|
||||
opt.port = opt.port || 8888;
|
||||
opt.host = opt.host || '0.0.0.0';
|
||||
|
||||
if(LIVE){
|
||||
//process.env['redis-install'] = '/tmp';
|
||||
} else {
|
||||
// Keys are hosted outside this folder, you must provide your own with environment variables.
|
||||
var keys = '../../linux/.ssh/keys-gun.js';
|
||||
if((require('fs').existsSync||require('path').existsSync)(keys)){
|
||||
require(keys);
|
||||
}
|
||||
if((require('fs').existsSync||require('path').existsSync)('../coalesce')){
|
||||
web = require('../coalesce');
|
||||
}
|
||||
}
|
||||
|
||||
opt.run = ['./test/server', './test/tests', './test/shoot'];
|
||||
opt.node = {key: "temp gun key", src:["http://gunjs.herokuapp.com/com","http://gunjs-amark.rhcloud.com/com","http://gunjs.aws.af.cm/com"]};
|
||||
|
||||
web = web || require('coalesce');
|
||||
web(opt);
|
||||
console.log("Gun @ "+ opt.port);
|
||||
|
||||
})();
|
@ -127,7 +127,7 @@
|
||||
return this;
|
||||
}
|
||||
return s3;
|
||||
})(require('../gun'), {});
|
||||
})(require('gun/gun'), {});
|
||||
/**
|
||||
Knox S3 Config is:
|
||||
knox.createClient({
|
50
lib/http.js
Normal file
@ -0,0 +1,50 @@
|
||||
var Gun = require('gun/gun')
|
||||
, formidable = require('formidable')
|
||||
, url = require('url');
|
||||
module.exports = function(req, res, next){
|
||||
next = next || function(){};
|
||||
if(!req || !res){ return next() }
|
||||
if(!req.url){ return next() }
|
||||
if(!req.method){ return next() }
|
||||
var msg = {};
|
||||
msg.url = url.parse(req.url, true);
|
||||
msg.method = (req.method||'').toLowerCase();
|
||||
msg.headers = req.headers;
|
||||
var u, body
|
||||
, form = new formidable.IncomingForm()
|
||||
, post = function(err, body){
|
||||
if(u !== body){ msg.body = body }
|
||||
next(msg, function(reply){
|
||||
if(!res){ return }
|
||||
if(!reply){ return res.end() }
|
||||
if(Gun.obj.has(reply, 'statusCode') || Gun.obj.has(reply, 'status')){
|
||||
res.statusCode = reply.statusCode || reply.status;
|
||||
}
|
||||
if(reply.headers){
|
||||
if(!res._headerSent){
|
||||
Gun.obj.map(reply.headers, function(val, field){
|
||||
res.setHeader(field, val);
|
||||
});
|
||||
}
|
||||
}
|
||||
if(Gun.obj.has(reply,'chunk') || Gun.obj.has(reply,'write')){
|
||||
res.write(Gun.text.ify(reply.chunk || reply.write) || '');
|
||||
}
|
||||
if(Gun.obj.has(reply,'body') || Gun.obj.has(reply,'end')){
|
||||
res.end(Gun.text.ify(reply.body || reply.end) || '');
|
||||
}
|
||||
});
|
||||
}
|
||||
form.on('field',function(k,v){
|
||||
(body = body || {})[k] = v;
|
||||
}).on('file',function(k,v){
|
||||
return; // files not supported in gun yet
|
||||
}).on('error',function(e){
|
||||
if(form.done){ return }
|
||||
post(e);
|
||||
}).on('end', function(){
|
||||
if(form.done){ return }
|
||||
post(null, body);
|
||||
});
|
||||
form.parse(req);
|
||||
}
|
37
lib/jsonp.js
Normal file
@ -0,0 +1,37 @@
|
||||
var Gun = require('gun/gun');
|
||||
module.exports = function(req, cb){
|
||||
if(!req.url || !req.url.query || !req.url.query.jsonp){ return cb }
|
||||
cb.jsonp = req.url.query.jsonp;
|
||||
delete req.url.query.jsonp;
|
||||
Gun.obj.map(Gun.obj.ify(req.url.query['`']), function(val, i){
|
||||
req.headers[i] = val;
|
||||
});
|
||||
delete req.url.query['`'];
|
||||
if(req.url.query.$){
|
||||
req.body = req.url.query.$;
|
||||
if(!Gun.obj.has(req.url.query, '^') || 'json' == req.url.query['^']){
|
||||
req.body = Gun.obj.ify(req.body); // TODO: BUG! THIS IS WRONG! This doesn't handle multipart chunking, and will fail!
|
||||
}
|
||||
}
|
||||
delete req.url.query.$;
|
||||
delete req.url.query['^'];
|
||||
delete req.url.query['%'];
|
||||
var reply = {headers:{}};
|
||||
return function(res){
|
||||
if(!res){ return }
|
||||
if(res.headers){
|
||||
Gun.obj.map(res.headers, function(val, field){
|
||||
reply.headers[field] = val;
|
||||
});
|
||||
}
|
||||
reply.headers['Content-Type'] = "text/javascript";
|
||||
if(Gun.obj.has(res,'chunk') && (!reply.body || Gun.list.is(reply.chunks))){
|
||||
(reply.chunks = reply.chunks || []).push(res.chunk);
|
||||
}
|
||||
if(Gun.obj.has(res,'body')){
|
||||
reply.body = res.body; // self-reference yourself so on the client we can get the headers and body.
|
||||
reply.body = ';'+ cb.jsonp + '(' + Gun.text.ify(reply) + ');'; // javascriptify it! can't believe the client trusts us.
|
||||
cb(reply);
|
||||
}
|
||||
}
|
||||
}
|
113
lib/s3.js
Normal file
@ -0,0 +1,113 @@
|
||||
;(function(){
|
||||
var Gun = require('gun/gun');
|
||||
var S3 = require('./aws');
|
||||
|
||||
Gun.on('opt').event(function(gun, opt){
|
||||
opt.s3 = opt.s3 || {};
|
||||
var s3 = gun.__.opt.s3 = gun.__.opt.s3 || S3(opt && opt.s3);
|
||||
s3.prefix = s3.prefix || opt.s3.prefix || '';
|
||||
s3.prekey = s3.prekey || opt.s3.prekey || '';
|
||||
s3.prenode = s3.prenode || opt.s3.prenode || '_/nodes/';
|
||||
gun.__.opt.batch = opt.batch || gun.__.opt.batch || 10;
|
||||
gun.__.opt.throttle = opt.throttle || gun.__.opt.throttle || 15;
|
||||
gun.__.opt.disconnect = opt.disconnect || gun.__.opt.disconnect || 5;
|
||||
s3.load = s3.load || function(key, cb, opt){
|
||||
if(!key){ return }
|
||||
cb = cb || function(){};
|
||||
opt = opt || {};
|
||||
if(key[Gun._.soul]){
|
||||
key = s3.prefix + s3.prenode + key[Gun._.soul];
|
||||
} else {
|
||||
key = s3.prefix + s3.prekey + key;
|
||||
}
|
||||
s3.get(key, function(err, data, text, meta){
|
||||
console.log('via s3', key, err);
|
||||
if(meta && meta[Gun._.soul]){
|
||||
return s3.load(meta, cb);
|
||||
}
|
||||
if(err && err.statusCode == 404){
|
||||
err = null; // we want a difference between 'unfound' (data is null) and 'error' (auth is wrong).
|
||||
}
|
||||
cb(err, data);
|
||||
});
|
||||
}
|
||||
s3.set = s3.set || function(nodes, cb){
|
||||
s3.batching += 1;
|
||||
cb = cb || function(){};
|
||||
cb.count = 0;
|
||||
var next = s3.next
|
||||
, ack = Gun.text.random(8)
|
||||
, batch = s3.batch[next] = s3.batch[next] || {};
|
||||
s3.on(ack).once(cb);
|
||||
Gun.obj.map(nodes, function(node, soul){
|
||||
cb.count += 1;
|
||||
batch[soul] = (batch[soul] || 0) + 1;
|
||||
//console.log("set listener for", next + ':' + soul, batch[soul], cb.count);
|
||||
s3.on(next + ':' + soul).event(function(){
|
||||
cb.count -= 1;
|
||||
//console.log("transaction", cb.count);
|
||||
if(!cb.count){
|
||||
s3.on(ack).emit();
|
||||
this.off(); // MEMORY LEAKS EVERYWHERE!!!!!!!!!!!!!!!! FIX THIS!!!!!!!!!
|
||||
}
|
||||
});
|
||||
});
|
||||
if(gun.__.opt.batch < s3.batching){
|
||||
return s3.set.now();
|
||||
}
|
||||
if(!gun.__.opt.throttle){
|
||||
return s3.set.now();
|
||||
}
|
||||
s3.wait = s3.wait || setTimeout(s3.set.now, gun.__.opt.throttle * 1000); // in seconds
|
||||
}
|
||||
s3.set.now = s3.set.now || function(){
|
||||
clearTimeout(s3.wait);
|
||||
s3.batching = 0;
|
||||
s3.wait = null;
|
||||
var now = s3.next
|
||||
, batch = s3.batch[s3.next];
|
||||
s3.next = Gun.time.is();
|
||||
Gun.obj.map(batch, function put(exists, soul){
|
||||
var node = gun.__.graph[soul]; // the batch does not actually have the nodes, but what happens when we do cold data? Could this be gone?
|
||||
s3.put(s3.prefix + s3.prenode + soul, node, function(err, reply){
|
||||
console.log("s3 put reply", soul, err, reply);
|
||||
if(err || !reply){
|
||||
put(exists, soul); // naive implementation of retry TODO: BUG: need backoff and anti-infinite-loop!
|
||||
return;
|
||||
}
|
||||
s3.on(now + ':' + soul).emit(200);
|
||||
});
|
||||
});
|
||||
}
|
||||
s3.next = s3.next || Gun.time.is();
|
||||
s3.on = s3.on || Gun.on.create();
|
||||
s3.batching = s3.batching || 0;
|
||||
s3.batched = s3.batched || {};
|
||||
s3.batch = s3.batch || {};
|
||||
s3.persisted = s3.persisted || {};
|
||||
s3.wait = s3.wait || null;
|
||||
|
||||
s3.key = s3.key || function(key, soul, cb){
|
||||
var meta = {};
|
||||
meta[Gun._.soul] = soul = Gun.text.is(soul)? soul : (soul||{})[Gun._.soul];
|
||||
if(!soul){
|
||||
return cb({err: "No soul!"});
|
||||
}
|
||||
s3.put(s3.prefix + s3.prekey + key, '', function(err, reply){ // key is 2 bytes??? Should be smaller. Wait HUH? What did I mean by this?
|
||||
console.log("s3 put reply", soul, err, reply);
|
||||
if(err || !reply){
|
||||
s3.key(key, soul, cb); // naive implementation of retry TODO: BUG: need backoff and anti-infinite-loop!
|
||||
return;
|
||||
}
|
||||
cb();
|
||||
}, {Metadata: meta});
|
||||
}
|
||||
|
||||
opt.hooks = opt.hooks || {};
|
||||
gun.opt({hooks: {
|
||||
load: opt.hooks.load || s3.load
|
||||
,set: opt.hooks.set || s3.set
|
||||
,key: opt.hooks.key || s3.key
|
||||
}}, true);
|
||||
});
|
||||
}());
|
7
lib/server.js
Normal file
@ -0,0 +1,7 @@
|
||||
;(function(){
|
||||
console.log("Hello wonderful person! :) I'm mark@gunDB.io, message me for help or with hatemail. I want to hear from you! <3");
|
||||
var Gun = require('../gun');
|
||||
require('./s3');
|
||||
require('./wsp');
|
||||
module.exports = Gun;
|
||||
}());
|
37
lib/ws.js
Normal file
@ -0,0 +1,37 @@
|
||||
var Gun = require('gun/gun')
|
||||
, url = require('url');
|
||||
module.exports = function(wss, server){
|
||||
wss.on('connection', function(ws){
|
||||
var req = {};
|
||||
ws.upgradeReq = ws.upgradeReq || {};
|
||||
req.url = url.parse(ws.upgradeReq.url||'');
|
||||
req.method = (ws.upgradeReq.method||'').toLowerCase();
|
||||
req.headers = ws.upgradeReq.headers || {};
|
||||
//console.log("wsReq", req);
|
||||
ws.on('message', function(msg){
|
||||
msg = Gun.obj.ify(msg);
|
||||
msg.url = msg.url || {};
|
||||
msg.url.pathname = (req.url.pathname||'') + (msg.url.pathname||'');
|
||||
Gun.obj.map(req.url, function(val, i){
|
||||
msg.url[i] = msg.url[i] || val; // reattach url
|
||||
});
|
||||
msg.method = msg.method || req.method;
|
||||
msg.headers = msg.headers || {};
|
||||
Gun.obj.map(req.headers, function(val, i){
|
||||
msg.headers[i] = msg.headers[i] || val; // reattach headers
|
||||
});
|
||||
server.call(ws, msg, function(reply){
|
||||
if(!ws || !ws.send){ return }
|
||||
reply = reply || {};
|
||||
reply.wsrid = msg.wsrid;
|
||||
ws.send(Gun.text.ify(reply));
|
||||
});
|
||||
});
|
||||
ws.off = function(m){
|
||||
console.log("ws.off", m);
|
||||
ws.send = null;
|
||||
}
|
||||
ws.on('close', ws.off);
|
||||
ws.on('error', ws.off);
|
||||
});
|
||||
}
|
153
lib/wsp.js
Normal file
@ -0,0 +1,153 @@
|
||||
;(function(wsp){
|
||||
var Gun = require('gun/gun')
|
||||
, formidable = require('formidable')
|
||||
, ws = require('ws').Server
|
||||
, http = require('./http')
|
||||
, url = require('url');
|
||||
Gun.on('opt').event(function(gun, opt){
|
||||
gun.__.opt.ws = opt.ws = gun.__.opt.ws || opt.ws || {};
|
||||
gun.attach = gun.attach || function(app){
|
||||
if(app.use){
|
||||
app.use(gun.server);
|
||||
}
|
||||
var listen = app.listen;
|
||||
app.listen = function(port){
|
||||
var server = listen.apply(app, arguments);
|
||||
gun.__.opt.ws.server = gun.__.opt.ws.server || opt.ws.server || server;
|
||||
gun.__.opt.ws.path = gun.__.opt.ws.path || opt.ws.path || '/gun';
|
||||
require('./ws')(gun.server.websocket = gun.server.websocket || new ws(gun.__.opt.ws), function(req, res){
|
||||
var ws = this;
|
||||
req.headers['gun-tid'] = ws.tid = ws.tid? ws.tid : req.headers['gun-tid'];
|
||||
ws.sub = ws.sub || gun.server.on('network').event(function(msg){
|
||||
if(!ws || !ws.send){ return this.off() }
|
||||
if(!msg || (msg.headers && msg.headers['gun-tid'] === ws.tid)){ return }
|
||||
delete msg.wsrid; // depreciate this!
|
||||
ws.send(Gun.text.ify(msg));
|
||||
});
|
||||
gun.__.opt.hooks.transport(req, res);
|
||||
});
|
||||
gun.__.opt.ws.port = port || opt.ws.port || gun.__.opt.ws.port || 80;
|
||||
return server;
|
||||
}
|
||||
return gun;
|
||||
}
|
||||
gun.server = gun.server || function(req, res, next){
|
||||
//console.log("\n\n GUN SERVER!", req);
|
||||
next = next || function(){};
|
||||
if(!req || !res){ return next() }
|
||||
if(!req.url){ return next() }
|
||||
if(!req.method){ return next() }
|
||||
var msg = {};
|
||||
msg.url = url.parse(req.url, true);
|
||||
if(!gun.server.regex.test(msg.url.pathname)){ return next() }
|
||||
if(msg.url.pathname.replace(gun.server.regex,'').slice(0,3).toLowerCase() === '.js'){
|
||||
res.writeHead(200, {'Content-Type': 'text/javascript'});
|
||||
res.end(gun.server.js = gun.server.js || require('fs').readFileSync(__dirname + '/../gun.js')); // gun server is caching the gun library for the client
|
||||
return;
|
||||
}
|
||||
http(req, res, function(req, res){
|
||||
if(!req){ return next() }
|
||||
var tab, cb = res = require('./jsonp')(req, res);
|
||||
if(req.headers && (tab = req.headers['gun-tid'])){
|
||||
tab = (gun.server.peers = gun.server.peers || {})[tab] = gun.server.peers[tab] || {tid: tab};
|
||||
tab.sub = tab.sub || gun.server.on('network').event(function(req){
|
||||
if(!tab){ return this.off() } // self cleans up after itself!
|
||||
if(!req || (req.headers && req.headers['gun-tid'] === tab.tid)){ return }
|
||||
(tab.queue = tab.queue || []).push(req);
|
||||
tab.drain(tab.reply);
|
||||
});
|
||||
cb = function(r){ (r.headers||{}).poll = gun.__.opt.poll; res(r) }
|
||||
tab.drain = tab.drain || function(res){
|
||||
if(!res || !tab || !tab.queue || !tab.queue.length){ return }
|
||||
res({headers: {'gun-tid': tab.tid}, body: tab.queue });
|
||||
tab.off = setTimeout(function(){ tab = null }, gun.__.opt.pull);
|
||||
tab.reply = tab.queue = null;
|
||||
return true;
|
||||
}
|
||||
clearTimeout(tab.off);
|
||||
if(req.headers.pull){
|
||||
if(tab.drain(cb)){ return }
|
||||
return tab.reply = cb;
|
||||
}
|
||||
}
|
||||
gun.__.opt.hooks.transport(req, cb);
|
||||
});
|
||||
}
|
||||
gun.server.on = gun.server.on || Gun.on.create();
|
||||
gun.__.opt.poll = gun.__.opt.poll || opt.poll || 1;
|
||||
gun.__.opt.pull = gun.__.opt.pull || opt.pull || gun.__.opt.poll * 1000;
|
||||
gun.server.regex = gun.__.opt.route = gun.__.opt.route || opt.route || /^\/gun/i;
|
||||
if((gun.__.opt.maxSockets = opt.maxSockets || gun.__.opt.maxSockets) !== false){
|
||||
require('https').globalAgent.maxSockets = require('http').globalAgent.maxSockets = gun.__.opt.maxSockets || Infinity; // WARNING: Document this!
|
||||
}
|
||||
/* gun.server.xff = function(r){
|
||||
if(!r){ return '' }
|
||||
var req = {headers: r.headers || {}, connection: r.connection || {}, socket: r.socket || {}};
|
||||
return req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || (req.connection.socket || {}).remoteAddress || '';
|
||||
} */
|
||||
gun.server.transport = gun.server.transport || (function(){
|
||||
// all streams, technically PATCH but implemented as POST, are forwarded to other trusted peers
|
||||
// except for the ones that are listed in the message as having already been sending to.
|
||||
// all states, implemented with GET, are replied to the source that asked for it.
|
||||
function tran(req, cb){
|
||||
//console.log("gun.server", req);
|
||||
req.method = req.body? 'post' : 'get'; // post or get is based on whether there is a body or not
|
||||
req.url.key = req.url.pathname.replace(gun.server.regex,'').replace(/^\//i,'') || '';
|
||||
if('get' == req.method){ return tran.load(req, cb) }
|
||||
if('post' == req.method){ return tran.post(req, cb) }
|
||||
cb({body: {hello: 'world'}});
|
||||
}
|
||||
tran.load = function(req, cb){
|
||||
var key = req.url.key
|
||||
, reply = {headers: {'Content-Type': tran.json}};
|
||||
if(!key){
|
||||
if(!Gun.obj.has(req.url.query, Gun._.soul)){
|
||||
return cb({headers: reply.headers, body: {err: "No key or soul to load."}});
|
||||
}
|
||||
key = {};
|
||||
key[Gun._.soul] = req.url.query[Gun._.soul];
|
||||
}
|
||||
gun.load(key, function(err, node){
|
||||
//tran.sub.scribe(req.tab, node._[Gun._.soul]);
|
||||
cb({headers: reply.headers, body: (err? (err.err? err : {err: err || "Unknown error."}) : node || null)});
|
||||
});
|
||||
}
|
||||
tran.post = function(req, cb){
|
||||
// NOTE: It is highly recommended you do your own POSTs through your own API that then saves to gun manually.
|
||||
// This will give you much more fine-grain control over security, transactions, and what not.
|
||||
var reply = {headers: {'Content-Type': tran.json}};
|
||||
if(!req.body){ return cb({headers: reply.headers, body: {err: "No body"}}) }
|
||||
if(req.url.key && Gun.obj.has(req.body, Gun._.soul)){ // key hook!
|
||||
console.log("TODO: BUG! IMPLEMENT KEY TRANSPORT HOOK!");
|
||||
return;
|
||||
}
|
||||
// saving
|
||||
Gun.obj.map(req.body, function(node, soul){
|
||||
if(soul != Gun.is.soul.on(node)){ return this.end("No soul!") }
|
||||
gun.load(node._, this.add(soul));
|
||||
}, Gun.fns.sum(function(err){
|
||||
if(err){ return cb({headers: reply.headers, body: {err: err}}) }
|
||||
gun.union(req.body, function(err, context){
|
||||
if(err || context.err || !context.nodes){ return cb({headers: reply.headers, body: {err: err || context.err || "Union failed." }}) }
|
||||
if(!Gun.fns.is(gun.__.opt.hooks.set)){ return cb({headers: reply.headers, body: {err: "Persistence not supported." }}) }
|
||||
gun.__.opt.hooks.set(context.nodes, function(err, data){ // since we've already manually done the union, we can now directly call the persistence layer.
|
||||
if(err){ return cb({headers: reply.headers, body: {err: err || "Persistence failed." }}) }
|
||||
cb({headers: reply.headers, body: {ok: "Persisted."}});
|
||||
});
|
||||
});
|
||||
}));
|
||||
gun.server.on('network').emit(req);
|
||||
}
|
||||
gun.server.on('network').event(function(req){
|
||||
// TODO: MARK! You should move the networking events to here, not in WSS only.
|
||||
});
|
||||
tran.json = 'application/json';
|
||||
return tran;
|
||||
}());
|
||||
|
||||
opt.hooks = opt.hooks || {};
|
||||
gun.opt({hooks: {
|
||||
transport: opt.hooks.transport || gun.server.transport
|
||||
}}, true);
|
||||
});
|
||||
}({}));
|
@ -1,7 +1,5 @@
|
||||
;(function(){
|
||||
console.log("Hello wonderful person! :) I'm mark@gunDB.io, message me for help or with hatemail. I want to hear from you! <3");
|
||||
var Gun = require(__dirname+'/gun')
|
||||
, S3 = require(__dirname+'/gate/s3') // redis has been removed, can be replaced with a disk system
|
||||
var Gun = require('gun/gun')
|
||||
, formidable = require('formidable')
|
||||
, url = require('url')
|
||||
, meta = {};
|
||||
@ -61,108 +59,8 @@
|
||||
form.parse(req);
|
||||
}
|
||||
gun.server.regex = /^\/gun/i;
|
||||
opt.s3 = opt.s3 || {};
|
||||
var s3 = gun.__.opt.s3 = gun.__.opt.s3 || S3(opt && opt.s3);
|
||||
s3.prefix = s3.prefix || opt.s3.prefix || '';
|
||||
s3.prekey = s3.prekey || opt.s3.prekey || '';
|
||||
s3.prenode = s3.prenode || opt.s3.prenode || '_/nodes/';
|
||||
gun.__.opt.batch = opt.batch || gun.__.opt.batch || 10;
|
||||
gun.__.opt.throttle = opt.throttle || gun.__.opt.throttle || 15;
|
||||
gun.__.opt.disconnect = opt.disconnect || gun.__.opt.disconnect || 5;
|
||||
if(!gun.__.opt.keepMaxSockets){ require('https').globalAgent.maxSockets = require('http').globalAgent.maxSockets = Infinity } // WARNING: Document this!
|
||||
|
||||
s3.load = s3.load || function(key, cb, opt){
|
||||
if(!key){ return }
|
||||
cb = cb || function(){};
|
||||
opt = opt || {};
|
||||
if(key[Gun._.soul]){
|
||||
key = s3.prefix + s3.prenode + key[Gun._.soul];
|
||||
} else {
|
||||
key = s3.prefix + s3.prekey + key;
|
||||
}
|
||||
s3.get(key, function(err, data, text, meta){
|
||||
console.log('via s3', key, err);
|
||||
if(meta && meta[Gun._.soul]){
|
||||
return s3.load(meta, cb);
|
||||
}
|
||||
if(err && err.statusCode == 404){
|
||||
err = null; // we want a difference between 'unfound' (data is null) and 'error' (auth is wrong).
|
||||
}
|
||||
cb(err, data);
|
||||
});
|
||||
}
|
||||
s3.set = s3.set || function(nodes, cb){
|
||||
s3.batching += 1;
|
||||
cb = cb || function(){};
|
||||
cb.count = 0;
|
||||
var next = s3.next
|
||||
, ack = Gun.text.random(8)
|
||||
, batch = s3.batch[next] = s3.batch[next] || {};
|
||||
s3.on(ack).once(cb);
|
||||
Gun.obj.map(nodes, function(node, soul){
|
||||
cb.count += 1;
|
||||
batch[soul] = (batch[soul] || 0) + 1;
|
||||
//console.log("set listener for", next + ':' + soul, batch[soul], cb.count);
|
||||
s3.on(next + ':' + soul).event(function(){
|
||||
cb.count -= 1;
|
||||
//console.log("transaction", cb.count);
|
||||
if(!cb.count){
|
||||
s3.on(ack).emit();
|
||||
this.off(); // MEMORY LEAKS EVERYWHERE!!!!!!!!!!!!!!!! FIX THIS!!!!!!!!!
|
||||
}
|
||||
});
|
||||
});
|
||||
if(gun.__.opt.batch < s3.batching){
|
||||
return s3.set.now();
|
||||
}
|
||||
if(!gun.__.opt.throttle){
|
||||
return s3.set.now();
|
||||
}
|
||||
s3.wait = s3.wait || setTimeout(s3.set.now, gun.__.opt.throttle * 1000); // in seconds
|
||||
}
|
||||
s3.set.now = s3.set.now || function(){
|
||||
clearTimeout(s3.wait);
|
||||
s3.batching = 0;
|
||||
s3.wait = null;
|
||||
var now = s3.next
|
||||
, batch = s3.batch[s3.next];
|
||||
s3.next = Gun.time.is();
|
||||
Gun.obj.map(batch, function put(exists, soul){
|
||||
var node = gun.__.graph[soul]; // the batch does not actually have the nodes, but what happens when we do cold data? Could this be gone?
|
||||
s3.put(s3.prefix + s3.prenode + soul, node, function(err, reply){
|
||||
console.log("s3 put reply", soul, err, reply);
|
||||
if(err || !reply){
|
||||
put(exists, soul); // naive implementation of retry TODO: BUG: need backoff and anti-infinite-loop!
|
||||
return;
|
||||
}
|
||||
s3.on(now + ':' + soul).emit(200);
|
||||
});
|
||||
});
|
||||
}
|
||||
s3.next = s3.next || Gun.time.is();
|
||||
s3.on = s3.on || Gun.on.create();
|
||||
s3.batching = s3.batching || 0;
|
||||
s3.batched = s3.batched || {};
|
||||
s3.batch = s3.batch || {};
|
||||
s3.persisted = s3.persisted || {};
|
||||
s3.wait = s3.wait || null;
|
||||
|
||||
s3.key = s3.key || function(key, soul, cb){
|
||||
var meta = {};
|
||||
meta[Gun._.soul] = soul = Gun.text.is(soul)? soul : (soul||{})[Gun._.soul];
|
||||
if(!soul){
|
||||
return cb({err: "No soul!"});
|
||||
}
|
||||
s3.put(s3.prefix + s3.prekey + key, '', function(err, reply){ // key is 2 bytes??? Should be smaller
|
||||
console.log("s3 put reply", soul, err, reply);
|
||||
if(err || !reply){
|
||||
s3.key(key, soul, cb); // naive implementation of retry TODO: BUG: need backoff and anti-infinite-loop!
|
||||
return;
|
||||
}
|
||||
cb();
|
||||
}, {Metadata: meta});
|
||||
}
|
||||
|
||||
gun.server.transport = (function(){
|
||||
function tran(req, cb){
|
||||
//console.log(req);
|
||||
@ -204,6 +102,23 @@
|
||||
}
|
||||
tran.post = function(req, cb){ // post is used as patch, sad that patch has such poor support
|
||||
if(!req.body){ return cb({body: {err: "No body"}}) }
|
||||
if(req.url.key && Gun.obj.has(req.body, Gun._.soul)){ // key hook!
|
||||
req.tab = tran.sub.s[req.sub] || {};
|
||||
req.tab.sub = req.sub;
|
||||
console.log("key.hook", req.tab);
|
||||
tran.sub.scribe(req.tab, req.body[Gun._.soul]);
|
||||
return gun.load(req.body).get(function(frozen){
|
||||
// NEED to allow a security callback so server can tamper with this!
|
||||
this.key(req.url.key, function(err, reply){
|
||||
reply = reply || {};
|
||||
if(err){ reply.err = err }
|
||||
reply = {body: reply};
|
||||
reply.headers = {'Content-Type': tran.json};
|
||||
reply.headers['Gun-Sub'] = req.tab.sub;
|
||||
cb(reply);
|
||||
});
|
||||
}); // do I need to handle the blank case? :/ Not sure.
|
||||
}
|
||||
// raw test for now, no auth:
|
||||
// should probably load all the nodes first? YES.
|
||||
var context = gun.union(req.body, function(err, context){ // data safely transformed
|
||||
@ -327,6 +242,7 @@
|
||||
tran.sub.scribe = function(tab, soul){
|
||||
tran.sub.s[tab.sub] = tab;
|
||||
tab.subs = tab.subs || {};
|
||||
console.log("meow subscribes", soul);
|
||||
tab.subs[soul] = tab.subs[soul] || tran.push(soul).event(function(req){
|
||||
if(!req){ return }
|
||||
if(!tab){ return this.off() } // resolve any dangling callbacks
|
||||
@ -407,10 +323,7 @@
|
||||
|
||||
opt.hooks = opt.hooks || {};
|
||||
gun.opt({hooks: {
|
||||
load: opt.hooks.load || s3.load
|
||||
,set: opt.hooks.set || s3.set
|
||||
,key: opt.hooks.key || s3.key
|
||||
,transport: opt.hooks.transport || gun.server.transport
|
||||
transport: opt.hooks.transport || gun.server.transport
|
||||
}}, true);
|
||||
});
|
||||
meta.json = 'application/json';
|
||||
@ -438,5 +351,4 @@
|
||||
return true;
|
||||
}
|
||||
};
|
||||
module.exports = Gun;
|
||||
}());
|
16
manifest.yml
@ -1,16 +0,0 @@
|
||||
---
|
||||
applications:
|
||||
".":
|
||||
name: gunjs
|
||||
framework:
|
||||
name: standalone
|
||||
info:
|
||||
mem: 64M
|
||||
description: Standalone Application
|
||||
exec:
|
||||
runtime: node10
|
||||
command: node init.js
|
||||
infra: aws
|
||||
url: http://gunjs.aws.af.cm
|
||||
mem: 64M
|
||||
instances: 1
|
46
on.js
@ -1,46 +0,0 @@
|
||||
;(function(){
|
||||
var setImmediate = setImmediate || function(cb){setTimeout(cb,0)}
|
||||
function On(){
|
||||
var chain = new Chain();
|
||||
return chain.$ = function(where){
|
||||
chain.$[where] = function(fn){
|
||||
chain.$[where] = fn;
|
||||
}
|
||||
chain.where = where;
|
||||
return chain;
|
||||
}
|
||||
}
|
||||
On.is = function(On){ return (On instanceof On)? true : false }
|
||||
function Chain(){
|
||||
if(!(this instanceof Chain)){
|
||||
return new Chain();
|
||||
}
|
||||
}
|
||||
Chain.chain = Chain.prototype;
|
||||
Chain.chain.emit = function(a,s,d,f){
|
||||
var me = this
|
||||
, where = me.where
|
||||
, args = Array.prototype.slice.call(arguments);
|
||||
setImmediate(function(){
|
||||
if(!me || !me.$ || !me.$[where]){ return }
|
||||
me.$[where].apply(me, args);
|
||||
});
|
||||
return me;
|
||||
}
|
||||
if(typeof window !== "undefined"){
|
||||
window.On = On;
|
||||
} else {
|
||||
module.exports = On;
|
||||
}
|
||||
|
||||
;(function(){ // test
|
||||
var doSomething = function(){
|
||||
var cb = On();
|
||||
cb('now').emit(1,2,3);
|
||||
return cb;
|
||||
}
|
||||
doSomething('foo', 'bar').now(function(a,b,c){
|
||||
console.log("Oh yeah baby", a,b,c);
|
||||
})
|
||||
}());
|
||||
}());
|
@ -1,5 +1,5 @@
|
||||
{ "name": "gun"
|
||||
, "version": "0.0.8"
|
||||
, "version": "0.0.9"
|
||||
, "author": "Mark Nadal"
|
||||
, "description": "Graph engine."
|
||||
, "engines": {
|
||||
@ -9,6 +9,7 @@
|
||||
"mime": "~>1.2.11",
|
||||
"aws-sdk": "~>2.0.0",
|
||||
"formidable": "~>1.0.15",
|
||||
"ws": "~>0.4.32",
|
||||
"request": "~>2.39.0"
|
||||
}
|
||||
, "devDependencies": {
|
||||
|
148
shot0.js
@ -1,148 +0,0 @@
|
||||
module.exports = require('theory')
|
||||
('shot',function(a){
|
||||
return function(opt){
|
||||
opt = opt || {};
|
||||
opt.path = opt.path || '.'
|
||||
opt.batch = opt.batch || 0;
|
||||
opt.throttle = opt.throttle || 0;
|
||||
opt.src = opt.src || (this && this.com) || '';
|
||||
opt.cache = a.num.is(opt.cache)? opt.cache : opt.cache || 1;
|
||||
if(root.node){ return require(opt.path+'/shots0')(opt); }
|
||||
var u, shot = {},
|
||||
store = window.amplify && window.amplify.store? amplify.store
|
||||
: function(src, data){
|
||||
if(data === u){ return store[src] }
|
||||
return store[src] = data;
|
||||
}
|
||||
store.batch = [];
|
||||
store.last = a.time.now();
|
||||
store.list = function(){
|
||||
var g = store(a.gun.event) || {}
|
||||
, z = function(l,g,i){
|
||||
if(i !== 0 && !i){ return }
|
||||
if(!l || !l[i]){ return }
|
||||
shot.fire(l[i], 1);
|
||||
console.log("re-sent", l[i]);
|
||||
a.time.wait(function(){ z(l,g,i+1) },1);
|
||||
}
|
||||
a.obj(g).each(function(l,g){
|
||||
z(l,g,0);
|
||||
});
|
||||
}
|
||||
store.sort = function(A,B){
|
||||
if(!A || !B){ return 0 }
|
||||
A = ((A||{})._||{})[a.gun._.ham]; B = ((B||{})._||{})[a.gun._.ham];
|
||||
if(A < B){ return -1 }
|
||||
else if(A > B){ return 1 }
|
||||
else { return 0 }
|
||||
}
|
||||
store.add = function(m, g, b){
|
||||
if(!m){ return }
|
||||
g = '_' + (a(g,'at') || g || a(m,'where.at') || m.where);
|
||||
var gs = store(a.gun.event) || {}
|
||||
, when = shot.when(m);
|
||||
gs[g] = gs[g] || [];
|
||||
if(a.list(gs[g]).each(function(v){
|
||||
var w = shot.when(v);
|
||||
if(w === when){
|
||||
return true;
|
||||
}
|
||||
})){ return 2; } // already
|
||||
if(opt.batch && a.list.is(b)){ b.push(m) }
|
||||
gs[g].push(m);
|
||||
store(a.gun.event, gs);
|
||||
return gs[g];
|
||||
}
|
||||
store.del = function(m, g){
|
||||
if(!m){ return }
|
||||
var gs = store(a.gun.event) || {}
|
||||
, when = shot.when(m);
|
||||
g = '_'+(m.where.at || m.where || g);
|
||||
console.log("clear queue", g, m);
|
||||
gs[g] = gs[g] || [];
|
||||
gs[g] = a.list(gs[g]).each(function(v,i,t){
|
||||
var w = shot.when(v);
|
||||
if(w === when){
|
||||
return;
|
||||
}
|
||||
t(v);
|
||||
});
|
||||
store(a.gun.event, gs);
|
||||
}
|
||||
store.set = function(key, val){
|
||||
var s = store(a.gun.event) || {};
|
||||
s[key] = val;
|
||||
store(a.gun.event, s);
|
||||
}
|
||||
store.get = function(key, cb){
|
||||
var s = store(a.gun.event) || {};
|
||||
s = s[key];
|
||||
if(cb){
|
||||
return cb(null, s);
|
||||
}
|
||||
return s;
|
||||
};
|
||||
a.gun.shots(shot.fire = function(m, r){
|
||||
if(!m || !m.where){ return }
|
||||
if(!r){
|
||||
if(store.add(m, m.where, store.batch) === 2){
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(opt.src && opt.src.send){
|
||||
m = opt.src.meta(m);
|
||||
if(!m.what || !m.where || !m.when){ return }
|
||||
console.log("to server!", m);
|
||||
return opt.src.send(m);
|
||||
}
|
||||
return; // below should be a fallback. TODO: Unfinished!
|
||||
});
|
||||
shot.when = function(m){ return a(m,'what._.'+a.gun._.ham) || a(m,'_.'+a.gun._.ham) || m.when }
|
||||
shot.load = function(where,cb,o){
|
||||
if(!where){ return }
|
||||
o = o || {};
|
||||
var m = {what: where, how: {gun:3}}
|
||||
, g = a.gun.magazine[where] || store.get(where);
|
||||
g = a.fns.is(g)? g : a.obj.is(g)? a.gun(where, g) : null;
|
||||
if(g){
|
||||
//cb(g);
|
||||
}
|
||||
//console.log("!!! ASK !!!");
|
||||
if(opt.src && opt.src.ask){
|
||||
opt.src.ask(m,function(m){
|
||||
if(g){
|
||||
//console.log("!!! double load !!!");
|
||||
//return; // prevent load from calling twice! Add sync comparison.
|
||||
}
|
||||
if(!m || !m.what){ cb(null) }
|
||||
if(o.cache !== 0){
|
||||
if(o.cache || opt.cache){ // make options more configurable.
|
||||
store.set(where, m.what);
|
||||
}
|
||||
}
|
||||
m = a.gun(where, m.what);
|
||||
cb(m);
|
||||
});
|
||||
}
|
||||
}
|
||||
shot.spray = function(filter){
|
||||
if(filter && filter.how){
|
||||
shot.spray.action(filter);
|
||||
return shot;
|
||||
}
|
||||
if(a.fns.is(filter)){
|
||||
shot.spray.action = filter;
|
||||
return shot;
|
||||
}
|
||||
return shot.spray.action;
|
||||
}
|
||||
shot.spray.action = function(m){
|
||||
if(!m || !m.how || !m.how.gun){ return }
|
||||
if(m.how.gun === -1){
|
||||
store.del(m);
|
||||
}
|
||||
}
|
||||
store.list();
|
||||
return shot;
|
||||
}
|
||||
},['./gun0'])
|
305
shots0.js
@ -1,305 +0,0 @@
|
||||
module.exports = require('theory')
|
||||
('shot',function(a){
|
||||
var s3 = require(__dirname+'/gate/s3')
|
||||
, store = require(__dirname+'/gate/redis');
|
||||
function shot(opt){
|
||||
opt = opt || {};
|
||||
var u, shot = {};
|
||||
opt.path = opt.path || '.'
|
||||
opt.batch = opt.batch || 10;
|
||||
opt.throttle = opt.throttle || 15;
|
||||
opt.src = opt.src || (this && this.com) || '';
|
||||
opt.redis = opt.redis || {};
|
||||
opt.redis.max = a.num.is(opt.redis.max)? opt.redis.max : .8;
|
||||
opt.redis.Max = Math.floor(require('os').totalmem() * opt.redis.max);
|
||||
opt.redis.append = a.obj(opt.redis).has('append')? opt.redis.append : true;
|
||||
opt.redis.expire = opt.redis.expire || 60*15;
|
||||
opt.redis.config = function(){
|
||||
if(opt.redis.config.done === 0){ return }
|
||||
opt.redis.config.done = 3;
|
||||
var reply = function(e,r){
|
||||
if(e){ return }
|
||||
opt.redis.config.done -= 1;
|
||||
};
|
||||
if(opt.redis.max){
|
||||
store.client.config('set','maxmemory',opt.redis.Max, reply);
|
||||
store.client.config('set','maxmemory-policy','allkeys-lru', reply);
|
||||
}
|
||||
if(opt.redis.append){
|
||||
store.client.config('set','appendonly','yes', reply);
|
||||
}
|
||||
}
|
||||
opt.s3 = opt.s3 || {};
|
||||
opt.s3.Bucket = a.text.is(opt.s3.bucket)? opt.s3.bucket : (process.env.s3Bucket || '');
|
||||
opt.s3.bucket = a.fns.is(opt.s3.bucket)? opt.s3.bucket : function(key){
|
||||
return opt.s3.Bucket || a.text(key).clip('/',0,1);
|
||||
}
|
||||
opt.s3.key = a.fns.is(opt.s3.key)? opt.s3.key : function(key){
|
||||
if(key.slice(0, opt.s3.Bucket.length) === opt.s3.Bucket){
|
||||
key = key.slice(opt.s3.Bucket.length)||'';
|
||||
if(key.charAt(0) === '/'){
|
||||
key = key.slice(1);
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
store.batch = [];
|
||||
store.last = a.time.now();
|
||||
store.push = function(key, score, val, cb){
|
||||
if(!val){ return }
|
||||
store.client.zadd(key, score, val, function(e,r){
|
||||
if(e){
|
||||
store.clienf.zadd(key, score, val, cb);
|
||||
return;
|
||||
}
|
||||
if(cb){ cb(e,r) }
|
||||
});
|
||||
}
|
||||
store.when = function(m){ return a(m,'what._.'+a.gun._.ham) || a(m,'_.'+a.gun._.ham) || m.when }
|
||||
store.where = function(m){ return a.text.is(m)? m : a.text.is(m.where)? m.where : m.where.at }
|
||||
store.add = function(m, g){
|
||||
if(!m){ return }
|
||||
g = '_' + (g || a(m,'where.at') || m.where);
|
||||
store.push(g, store.when(m) || 0, a.text.ify(m));
|
||||
}
|
||||
store.del = function(m, g){
|
||||
|
||||
}
|
||||
store.sort = function(A,B){
|
||||
if(!A || !B){ return 0 }
|
||||
A = A.w; B = B.w;
|
||||
if(A < B){ return -1 }
|
||||
else if(A > B){ return 1 }
|
||||
else { return 0 }
|
||||
}
|
||||
store.batching = 0;
|
||||
store.batched = {};
|
||||
store.batch = {};
|
||||
store.persisted = {};
|
||||
store.wait = null;
|
||||
store.stay = function(key, val, cb){
|
||||
store.batching += 1;
|
||||
store.batch[key] = val;
|
||||
(store.batched[key] = store.batched[key]||[]).push(cb);
|
||||
if(opt.batch < store.batching){
|
||||
return store.stay.now();
|
||||
}
|
||||
if(!opt.throttle){
|
||||
return store.stay.now();
|
||||
}
|
||||
store.wait = store.wait || a.time.wait(store.stay.now, opt.throttle * 1000); // to seconds
|
||||
}
|
||||
store.stay.now = function(){
|
||||
store.batching = 0;
|
||||
a.time.stop(store.wait);
|
||||
store.wait = null;
|
||||
a.obj(store.batch).each(function(g,where){
|
||||
if(!g || !where){ return }
|
||||
//console.log('*************** save', where, '*******************');
|
||||
store.stay.put(where,g,function(e,r){
|
||||
a.list(store.batched[where]).each(function(cb){
|
||||
if(a.fns.is(cb)){ cb(e,r) }
|
||||
console.log('*** saved ***');
|
||||
});
|
||||
console.log(store.batched[where]);
|
||||
delete store.batched[where];
|
||||
});
|
||||
});
|
||||
}
|
||||
store.stay.put = function(where,obj,cb){
|
||||
s3(opt.s3.bucket(where)).put(opt.s3.key(where),obj,function(e,r){
|
||||
if(!e){ store.persisted[where] = 's3' }
|
||||
if(a.fns.is(cb)){ cb(e,r) }
|
||||
});
|
||||
}
|
||||
store.set = function(key, value, cb, fn){
|
||||
opt.redis.config();
|
||||
var val = a.text.is(value)? value : a.text.ify(value);
|
||||
if(a.fns.is(fn)){ store.stay(key, value, fn) }
|
||||
//console.log("potential setex:", key, opt.redis.expire, val);
|
||||
if(opt.redis.max){
|
||||
store.client.set(key, val, function(e,r){
|
||||
if(e){
|
||||
store.clienf.setex(key, opt.redis.expire, val, cb);
|
||||
return;
|
||||
}
|
||||
if(cb){ cb(e,r) }
|
||||
});
|
||||
} else {
|
||||
store.client.setex(key, opt.redis.expire, val, function(e,r){
|
||||
if(e){
|
||||
store.clienf.setex(key, opt.redis.expire, val, cb);
|
||||
return;
|
||||
}
|
||||
if(cb){ cb(e,r) }
|
||||
});
|
||||
}
|
||||
}
|
||||
store.get = function(key, cb){
|
||||
store.clienf.get(key, function(e,r){
|
||||
if(e || !r){ return store.client.get(key, cb) }
|
||||
if(cb){ cb(e,r) }
|
||||
});
|
||||
}
|
||||
shot.load = function(where,cb,o){
|
||||
//console.log("shot.load >", where);
|
||||
if(!where){ return }
|
||||
where = store.where(where);
|
||||
if(!a.text.is(where)){ return }
|
||||
if(a.fns.is(a.gun.magazine[where])){
|
||||
console.log('via memory', where);
|
||||
cb(a.gun.magazine[where], null); // TODO: Need to clear queue these at some point, too!
|
||||
return;
|
||||
}
|
||||
if(opt.src && opt.src.send){
|
||||
//console.log("Getting and subscribe");
|
||||
opt.src.send({where:{on: where}, how: {gun: 2}});
|
||||
}
|
||||
store.get(where, function(e,r){
|
||||
if(e || !r){
|
||||
return s3(opt.s3.bucket(where)).get(opt.s3.key(where),function(e,r,t){
|
||||
console.log('via s3', where); if(e){ console.log(e) }
|
||||
if(e || !r){ return cb(null, e) }
|
||||
store.persisted[where] = 's3';
|
||||
store.set(where, (t || a.text.ify(r)));
|
||||
r = shot.load.action(where,r); //a.gun(where,r);
|
||||
cb(r, e);
|
||||
},o);
|
||||
}
|
||||
console.log('via redis', where);
|
||||
r = a.obj.ify(r);
|
||||
r = shot.load.action(where,r); //a.gun(where,r);
|
||||
cb(r,e);
|
||||
});
|
||||
}
|
||||
shot.load.action = function(w,o){
|
||||
if(!w || !o){ return }
|
||||
return a.gun(w,o);
|
||||
}
|
||||
shot.spray = function(m){
|
||||
if(m && m.how){
|
||||
shot.spray.action(m);
|
||||
return shot;
|
||||
}
|
||||
if(a.fns.is(m)){
|
||||
shot.spray.transform = m;
|
||||
return shot.spray.action;
|
||||
}
|
||||
return shot.spray.action;
|
||||
}
|
||||
shot.spray.transform = function(g,m,d){if(d){d()}}
|
||||
shot.spray.action = function(m){
|
||||
console.log("gun spray ---->", m, (opt.src && opt.src.way? opt.src.way : null));
|
||||
if(!m || !m.how){ return }
|
||||
var where = store.where(m);
|
||||
if(m.how.gun === -2){
|
||||
console.log("gun data from others", m);
|
||||
if(m && m.what && m.what.session){ console.log(m.what.session) }
|
||||
return;
|
||||
}
|
||||
if(m.how.gun === 2){
|
||||
if(!a.fns.is(a.gun.magazine[where])){
|
||||
return;
|
||||
}
|
||||
if(opt.src && opt.src.send){
|
||||
console.log("gun subscribe sync", m);
|
||||
opt.src.send({what: a.gun.magazine[where](), where: where, how: {gun: -(m.how.gun||2)}});
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(m.how.gun === 3){
|
||||
shot.load(m.what, function(g,e){
|
||||
shot.pump.action(g, m, function(){ // receive custom edited copy here and send it down instead.
|
||||
if(!opt.src || !opt.src.reply){ return }
|
||||
m.what = a.fns.is(g)? g() : {};
|
||||
m.how.gun = -(m.how.gun||3);
|
||||
opt.src.reply(m);
|
||||
}, e);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if(!where){ return }
|
||||
store.add(m);
|
||||
var n = a.obj.copy(m);
|
||||
shot.load(where, function(g,e){
|
||||
var done = function(){
|
||||
var u, s, w = store.when(m) || 0, r = {}, cb;
|
||||
m.how.gun = -(m.how.gun||1);
|
||||
g = a.fns.is(g)? g : (a.gun.magazine[where] || function(){});
|
||||
a.obj(m.what).each(function(v,p){
|
||||
if(g(p,v,w) === u){
|
||||
r[p] = 0; // Error code
|
||||
return;
|
||||
} s = true;
|
||||
});
|
||||
m.what = r;
|
||||
cb = function(){
|
||||
if(!opt.src || !opt.src.reply || m.where.mid){ return }
|
||||
opt.src.reply(m);
|
||||
console.log('reply', m);
|
||||
}
|
||||
if(!s){ return cb() }
|
||||
store.set(where, g(), null, cb);
|
||||
};
|
||||
done.end = function(){};
|
||||
shot.spray.transform(g, m, done, e);
|
||||
});
|
||||
if(n.where && !n.where.mid && opt.src.send){
|
||||
n.who = {};
|
||||
opt.src.send(n);
|
||||
}
|
||||
}
|
||||
if(opt.src && opt.src.on){
|
||||
opt.src.on(shot.spray.action);
|
||||
}
|
||||
shot.pump = function(fn){
|
||||
shot.pump.action = fn || shot.pump.action;
|
||||
return shot;
|
||||
}
|
||||
shot.pump.action = function(g,m,d){if(d){d()}}
|
||||
shot.server = function(req,res){
|
||||
console.log('shot server', req);
|
||||
if(!req || !res){ return }
|
||||
var b = shot.server.get(req);
|
||||
if(!b || !b.b){ return }
|
||||
b = a.obj.ify((b||{}).b);
|
||||
if(a.obj.is(b)){ b = [b] }
|
||||
if(!a.list.is(b)){ return }
|
||||
//console.log('gun >>>>>>');
|
||||
a.list(b).each(function(v,i){
|
||||
//console.log(v);
|
||||
});
|
||||
//console.log('<<<<<< gun');
|
||||
if(req.how && req.when && req.who && a.fns.is(res)){
|
||||
req.what.body = {ok:1};
|
||||
res(req);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
shot.server.get = function(m){
|
||||
return !a.obj.empty(a(m,'what.form'))? a(m,'what.form')
|
||||
: !a.obj.empty(a(m,'what.url.query'))? a(m,'what.url.query')
|
||||
: false ;
|
||||
};
|
||||
a.gun.shots(function(m){
|
||||
var w;
|
||||
if(!store.persisted[w = store.where(m)]){
|
||||
if(opt.src && opt.src.send){
|
||||
//console.log("made and subscribed", m);
|
||||
opt.src.send({where:{on: w}, how: {gun: 2}})
|
||||
}
|
||||
store.stay.put(w, m.what, function(e,r){
|
||||
//console.log("---> gun shots", m, "new graph saved!");
|
||||
});
|
||||
return;
|
||||
}
|
||||
if(opt.src && opt.src.send){
|
||||
opt.src.send(m);
|
||||
}
|
||||
});
|
||||
shot.gun = a.gun;
|
||||
return shot;
|
||||
}
|
||||
shot.gun = a.gun;
|
||||
return shot;
|
||||
},[__dirname+'/gun0'])
|
108
test/common.js
@ -147,6 +147,114 @@ describe('Gun', function(){
|
||||
expect(Gun.obj.map({a:'z',b:3,c:'x'},function(v,i,t){ if(v===3){ return 0 }})).to.be(0);
|
||||
});
|
||||
});
|
||||
describe('Functions', function(){
|
||||
it('sum',function(done){
|
||||
var obj = {a:2, b:2, c:3, d: 9};
|
||||
Gun.obj.map(obj, function(num, key){
|
||||
setTimeout(this.add(function(){
|
||||
this.sum(null, num * num);
|
||||
}, key), parseInt((""+Math.random()).substring(2,5)));
|
||||
}, Gun.fns.sum(function(err, val){
|
||||
expect(val.a).to.eql(4);
|
||||
expect(val.b).to.eql(4);
|
||||
expect(val.c).to.eql(9);
|
||||
expect(val.d).to.eql(81);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Gun Safety', function(){
|
||||
var gun = Gun();
|
||||
it('is',function(){
|
||||
expect(Gun.is(gun)).to.be(true);
|
||||
expect(Gun.is(true)).to.be(false);
|
||||
expect(Gun.is(false)).to.be(false);
|
||||
expect(Gun.is(0)).to.be(false);
|
||||
expect(Gun.is(1)).to.be(false);
|
||||
expect(Gun.is('')).to.be(false);
|
||||
expect(Gun.is('a')).to.be(false);
|
||||
expect(Gun.is(Infinity)).to.be(false);
|
||||
expect(Gun.is(NaN)).to.be(false);
|
||||
expect(Gun.is([])).to.be(false);
|
||||
expect(Gun.is([1])).to.be(false);
|
||||
expect(Gun.is({})).to.be(false);
|
||||
expect(Gun.is({a:1})).to.be(false);
|
||||
expect(Gun.is(function(){})).to.be(false);
|
||||
});
|
||||
it('is value',function(){
|
||||
expect(Gun.is.value(false)).to.be(true);
|
||||
expect(Gun.is.value(true)).to.be(true);
|
||||
expect(Gun.is.value(0)).to.be(true);
|
||||
expect(Gun.is.value(1)).to.be(true);
|
||||
expect(Gun.is.value('')).to.be(true);
|
||||
expect(Gun.is.value('a')).to.be(true);
|
||||
expect(Gun.is.value({'#':'somesoulidhere'})).to.be('somesoulidhere');
|
||||
expect(Gun.is.value({'#':'somesoulidhere', and: 'nope'})).to.be(false);
|
||||
expect(Gun.is.value(Infinity)).to.be(false); // boohoo :(
|
||||
expect(Gun.is.value(NaN)).to.be(false);
|
||||
expect(Gun.is.value([])).to.be(false);
|
||||
expect(Gun.is.value([1])).to.be(false);
|
||||
expect(Gun.is.value({})).to.be(false);
|
||||
expect(Gun.is.value({a:1})).to.be(false);
|
||||
expect(Gun.is.value(function(){})).to.be(false);
|
||||
});
|
||||
it('is soul',function(){
|
||||
expect(Gun.is.soul({'#':'somesoulidhere'})).to.be('somesoulidhere');
|
||||
expect(Gun.is.soul({'#':'somethingelsehere'})).to.be('somethingelsehere');
|
||||
expect(Gun.is.soul({'#':'somesoulidhere', and: 'nope'})).to.be(false);
|
||||
expect(Gun.is.soul({or: 'nope', '#':'somesoulidhere'})).to.be(false);
|
||||
expect(Gun.is.soul(false)).to.be(false);
|
||||
expect(Gun.is.soul(true)).to.be(false);
|
||||
expect(Gun.is.soul('')).to.be(false);
|
||||
expect(Gun.is.soul('a')).to.be(false);
|
||||
expect(Gun.is.soul(0)).to.be(false);
|
||||
expect(Gun.is.soul(1)).to.be(false);
|
||||
expect(Gun.is.soul(Infinity)).to.be(false); // boohoo :(
|
||||
expect(Gun.is.soul(NaN)).to.be(false);
|
||||
expect(Gun.is.soul([])).to.be(false);
|
||||
expect(Gun.is.soul([1])).to.be(false);
|
||||
expect(Gun.is.soul({})).to.be(false);
|
||||
expect(Gun.is.soul({a:1})).to.be(false);
|
||||
expect(Gun.is.soul(function(){})).to.be(false);
|
||||
});
|
||||
it('is node',function(){
|
||||
expect(Gun.is.node({_:{'#':'somesoulidhere'}})).to.be(true);
|
||||
expect(Gun.is.node({_:{'#':'somesoulidhere'}, a:0, b: 1, c: '', d: 'e', f: {'#':'somethingelsehere'}})).to.be(true);
|
||||
expect(Gun.is.node({_:{'#':'somesoulidhere'}, a:0, b: 1, c: '', d: 'e', f: {'#':'somethingelsehere'}, g: Infinity})).to.be(false);
|
||||
expect(Gun.is.node({_:{'#':'somesoulidhere'}, a:0, b: 1, z: NaN, c: '', d: 'e'})).to.be(false);
|
||||
expect(Gun.is.node({_:{'#':'somesoulidhere'}, a:0, b: 1, y: {_: 'cool'}, c: '', d: 'e'})).to.be(false);
|
||||
expect(Gun.is.node({_:{'#':'somesoulidhere'}, a:0, b: 1, x: [], c: '', d: 'e'})).to.be(false);
|
||||
expect(Gun.is.node({})).to.be(false);
|
||||
expect(Gun.is.node({a:1})).to.be(false);
|
||||
expect(Gun.is.node({_:{}})).to.be(false);
|
||||
expect(Gun.is.node({_:{}, a:1})).to.be(false);
|
||||
expect(Gun.is.node({'#':'somesoulidhere'})).to.be(false);
|
||||
});
|
||||
it('is graph',function(){
|
||||
expect(Gun.is.graph({'somesoulidhere': {_:{'#':'somesoulidhere'}}})).to.be(true);
|
||||
expect(Gun.is.graph({'somesoulidhere': {_:{'#':'somesoulidhere'}}, 'somethingelsehere': {_:{'#':'somethingelsehere'}}})).to.be(true);
|
||||
expect(Gun.is.graph({'somesoulidhere': {_:{'#':'somesoulidhere'}, a:0, b: 1, c: '', d: 'e', f: {'#':'somethingelsehere'}}, 'somethingelsehere': {_:{'#':'somethingelsehere'}}})).to.be(true);
|
||||
expect(Gun.is.graph({'somesoulidhere': {_:{'#':'somesoulidhere'}, a:0, b: 1, c: '', d: 'e', f: {'#':'somethingelsehere'}}})).to.be(true);
|
||||
expect(Gun.is.graph({'somesoulidhere': {_:{'#':'somesoulidhere'}, a:0, b: 1, c: '', d: 'e', f: {'#':'somethingelsehere'}}, foo: 1, 'somethingelsehere': {_:{'#':'somethingelsehere'}}})).to.be(false);
|
||||
expect(Gun.is.graph({'somesoulidhere': {_:{'#':'somesoulidhere'}, a:0, b: 1, c: '', d: 'e', f: {'#':'somethingelsehere'}}, foo: {}, 'somethingelsehere': {_:{'#':'somethingelsehere'}}})).to.be(false);
|
||||
expect(Gun.is.graph({'somesoulidhere': {_:{'#':'somesoulidhere'}, a:0, b: 1, c: '', d: 'e', f: {'#':'somethingelsehere'}}, foo: {_:{'#':'FOO'}}, 'somethingelsehere': {_:{'#':'somethingelsehere'}}})).to.be(false);
|
||||
expect(Gun.is.graph({'somesoulidhere': {_:{'#':'somesoulidhere'}, a:0, b: 1, c: '', d: 'e', f: {'#':'somethingelsehere'}}, foo: {_:{}}, 'somethingelsehere': {_:{'#':'somethingelsehere'}}})).to.be(false);
|
||||
expect(Gun.is.graph({'somesoulidhere': {_:{'#':'somesoulidhere'}, a:0, b: Infinity, c: '', d: 'e', f: {'#':'somethingelsehere'}}})).to.be(false);
|
||||
expect(Gun.is.graph({'somesoulidhere': {_:{'#':'somesoulidhere'}, a:0, b: Infinity, c: '', d: 'e', f: {'#':'somethingelsehere'}}, 'somethingelsehere': {_:{'#':'somethingelsehere'}}})).to.be(false);
|
||||
expect(Gun.is.graph({_:{'#':'somesoulidhere'}})).to.be(false);
|
||||
expect(Gun.is.graph({_:{'#':'somesoulidhere'}, a:0, b: 1, c: '', d: 'e', f: {'#':'somethingelsehere'}})).to.be(false);
|
||||
expect(Gun.is.graph({_:{'#':'somesoulidhere'}, a:0, b: 1, c: '', d: 'e', f: {'#':'somethingelsehere'}, g: Infinity})).to.be(false);
|
||||
expect(Gun.is.graph({_:{'#':'somesoulidhere'}, a:0, b: 1, z: NaN, c: '', d: 'e'})).to.be(false);
|
||||
expect(Gun.is.graph({_:{'#':'somesoulidhere'}, a:0, b: 1, y: {_: 'cool'}, c: '', d: 'e'})).to.be(false);
|
||||
expect(Gun.is.graph({_:{'#':'somesoulidhere'}, a:0, b: 1, x: [], c: '', d: 'e'})).to.be(false);
|
||||
expect(Gun.is.graph({})).to.be(false); // Empty graph is not a graph :(
|
||||
expect(Gun.is.graph({a:1})).to.be(false);
|
||||
expect(Gun.is.graph({_:{}})).to.be(false);
|
||||
expect(Gun.is.graph({_:{}, a:1})).to.be(false);
|
||||
expect(Gun.is.graph({'#':'somesoulidhere'})).to.be(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('ify', function(){
|
||||
|
46
web/deck/deck.html
Normal file
@ -0,0 +1,46 @@
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
font-size: 36pt;
|
||||
font-family: Verdana, Geneva, sans-serif;
|
||||
}
|
||||
</style>
|
||||
<div style="height: 100%; min-height: 500px; background-color: rgb(241, 90, 34); color: white;">
|
||||
<div id="e1413969480658t7942" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 413px;
|
||||
background-image: url('wave.png'); background-color: rgb(108, 197, 195); background-position: 43.1875% 100%; background-repeat: repeat-x;">
|
||||
<div id="e1414010158000t6484" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 9px;" contenteditable="false">Problem</div>
|
||||
<div id="e1414009476621t898" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 481px; width: 370px;
|
||||
background-image: url('whale.png'); background-position: 50% 50%; background-repeat: no-repeat;"></div>
|
||||
</div>
|
||||
<div id="e1414009076551t8032" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto 51px; min-height: 100px;">
|
||||
<br>Hassle to deploy slow databases that are costly to scale</div>
|
||||
</div>
|
||||
<div id="e1414009851463t501" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; height: 100%; min-height: 500px;">
|
||||
<div id="e1414009879758t838" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 100px; background-color: rgba(0, 0, 0, 0);" contenteditable="false">Solution</div>
|
||||
<div id="e1414009950683t8894" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; width: 50%; min-width: 200px; max-width: 500px; height: 400px;
|
||||
background-image: url('../../img/gun-logo.png'); background-position: 50% 50%; background-repeat: no-repeat; background-size: 100%;"></div>
|
||||
<div id="e1414009972993t897" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 100px; background-color: rgba(0, 0, 0, 0);" contenteditable="false">the NoDB database</div>
|
||||
</div>
|
||||
<div id="e1414010217854t5686" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; height: 100%; min-height: 500px; background-color: black; color: white;
|
||||
background-image: url('polygen.png'); background-position: 50% 50%; background-repeat: no-repeat; background-size: 100%;">
|
||||
<div id="e1414010395848t489" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 100px;" contenteditable="false">How</div>
|
||||
<div id="e1414010397417t8943" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; height: 500px;"></div>
|
||||
<div id="e1414010398484t2942" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 100px;" contenteditable="false">peer to peer algorithms that mimic reality</div>
|
||||
</div>
|
||||
<div id="e1414010478794t8943" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; height: 100%; min-height: 500px;">
|
||||
<div id="e1414010488753t8274" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 100px;" contenteditable="false">Now</div>
|
||||
<div id="e1414010489729t8174" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; height: 400px;
|
||||
background-image: url('stats.png'); background-position: 50% 50%; background-repeat: no-repeat; background-size: 100%;"></div>
|
||||
<div id="e1414010490585t2896" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 100px;" contenteditable="false">fastest growing trends ever in software history</div>
|
||||
</div>
|
||||
<div id="e1414010542879t6487" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 500px; height: 100%; background-color: black; color: white;
|
||||
background-image: url('team2.jpg'); background-position: 39.8610229492188% 17.7705977382876%; background-repeat: no-repeat; background-size: 100%;">
|
||||
<div id="e1414010614360t886" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 100px;" contenteditable="false">Team</div>
|
||||
<div id="e1414010615329t6812" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; height: 400px;"></div>
|
||||
<div id="e1414010616147t6367" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 100px;" contenteditable="false"></div>
|
||||
</div>
|
||||
<div id="e1414010638042t831" class="" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 500px; height: 100%;" contenteditable="false">
|
||||
<div id="e1414010679930t7366" class="create-evyt" style="position: relative; display: block; overflow: hidden; padding: 10px; margin: 0px auto; min-height: 100px;" contenteditable="false">we@gunDB.io are raising $500k</div>
|
||||
</div>
|
BIN
web/deck/team2.jpg
Normal file
After Width: | Height: | Size: 522 KiB |
BIN
web/deck/wave.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
web/deck/whale.png
Normal file
After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
@ -1,3 +1,9 @@
|
||||
HOOKS:
|
||||
- TRANSPORT:
|
||||
Has to basically re-implement set/load/key over some transport.
|
||||
REMEMBER that you have to subscribe on all set/load/key (especially key).
|
||||
|
||||
|
||||
Notes:
|
||||
|
||||
Messaging
|
210
web/time.html
Normal file
@ -0,0 +1,210 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
|
||||
<script src="../gun.js"></script>
|
||||
<link id="style" rel="stylesheet" href="https://yandex.st/highlightjs/8.0/styles/sunburst.min.css">
|
||||
<script src="https://yandex.st/highlightjs/8.0/highlight.min.js"></script>
|
||||
<script src="https://dl.dropboxusercontent.com/u/4374976/random/phrase.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
@import url(http://fonts.googleapis.com/css?family=Dosis|Poiret+One|Oxygen);
|
||||
html, body {
|
||||
font-family: 'Oxygen', Candara, Calibri, Segoe, "Segoe UI", Optima, Arial, sans-serif;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.lean {
|
||||
font-family: 'Poiret One', Candara, Calibri, Segoe, "Segoe UI", Optima, Arial, sans-serif;
|
||||
}
|
||||
.clean {
|
||||
font-family: 'Dosis', Candara, Calibri, Segoe, "Segoe UI", Optima, Arial, sans-serif;
|
||||
}
|
||||
.crisp {
|
||||
font-family: 'Oxygen', Candara, Calibri, Segoe, "Segoe UI", Optima, Arial, sans-serif;
|
||||
}
|
||||
pre {
|
||||
background-color: black;
|
||||
border: 1px dashed white;
|
||||
color: white;
|
||||
line-height: 1.5em;
|
||||
padding: 1em;
|
||||
overflow: hidden;
|
||||
}
|
||||
button {
|
||||
border: none;
|
||||
color: white;
|
||||
background: skyblue;
|
||||
padding: 1em;
|
||||
cursor: pointer;
|
||||
}
|
||||
input {
|
||||
background: transparent;
|
||||
border: 2px dashed grey;
|
||||
padding: 1em;
|
||||
}
|
||||
.step {
|
||||
display: none;
|
||||
}
|
||||
.step:target {
|
||||
display: block;
|
||||
}
|
||||
.grid {
|
||||
text-align: center;
|
||||
}
|
||||
.unit {
|
||||
display: inline-block;
|
||||
}
|
||||
.learn {
|
||||
min-width: 250px;
|
||||
max-width: 400px;
|
||||
width: 30%;
|
||||
padding: 2em;
|
||||
}
|
||||
</style>
|
||||
<div class="center">
|
||||
<h1 class="lean">Easiest . Database . Ever</h1>
|
||||
<h2 class="lean">Scale without pain, because it is decentralized.</h2>
|
||||
</div>
|
||||
<div id="steps">
|
||||
<div id="step1">
|
||||
As easy as 1, 2, 3!
|
||||
<ol>
|
||||
<li>Connect to a gun server.</li>
|
||||
<li>Save some data.</li>
|
||||
<li>Create a key to open it up later.</li>
|
||||
</ol>
|
||||
<pre>var gun = Gun('http://localhost:8888/gun');
|
||||
gun.set({hello: 'world'}).key('<span class="random">my/first/data</span>');</pre>
|
||||
<a href="#step2" class="run"><button>
|
||||
Try it Now!
|
||||
</button></a>
|
||||
<small>Disclaimer: This is a demo only! Data is deleted every 24 hours.</small>
|
||||
<!--
|
||||
<div>
|
||||
Already have a key? Then
|
||||
<input placeholder="copy and paste it into here!">
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div id="step2" class="step">
|
||||
Let's test to see if the data got saved.
|
||||
<ol>
|
||||
<li><a id="parallel" href="?key=" target="_blank">Open this page</a> in another browser tab.</li>
|
||||
<li>Now you'll see <b class="random" style="color: crimson;">my/first/data</b> load over there.
|
||||
<li>Meanwhile, this textarea will wait for realtime updates from the other tab:</li>
|
||||
</ol>
|
||||
<textarea style="width: 100%; height: 100px;">// Your data will log here!</textarea>
|
||||
The next level will be unlocked when you complete the realtime sync between tabs.
|
||||
</div>
|
||||
|
||||
<div id="step3" class="step">
|
||||
<pre>var gun = Gun('http://localhost:8888/gun');
|
||||
gun.load('<span class="random">my/first/data</span>', function(data){
|
||||
$('textarea').text(demo.print(data));
|
||||
});</pre>
|
||||
<a href="#step4" class="run"><button>
|
||||
Run the Code!
|
||||
</button></a> Does the key match from the previous tab?
|
||||
<textarea style="width: 100%; height: 100px;">// Your data will log here!</textarea>
|
||||
</div>
|
||||
|
||||
<div id="step4" class="step">
|
||||
Now let's listen to realtime updates, and change the value on the 'hello' field.
|
||||
<pre>gun.load('<span class="random">my/first/data</span>')
|
||||
.on(function(updates){
|
||||
$('textarea').text(demo.print(updates));
|
||||
}).path('hello').set('You!');</pre>
|
||||
<a class="run"><button>
|
||||
Let's do This!
|
||||
</button></a>
|
||||
<textarea style="width: 100%; height: 100px;">// Your data will log here!</textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid">
|
||||
<div class="learn unit center">
|
||||
<h1 class="lean">Did you know?</h1>
|
||||
<h2 class="lean">GUN is lightning fast, cause it runs in memory.</h2>
|
||||
Click to <a href="#step2" class="run"><button>
|
||||
See How
|
||||
</button></a> persistence works.
|
||||
</div>
|
||||
<div class="learn unit center">
|
||||
<h1 class="lean">Guess what!</h1>
|
||||
<h2 class="lean">GUN is the only database with realtime push notifications.</h2>
|
||||
Learn <a href="#step2" class="run"><button>
|
||||
How it Works
|
||||
</button></a>.
|
||||
</div>
|
||||
<div class="learn unit center">
|
||||
<h1 class="lean">Have Big Data?</h1>
|
||||
<h2 class="lean">GUN tranforms it into <i>meaningful data</i>, with regular JS.</h2>
|
||||
Discover <a href="#step2" class="run"><button>
|
||||
How To
|
||||
</button></a> do a graph search.
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(function(){
|
||||
var demo = {}, gun;
|
||||
window.demo = demo;
|
||||
demo.key = location.search.split('=')[1];
|
||||
demo.random = demo.key || random_phrase.noun() +'/'+ random_phrase.verb() +'/'+ random_phrase.adjective() +'/'+ random_phrase.noun() +'/'+ random_phrase.adverb();
|
||||
$(".random").text(demo.random);
|
||||
$('pre').each(function(){
|
||||
$(this).html(hljs.highlight('javascript', $(this).text()).value);
|
||||
});
|
||||
$('#step1').addClass((demo.key || location.hash)? 'step' : '').find('a').first().click(function(){
|
||||
$('#step1').addClass('step');
|
||||
});
|
||||
$('#parallel').attr('href', '?key=' + demo.random + '#step3');
|
||||
$(".run").click(function(){
|
||||
var code = $(this).closest('.step').attr('id');
|
||||
if(!code || !demo[code]){ return } // something went wrong!
|
||||
demo[code]();
|
||||
});
|
||||
demo.step0 = function(){
|
||||
gun = window.gun = window.gun || Gun('http://localhost:8888/gun');
|
||||
}
|
||||
demo.step1 = function(){
|
||||
demo.step0();
|
||||
gun.set({hello: 'world'}).key(demo.random);
|
||||
|
||||
// and also do this, so we can unlock!
|
||||
gun.load(demo.random)
|
||||
.on(function(updates){
|
||||
$('textarea').text(demo.print(updates));
|
||||
// unlock level 5!
|
||||
});
|
||||
}
|
||||
demo.step2 = function(){} // no step 2
|
||||
demo.step3 = function(){
|
||||
demo.step0();
|
||||
gun.load(demo.random, function(data){
|
||||
$('textarea').text(demo.print(data));
|
||||
});
|
||||
}
|
||||
demo.step4 = function(){
|
||||
demo.step0();
|
||||
gun.load(demo.random)
|
||||
.on(function(updates){
|
||||
$('textarea').text(demo.print(updates));
|
||||
}).path('hello').set('You!');
|
||||
}
|
||||
demo.print = function(data){
|
||||
if(!data){ return }
|
||||
delete data._; // this is gun specific metadata that we don't want to print.
|
||||
return JSON.stringify(data, null, 2);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<a href="https://github.com/amark/gun"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"></a>
|
||||
</body>
|
||||
</html>
|