<byondclass name="verbmenu">
<style>
.byond_verbmenu {
	position: absolute;
	z-index: 50;
}
.byond_verbmenu > div {
	position: relative;
	left: 0;
	top: 0;
	overflow-x: hidden;
	overflow-y: auto;
	border-width: 1px;
	border-style: solid;
}
.byond_verbmenu_header {
	font-weight: bold;
	border-bottom-width: 1px;
	border-bottom-style: solid;
	display: none;
}
.byond_verbmenu_item {
	padding: 2px;
	width: 100%;
	min-width: 5em;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	clear: both;
	cursor: pointer;
	line-height: 1;
}
.byond_verbmenu_item img {
	width: 16px;
	height: 16px;
}
.byond_verbmenu_item * {
	vertical-align: middle;
}
</style>
<script>
{
	// static method
	createAt: function(p,a) {	// p has x/y parameters that corresond to clientX/Y
		var t = byond.skin.attach(document.createElement('div'),'verbmenu'), top=t.top, s;
		t.config._pos = p = byond.extend({},p);
		s = byond.pos(document.querySelector('#skin'));
		p.x -= s.x;
		p.y -= s.y;
		byond.backstage().appendChild(top);
		t._repos();
		if(a) t.output(a);
	},
	fn: {
		create: function() {
			var t=this,ui=t.ui,e,ct=ui.contents;
			t.elem = e = ct.parentNode;
			ct.removeChild(ui.item);
			ui.header.onclick = t._atomClick.bind(t);
		},
		output: function(obj) {
			var t=this,c=t.config;
			if(!obj) {
				if(!t._atomClick()) t._close();
				return;
			}
			if(obj.atoms && obj.atoms.length) {
				c._atoms = obj.atoms.slice(0);
				c._verbs = c._atom = null;
				if(typeof obj.atom == 'number') t._atomClick(obj.atom);
				else t._fill();
			}
			else if(obj.verbs) {
				c._atom = obj.atom;
				c._verbs = obj.verbs;
				c._verbs.sort(function(a,b){
					a = a.name.toLowerCase();
					b = b.name.toLowerCase();
					return (a<b)?-1:((a>b)?1:0);
				});
				t._fill();
			}
			else if(typeof obj.atom == 'number') {
				t._atomClick(obj.atom);
			}
		},
		_repos: function() {
			var t=this,c=t.config,p=c._pos,top=t.top,e=t.elem,w,h,ws,ms,mp;
			ws = byond.innerSize(document.querySelector('#skin'));
			ms = {maxWidth:Math.min(byond.toPx('em')*20,ws.width/2), maxHeight:ws.height/2};
			mp = {};
			byond.cssPx(top,ms);
			byond.cssPx(e,ms);
			w = e.offsetWidth;
			h = e.offsetHeight;
			mp.left = (p.x+w >= ws.width) ? ws.width-w : p.x;
			mp.top = (p.y+h >= ws.height) ? ws.height-h : p.y;
			byond.cssPx(top,mp);
		},
		_show: function() {
			var t=this,c=t.config,s=document.querySelector('#skin')||document.body;
			t._repos();
			s.appendChild(t.top);
			t.captureMouse();
			delete c._dist;
		},
		_close: function() {
			this.remove();
		},
		mouseEvent: function(e) {
			var t=this,c=t.config,top=t.top,p=e,bp,f=10,d;
			if(e.changedTouches) {
				p=e.touches[0];
				if(!p) return;
			}
			if(e.type.match(/(start|move|down)$/i)) {
				bp = byond.pos(top);
				p = {x:e.clientX-bp.x, y:e.clientY-bp.y};
				d = Math.max(-p.x,-p.y,p.x-top.offsetWidth-1,p.y-top.offsetHeight-1);
				if(d <= 0) c._dist = -1;
				else if(d >= f) {
					// if the menu moved on us, reset the current distance
					if(!c._dist) c._dist = d;
					// if we were inside the menu, or we've moved too far away from where we were, close
					else if(c._dist < 0 || d >= c._dist + f) t._close();
					// mark the new distance as closest; moving too far from here will close
					else if(d < c._dist) c._dist = d;
				}
			}
		},
		_fill: function() {
			var t=this,c=t.config,ui=t.ui,d,ct=ui.contents,a,i,l,e,b=ui.bottom,txt;
			e=ui.header.nextSibling;
			if(typeof c._atom == 'number') {
				txt = t._atomHtml(c._atom);
				if(c._atoms) txt = '&laquo; ' + txt;
				ui.header.innerHTML = txt;
				byond.css(ui.header,'display','block');
			}
			else byond.css(ui.header,'display','none');
			if((a=c._verbs)) {
				for(i=0,l=a.length; i<l; ++i,e=e.nextSibling) {
					if(!e||e==b) {e = ui.item.cloneNode(false); ct.insertBefore(e,b);}
					e.innerHTML = byond.htmlEncode(t._verbName(a[i]));
					if(a[i].desc) byond.attr(e,'title',a[i].desc);
					byond.attr(e,'verb',a[i].name.replace(/\s+/g,'-')+' '+(a[i].args||''));
					e.onclick = t._verbClick;
				}
			}
			else if((a=c._atoms)) {
				for(i=0,l=a.length; i<l; ++i,e=e.nextSibling) {
					if(!e||e==b) {e = ui.item.cloneNode(false); ct.insertBefore(e,b);}
					e.innerHTML = t._atomHtml(a[i]) + ' <b>&raquo;</b>';
					byond.attr(e,'title',null);
					e.onclick = t._atomClick.bind(t,a[i]);
				}
			}
			while(e&&e!=b) {i=e.nextSibling; ct.removeChild(e); e=i;}
			t._show();
		},
		_atomHtml: function(atom) {
			var t=this, info = t.atomInfo(atom), txt, ic;
			if(!info) return '';
			txt = '<span>'+byond.htmlEncode(info.name)+'</span>';
			ic = t.atomIcon(atom);
			if(ic) txt = '<img src="'+ic+'" onload="byond(\''+t.id+'\')._repos()" /> ' + txt;
			return txt;
		},
		_verbName: function(v) {
			return v.name.replace(/(^|\s+)([a-z])/g, function(m,a,b){return a+b.toUpperCase();});
		},
		_atomClick: function(atom) {
			var t=this,c=t.config;
			if(typeof atom == 'number') {t.atomVerbs(atom); return true;}
			else if(c._verbs || typeof c._atom == 'number') {c._verbs = c._atom = null; t._fill(); return true;}
			return false;
		},
		_verbClick: function(e) {
			var v=e.target,t=byond.controlFor(v);
			v = byond.attr(v,'verb');
			if(v) t.input(v);
			t._close();
		}
	}
}
</script>
<div class="byond_bk1 byond_border">
<div id=contents class="byond_verbmenu_contents byond_bk1">
<div id=header class="byond_verbmenu_header byond_verbmenu_item byond_border0"></div>
<div id=item class="byond_verbmenu_item byond_buttonbk"></div>
<div id=bottom style="clear:both"></div>
</div>
</div>

</byondclass>