eval("C=document.body.children[0];$=C.getContext('2d');X=Y=Z=S=20;A=s(W=14,E=Array(281).join(F=0)),B=s(W,E);@s(w,v){a=v.split('');a.w=w;Qa}@_(v,f){i=v.length;while(i--)f(v[i],i%v.w,~~(i/v.w))}@l(v){Qv.length/v.w}@r(v){h=l(v),u=[],u.w=h;_(v,@(c,x,y){u[h*x+h-y-1]=c});Qu}@d(){C.width=C.height=400;_(B,@(c,x,y){$.fillStyle='#'+(c%5+4)+(c%3+3)+(c%2+3);$.fillRect(x*S,y*S,S,S)});$.restore();$.fillText(F,300,S)}@p(v,i,j,b){b=s(W,A.join('')),h=l(b),_(v,@(c,x,y){e=x+i,f=y+j;b&&((e<0||e>=W||f>=h||-c&&-b[f*W+e])?b=0:-c?b[f*W+e]=c:0)});Qb}@t(z,x,y){if(b=p(z,x,y))B=b,Z=z,X=x,Y=y}@n(){Q[s(4,'5555J333003J444400'),s(2,'1111J077770J888080J990099')][~~(Math.random()*7)]}@o(){w=W,h=S,j=1;while(h--){if(A.slice(i=h*w,i+w).indexOf('0')<0)A.splice(i,w),F++,j+=w}A.unshift.apply(A,Array(j).join(0).split(''))};onkeydown=@(e){d(eval(['t(Z,X-1,Y)','t(r(Z),X,Y)','t(Z,X+1,Y)'][e.keyCode-37]))};setInterval('t(Z,X,Y+1,c=B);c==B&&t(n(),5,0,A=B);d(o())',250);t(n(),5,0)".replace(/J/g,"'),s(3,'").replace(/Q/g,'return ').replace(/@/g,'function '))
/* C is the canvas element */
C=document.body.children[0]
/* $ is the canvas context */
$=C.getContext('2d')
/* X = piece x, Y = piece y, Z = piece sprite; they just need to be vivified here */
/* S is the scale factor, and doubles as the board height */
X=Y=Z=S=20
/* A and B are the board sprites; A does not contain the current piece */
/* W is the board width, F is the line count */
A=s(W=14,E=Array(281).join(F=0)),B=s(W,E)
/* s(3,222002) creates a 3x2 sprite '222', '002' */
function s(w,v){a=v.split('');a.w=w;return a}
/* _(v,function(c,x,y){...}) iterates over sprite v */
function _(v,f){i=v.length;while(i--)f(v[i],i%v.w,~~(i/v.w))}
/* l(v) returns the height of sprite v */
function l(v){return v.length/v.w}
/* r(v) rotates sprite v clockwise */
function r(v){h=l(v),u=[],u.w=h;_(v,function(c,x,y){u[h*x+h-y-1]=c});return u}
/* d() draws the board */
function d(){C.width=C.height=400;_(B,function(c,x,y){$.fillStyle='#'+(c%5+4)+(c%3+3)+(c%2+3);$.fillRect(x*S,y*S,S,S)});$.restore();$.fillText(F,300,S)}
/* p(P[1],0,2) returns a new board sprite with piece 1 at x 0, y 2, or undefined if it's out of bounds */
function p(v,i,j,b){b=s(W,A.join('')),h=l(b),_(v,function(c,x,y){e=x+i,f=y+j;b&&((e<0||e>=W||f>=h||-c&&-b[f*W+e])?b=0:-c?b[f*W+e]=c:0)});return b}
/* t(z,x,y) tries to change the current piece to z at x, y */
function t(z,x,y){if(b=p(z,x,y))B=b,Z=z,X=x,Y=y}
/* n() returns a new, randomly selected piece */
function n(){return [s(4,'5555'),s(3,'333003'),s(3,'444400'),s(2,'1111'),s(3,'077770'),s(3,'888080'),s(3,'990099')][~~(Math.random()*7)]}
/* o() removes full lines and shifts the board downward */
function o(){w=W,h=S,j=1;while(h--){if(A.slice(i=h*w,i+w).indexOf('0')<0)A.splice(i,w),F++,j+=w}A.unshift.apply(A,Array(j).join(0).split(''))}
/* Left arrow = move left; right arrow = move right; up arrow = rotate 90 degrees clockwise */
onkeydown=function(e){d(eval(['t(Z,X-1,Y)','t(r(Z),X,Y)','t(Z,X+1,Y)'][e.keyCode-37]))}
/* Pieces drop every 250 ms */
setInterval('t(Z,X,Y+1,c=B);c==B&&t(n(),5,0,A=B);d(o())',250)
/* Position the initial piece */
t(n(),5,0)