text: /*! Periphery.js - v0.1.0 - 2013-01-10
  * http://cfurrow.github.com/periphery.js
  * Copyright (c) 2013 Carl Furrow; Licensed MIT */
  function deg2rad(e){return e*Math.PI/180}function rad2deg(e){return e*(180/Math.PI)}function distanceToClosestWallX(e,t){return deg2rad(t)>0&&deg2rad(t)<deg2rad(90)?ctx.canvas.width:deg2rad(t)>270&&deg2rad(t)<deg2rad(360)?ctx.canvas.width:deg2rad(t)>90&&deg2rad(t)<deg2rad(270)?0:e}function distanceToClosestWallY(e,t){return deg2rad(t)>deg2rad(235)&&deg2rad(t)<deg2rad(315)?0:deg2rad(t)>45&&deg2rad(t)<deg2rad(135)?ctx.canvas.height:e}function drawPeripheryVision(e,t){e.beginPath(),e.fillStyle="rgba(20,20,20,0.9)",t.periphery=[],e.moveTo(t.x,t.y),t.periphery.push(t.x,t.y);var n=t.x+t.visionRadius*Math.cos(t.direction-deg2rad(50)),r=t.y+t.visionRadius*Math.sin(t.direction-deg2rad(50));e.lineTo(n,r),t.periphery.push([n,r]),n=t.x+t.visionRadius*Math.cos(t.direction+deg2rad(50)),r=t.y+t.visionRadius*Math.sin(t.direction+deg2rad(50)),e.lineTo(n,r),t.periphery.push([n,r]),e.lineTo(t.x,t.y),e.closePath(),e.fill(),e.clip()}function drawCentralVision(e,t){e.beginPath(),e.fillStyle="rgba(200,200,200,0.9)",e.moveTo(t.x,t.y),t.central=[],t.central.push([t.x,t.y]);var n=t.x+t.visionRadius*Math.cos(t.direction-deg2rad(15)),r=t.y+t.visionRadius*Math.sin(t.direction-deg2rad(15));e.lineTo(n,r),t.central.push([n,r]),n=t.x+t.visionRadius*Math.cos(t.direction+deg2rad(15)),r=t.y+t.visionRadius*Math.sin(t.direction+deg2rad(15)),e.lineTo(n,r),t.central.push([n,r]),e.lineTo(t.x,t.y),e.closePath(),e.fill(),e.clip()}function drawPlayer(e,t){var n=t.x,r=t.y,i=t.direction;e.beginPath(),e.fillStyle="#ffffff",e.arc(n,r,playerRadius+2,0,Math.PI*2,!1),e.fill(),e.closePath(),e.beginPath(),e.fillStyle="#5e9fd2",e.arc(n,r,playerRadius,0,Math.PI*2,!1),e.fill(),e.closePath(),e.globalCompositeOperation="xor",drawPeripheryVision(e,t),e.save(),e.globalCompositeOperation="xor",drawCentralVision(e,t),e.restore()}function drawScene(e){var t=0,n=scene.length;for(;t<n;t++)scene[t].draw()}function handleMovement(e){e.movingForward&&(e.y+=e.velocity*2.5*Math.sin(e.direction),e.x+=e.velocity*2.5*Math.cos(e.direction)),e.movingBack&&(e.y-=e.velocity*2.5*Math.sin(e.direction),e.x-=e.velocity*2.5*Math.cos(e.direction)),e.turningRight&&(e.direction+=deg2rad(e.velocity),e.direction>deg2rad(360)&&(e.direction=0)),e.turningLeft&&(e.direction-=deg2rad(e.velocity),e.direction<deg2rad(0)&&(e.direction=deg2rad(360))),e.x=e.x-e.radius<0?e.radius:e.x,e.x=e.x+e.radius>ctx.canvas.width?ctx.canvas.width-e.radius:e.x,e.y=e.y-e.radius<0?e.radius:e.y,e.y=e.y+e.radius>ctx.canvas.height?ctx.canvas.height-e.radius:e.y,e.light.position=new Vec2(e.x,e.y)}function frame(){ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height),handleMovement(player),ctx.save(),drawPlayer(ctx,player),drawScene(player),player.light.angle=player.direction,lighting.light=player.light,lighting.objects=scene,lighting.compute(canvas.width,canvas.height),lighting.render(ctx),ctx.restore(),darkmask.lights=[player.light],darkmask.compute(canvas.width,canvas.height),darkmask.render(ctx),requestAnimationFrame(frame)}(function(e){function t(n,r){var i=t.epsilon||1e-6,s,o,u,a,f=[],l=n;if(typeof l=="object"&&typeof r=="number"){var c=l;r=l,r=c}typeof r=="number"?(s=r,o=arguments[2],u=s*s+o*o):(s=r.x,o=r.y,u=r.length2());var h=o*Math.sqrt(u-l*l),p=Math.acos((-l*s+h)/u),d=Math.acos((-l*s-h)/u),v=l*Math.cos(p),m=l*Math.sin(p),g=l*Math.cos(d),y=l*Math.sin(d);a=new e.Vec2(s+g,o+y),f.push(a);var b=a.length2();a=new e.Vec2(s+v,o-m),f.push(a);var w=a.length2();if(Math.abs(b-w)<i)return f;a=new e.Vec2(s+g,o-y),f.push(a);var E=a.length2();if(Math.abs(w-E)<i)return[a,f[1]];if(Math.abs(b-E)<i)return[f[0],a];a=new e.Vec2(s+v,o+m),f.push(a);var S=a.length2();return Math.abs(E-S)<i?[f[2],a]:Math.abs(w-S)<i?[f[1],a]:Math.abs(b-S)<i?[f[0],a]:f}function i(e,t){var n=document.createElement("canvas");return n.width=e,n.height=t,{canvas:n,ctx:n.getContext("2d"),w:e,h:t}}function s(e,t,n){var r=t[0];e.moveTo(r.x,r.y);for(var i=1;i<t.length;++i)r=t[i],e.lineTo(r.x,r.y);!n&&t.length>2&&(r=t[0],e.lineTo(r.x,r.y))}function a(e){for(var t=1;t<arguments.length;++t){var n=arguments[t];if(n)for(var r in n)n[r]!==void 0&&(e[r]=n[r])}}function f(){}function l(e,t){var n=e;f.prototype=t.prototype,e.prototype=new f,e.prototype.constructor=n,e.prototype.__super=t.prototype}e.Vec2=function(e,t){this.x=e||0,this.y=t||0},e.Vec2.prototype.copy=function(){return new e.Vec2(this.x,this.y)},e.Vec2.prototype.dot=function(e){return e.x*this.x+e.y*this.y},e.Vec2.prototype.sub=function(t){return new e.Vec2(this.x-t.x,this.y-t.y)},e.Vec2.prototype.add=function(t){return new e.Vec2(this.x+t.x,this.y+t.y)},e.Vec2.prototype.mul=function(t){return new e.Vec2(this.x*t,this.y*t)},e.Vec2.prototype.inv=function(){return this.mul(-1)},e.Vec2.prototype.dist2=function(e){var t=this.x-e.x,n=this.y-e.y;return t*t+n*n},e.Vec2.prototype.normalize=function(){var t=Math.sqrt(this.length2());return new e.Vec2(this.x/t,this.y/t)},e.Vec2.prototype.length2=function(e){return this.x*this.x+this.y*this.y},e.Vec2.prototype.toString=function(){return this.x+","+this.y},e.Vec2.prototype.inBound=function(e,t){return e.x<this.x&&this.x<t.x&&e.y<this.y&&this.y<t.y},e.Light=function(t){a(this,e.Light.defaults,t)},e.Light.defaults={position:new e.Vec2,distance:100,diffuse:.8},e.Light.prototype.render=function(e){},e.Light.prototype.mask=function(e){var t=this._getVisibleMaskCache();e.drawImage(t.canvas,Math.round(this.position.x-t.w/2),Math.round(this.position.y-t.h/2))},e.Light.prototype.bounds=function(){return{topleft:new e.Vec2(this.position.x-this.distance,this.position.y-this.distance),bottomright:new e.Vec2(this.position.x+this.distance,this.position.y+this.distance)}},e.Light.prototype.center=function(){return new e.Vec2(this.distance,this.distance)},e.Light.prototype.forEachSample=function(e){e(this.position)},e.Light.prototype._getVisibleMaskCache=function(){var e=Math.floor(this.distance*1.4),t=""+e;if(this.vismaskhash!=t){this.vismaskhash=t;var n=this._vismaskcache=i(2*e,2*e),r=n.ctx.createRadialGradient(e,e,0,e,e,e);r.addColorStop(0,"rgba(0,0,0,1)"),r.addColorStop(1,"rgba(0,0,0,0)"),n.ctx.fillStyle=r,n.ctx.fillRect(0,0,n.w,n.h)}return this._vismaskcache},e.OpaqueObject=function(t){a(this,e.OpaqueObject.defaults,t)},e.OpaqueObject.defaults={diffuse:.8},e.OpaqueObject.prototype.cast=function(e,t,n){},e.OpaqueObject.prototype.path=function(e){},e.OpaqueObject.prototype.bounds=function(){return{topleft:new e.Vec2,bottomright:new e.Vec2}},e.OpaqueObject.prototype.contains=function(e){return!1},e.Lamp=function(t){a(this,e.Light.defaults,e.Lamp.defaults,t)},l(e.Lamp,e.Light),e.Lamp.defaults={color:"rgba(250,220,150,0.8)",radius:0,samples:1,angle:0,roughness:0},e.Lamp.prototype._getHashCache=function(){return[this.color,this.distance,this.diffuse,this.angle,this.roughness].toString()},e.Lamp.prototype.center=function(){return new e.Vec2((1-Math.cos(this.angle)*this.roughness)*this.distance,(1+Math.sin(this.angle)*this.roughness)*this.distance)},e.Light.prototype.bounds=function(){var t=(new e.Vec2(Math.cos(this.angle),-Math.sin(this.angle))).mul(this.roughness*this.distance);return{topleft:new e.Vec2(this.position.x+t.x-this.distance,this.position.y+t.y-this.distance),bottomright:new e.Vec2(this.position.x+t.x+this.distance,this.position.y+t.y+this.distance)}},e.Lamp.prototype.mask=function(t){var n=this._getVisibleMaskCache(),r=(new e.Vec2(Math.cos(this.angle),-Math.sin(this.angle))).mul(this.roughness*this.distance);t.drawImage(n.canvas,Math.round(this.position.x+r.x-n.w/2),Math.round(this.position.y+r.y-n.h/2))},e.Lamp.prototype._getGradientCache=function(t){var n=this._getHashCache();if(this._cacheHashcode==n)return this._gcache;this._cacheHashcode=n;var r=Math.round(this.distance),s=r*2,o=i(s,s),u=o.ctx.createRadialGradient(t.x,t.y,0,r,r,r);return u.addColorStop(Math.min(1,this.radius/this.distance),this.color),u.addColorStop(1,e.getRGBA(this.color,0)),o.ctx.fillStyle=u,o.ctx.fillRect(0,0,o.w,o.h),this._gcache=o},e.Lamp.prototype.render=function(e){var t=this.center(),n=this._getGradientCache(t);e.drawImage(n.canvas,Math.round(this.position.x-t.x),Math.round(this.position.y-t.y))},e.Lamp.prototype.forEachSample=function(t){for(var r=0;r<this.samples;++r){var i=r*n,s=Math.sqrt(r/this.samples)*this.radius,o=new e.Vec2(Math.cos(i)*s,Math.sin(i)*s);t(this.position.add(o))}},e.DiscObject=function(t){a(this,e.OpaqueObject.defaults,e.DiscObject.defaults,t)},l(e.DiscObject,e.OpaqueObject),e.DiscObject.defaults={center:new e.Vec2,radius:20},e.DiscObject.prototype.cast=function(e,n,r){var i=this.center,o=i.sub(n),u=t(this.radius,o),a=u[0],f=u[1],l=a.add(n),c=f.add(n),h=(r.bottomright.x-r.topleft.x+(r.bottomright.y-r.topleft.y))/2;o=o.normalize().mul(h),a=a.normalize().mul(h),f=f.normalize().mul(h);var p=l.add(o),d=c.add(o),v=l.add(a),m=c.add(f),g=Math.atan2(o.x,-o.y);e.beginPath(),s(e,[c,m,d,p,v,l],!0),e.arc(i.x,i.y,this.radius,g,g+Math.PI),e.fill()},e.DiscObject.prototype.path=function(e){e.arc(this.center.x,this.center.y,this.radius,0,r)},e.DiscObject.prototype.bounds=function(){return{topleft:new e.Vec2(this.center.x-this.radius,this.center.y-this.radius),bottomright:new e.Vec2(this.center.x+this.radius,this.center.y+this.radius)}},e.DiscObject.prototype.contains=function(e){return e.dist2(this.center)<this.radius*this.radius},e.PolygonObject=function(t){a(this,e.OpaqueObject.defaults,e.PolygonObject.defaults,t)},l(e.PolygonObject,e.OpaqueObject),e.PolygonObject.defaults={points:[]},e.PolygonObject.prototype.bounds=function(){var e=this.points[0].copy(),t=e.copy();for(var n=1;n<this.points.length;++n){var r=this.points[n];r.x>t.x&&(t.x=r.x),r.y>t.y&&(t.y=r.y),r.x<e.x&&(e.x=r.x),r.y<e.y&&(e.y=r.y)}return{topleft:e,bottomright:t}},e.PolygonObject.prototype.contains=function(e){var t=this.points,n,r=t.length-1,i=e.x,s=e.y,o=!1;for(n=0;n<t.length;n++)(t[n].y<s&&t[r].y>=s||t[r].y<s&&t[n].y>=s)&&(t[n].x<=i||t[r].x<=i)&&t[n].x+(s-t[n].y)/(t[r].y-t[n].y)*(t[r].x-t[n].x)<i&&(o=!o),r=n;return o},e.PolygonObject.prototype.path=function(e){s(e,this.points)},e.PolygonObject.prototype.cast=function(e,t,n){var r=(n.bottomright.x-n.topleft.x+(n.bottomright.y-n.topleft.y))/2;this._forEachVisibleEdges(t,n,function(n,i,o,u,a){var f,l=o.inv().dot(a)/a.length2();l<0?f=n:l>1?f=i:f=n.add(a.mul(l));var c=f.sub(t);c=c.normalize().mul(r),o=o.normalize().mul(r),u=u.normalize().mul(r);var h=n.add(c),p=i.add(c),d=n.add(o),v=i.add(u);e.beginPath(),s(e,[n,i,v,p,h,d]),e.fill()})},e.PolygonObject.prototype._forEachVisibleEdges=function(t,n,r){var i=this.points[this.points.length-1],s;for(var o=0;o<this.points.length;++o,i=s){s=this.points[o];if(i.inBound(n.topleft,n.bottomright)){var u=i.sub(t),a=s.sub(t),f=s.sub(i),l=new e.Vec2(f.y,-f.x);l.dot(u)<0&&r(i,s,u,a,f)}}},e.RectangleObject=function(t){a(this,e.OpaqueObject.defaults,e.PolygonObject.defaults,e.RectangleObject.defaults,t),this.syncFromTopleftBottomright()},l(e.RectangleObject,e.PolygonObject),e.RectangleObject.defaults={topleft:new e.Vec2,bottomright:new e.Vec2},e.RectangleObject.prototype.syncFromTopleftBottomright=function(){var t=this.topleft,n=new e.Vec2(this.bottomright.x,this.topleft.y),r=this.bottomright,i=new e.Vec2(this.topleft.x,this.bottomright.y);this.points=[t,n,r,i]},e.RectangleObject.prototype.fill=function(e){var t=this.points[0].x,n=this.points[0].y;e.rect(t,n,this.points[2].x-t,this.points[2].y-n)},e.LineObject=function(t){a(this,e.OpaqueObject.defaults,e.PolygonObject.defaults,e.LineObject.defaults,t),this.syncFromAB()},l(e.LineObject,e.PolygonObject),e.LineObject.defaults={a:new e.Vec2,b:new e.Vec2},e.LineObject.prototype.syncFromAB=function(){this.points=[this.a,this.b]},e.Lighting=function(t){a(this,e.Lighting.defaults,t)},e.Lighting.defaults={light:new e.Light,objects:[]},e.Lighting.prototype.createCache=function(e,t){this._cache=i(e,t),this._castcache=i(e,t)},e.Lighting.prototype.cast=function(e){var t=this.light,n=t.samples,r=this._castcache,i=r.ctx;i.clearRect(0,0,r.w,r.h),i.fillStyle="rgba(0,0,0,"+Math.round(100/n)/100+")";var s=t.bounds(),o=this.objects;t.forEachSample(function(e){var t=!1;for(var n=0;n<o.length;++n)if(o[n].contains(e)){i.fillRect(s.topleft.x,s.topleft.y,s.bottomright.x-s.topleft.x,s.bottomright.y-s.topleft.y);return}o.forEach(function(t){t.cast(i,e,s)})}),o.forEach(function(e){var n=e.diffuse===undefined?.8:e.diffuse;n*=t.diffuse,i.fillStyle="rgba(0,0,0,"+(1-n)+")",i.beginPath(),e.path(i),i.fill()}),e.drawImage(r.canvas,0,0)},e.Lighting.prototype.compute=function(e,t){(!this._cache||this._cache.w!=e||this._cache.h!=t)&&this.createCache(e,t);var n=this._cache.ctx,r=this.light;n.save(),n.clearRect(0,0,n.canvas.width,n.canvas.height),r.render(n),n.globalCompositeOperation="destination-out",this.cast(n),n.restore()},e.Lighting.prototype.render=function(e){e.drawImage(this._cache.canvas,0,0)},e.DarkMask=function(t){a(this,e.DarkMask.defaults,t)},e.DarkMask.defaults={lights:[],color:"rgba(0,0,0,0.9)"},e.DarkMask.prototype.compute=function(e,t){if(!this._cache||this._cache.w!=e||this._cache.h!=t)this._cache=i(e,t);var n=this._cache.ctx;n.save(),n.clearRect(0,0,e,t),n.fillStyle=this.color,n.fillRect(0,0,e,t),n.globalCompositeOperation="destination-out",this.lights.forEach(function(e){e.mask(n)}),n.restore()},e.DarkMask.prototype.render=function(e){e.drawImage(this._cache.canvas,0,0)};var n=Math.PI*(3-Math.sqrt(5)),r=2*Math.PI;e.createCanvasAnd2dContext=i,e.path=s;var o=e.getRGBA=function(){var e=document.createElement("canvas");e.width=e.height=1;var t=e.getContext("2d");return function(e,n){t.clearRect(0,0,1,1),t.fillStyle=e,t.fillRect(0,0,1,1);var r=t.getImageData(0,0,1,1).data;return"rgba("+[r[0],r[1],r[2],n]+")"}}(),u=e.extractColorAndAlpha=function(){function n(e){var t=e.toString(16);return t.length==1&&(t="0"+t),t}var e=document.createElement("canvas");e.width=e.height=1;var t=e.getContext("2d");return function(e){t.clearRect(0,0,1,1),t.fillStyle=e,t.fillRect(0,0,1,1);var r=t.getImageData(0,0,1,1).data;return{color:"#"+n(r[0])+n(r[1])+n(r[2]),alpha:Math.round(1e3*r[3]/255)/1e3}}}();e.extend=a,e.inherit=l})(window.illuminated={});var Vec2=illuminated.Vec2,RectangleObject=illuminated.RectangleObject,Shape=function(e,t){this.x=e,this.y=t,this.draw=function(){};var n=new RectangleObject({topleft:new Vec2(this.x,this.y),bottomright:new Vec2(this.x+this.width,this.y+this.height)});this._forEachVisibleEdges=n._forEachVisibleEdges,this.inBound=n.inBound,this._forEachVisibleEdges=n._forEachVisibleEdges,this.contains=n.contains,this.cast=n.cast,this.path=n.path},Rectangle=Rectangle||{},Vec2=illuminated.Vec2,RectangleObject=illuminated.RectangleObject;Rectangle=function(e,t,n,r,i){Shape.apply(this,arguments),this.width=n,this.height=r,this.fillStyle=i,this.enableShadows=!1;var s=new RectangleObject({topleft:new Vec2(this.x,this.y),bottomright:new Vec2(this.x+this.width,this.y+this.height)});this.points=s.points,this.draw=function(){ctx.save(),ctx.fillStyle=this.fillStyle,ctx.fillRect(this.x,this.y,this.width,this.height),ctx.restore()}},Rectangle.prototype=new Shape;var Vec2=illuminated.Vec2,DiscObject=illuminated.DiscObject,Circle=Circle||{};Circle=function(e,t,n,r){Shape.apply(this,arguments),this.radius=n,this.fillStyle=r,this.center=new Vec2(this.x,this.y);var i=new DiscObject({center:new Vec2(this.x,this.y),radius:this.radius});this.contains=i.contains,this.cast=i.cast,this.points=i.points,this.path=i.path,this.draw=function(e){ctx.save(),ctx.fillStyle=this.fillStyle,ctx.beginPath(),ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,!1),ctx.closePath(),ctx.fill(),ctx.restore()}},Circle.prototype=new Shape;var Vec2=illuminated.Vec2,MovingCircle=function(e,t,n,r,i){Circle.apply(this,arguments),this.velocity=5,this.movingdown=!1,this.movingup=!0,this.movingright=!1,this.movingleft=!0,this.move=function(){this.movingleft&&(this.x-=this.velocity),this.movingright&&(this.x+=this.velocity),this.movingup&&(this.y-=this.velocity),this.movingdown&&(this.y+=this.velocity),this.x<this.radius&&(this.movingleft=!1,this.movingright=!0),this.x>ctx.canvas.width-this.radius&&(this.movingright=!1,this.movingleft=!0),this.y<this.radius&&(this.movingup=!1,this.movingdown=!0),this.y>ctx.canvas.height-this.radius&&(this.movingup=!0,this.movingdown=!1),this.center=new Vec2(this.x,this.y)},this.draw=function(e){this.move(),ctx.save(),ctx.fillStyle=this.fillStyle,ctx.beginPath(),ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,!1),ctx.closePath(),ctx.fill(),ctx.restore()}};MovingCircle.prototype=new Circle;var canvas=document.getElementById("c"),ctx=canvas.getContext("2d"),img=document.createElement("IMG"),playerRadius=10,FPS=60,width=0,height=0,scene=[],enableShadows=!1,Vec2=illuminated.Vec2,Lamp=illuminated.Lamp,Lighting=illuminated.Lighting,DarkMask=illuminated.DarkMask,lighting=null,darkmask=null;width=canvas.width,height=canvas.height;var player={x:width/2-playerRadius,y:height/2-playerRadius,direction:deg2rad(191),visionRadius:canvas.width*2,radius:playerRadius,velocity:3,turningLeft:!1,turningRight:!1,movingForward:!1,movingBack:!1,periphery:[[0,0],[0,0],[0,0]],central:[[0,0],[0,0],[0,0]],light:new Lamp({position:new Vec2(200,150),distance:350,radius:10,samples:1})};scene.push(new Rectangle(10,10,50,50,"rgb(255,0,0)")),scene.push(new Rectangle(400,400,30,30,"rgb(0,255,0)")),scene.push(new Rectangle(500,10,90,90,"rgb(0,0,255)")),scene.push(new Circle(90,300,30,"rgb(255,100,0)")),scene.push(new MovingCircle(90,300,30,"rgb(10,200,250)")),document.onkeydown=function(e){var t=!1;return e.which===38&&(player.movingForward=!0,player.movingBack=!1,t=!0),e.which===40&&(player.movingBack=!0,player.movingForward=!1,t=!0),e.which===37&&(player.turningLeft=!0,player.turningRight=!1,t=!0),e.which===39&&(player.turningRight=!0,player.turningLeft=!1,t=!0),!t},document.onkeyup=function(e){return e.which===38&&(player.movingForward=!1),e.which===40&&(player.movingBack=!1),e.which===37&&(player.turningLeft=!1),e.which===39&&(player.turningRight=!1),e.which===83&&(enableShadows=!enableShadows),!1};var requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(e){setTimeout(e,1e3/FPS)};lighting=new Lighting({light:player.light,objects:scene}),darkmask=new DarkMask({lights:[player.light],color:"rgba(0,0,0,1)"}),requestAnimationFrame(frame);