function f(){function j(s,w){var k=s[0],l=s[1],m=s[2],a=3.45565*k+27.1554*l+3.86714*m,p=0.0299566*k+0.184309*l+1.46709*m,t=2.02344*a+-2.52581*p,g=0.0809444479*t+-0.130504409*a+0.116721066*p,q=-0.0102485335*t+0.0540193266*a+-0.113614708*p;a=-3.65296938E-4*t+-0.00412161469*a+0.693511405*p;if(w)return[g>>0,q>>0,a>>0];g=k-g;q=l-q;a=m-a;return[k>>0,0.7*g+q+l>>0,0.7*g+a+m>>0]}var u=Math.random,h=document,i=h.getElementById("c"),c=i.getContext("2d"),r=(i.width=900)/199;i.height=520;h.body.style.background="#000";c.font="48px arial";c.fillText("RED",5,380);d=c.getImageData(8,344,97,37).data;for(n=o=d.length;(n-=4)>-1;){h=n/o*37;i=h%1*90;var b=d[n%o+3]>70;c.fillStyle="hsl("+((b?145:5)+30*u())+","+(90-50*u())+"%,"+((b?70:90)-50*u())+"%)";c.fillRect(0,0,1,1);b=c.getImageData(0,0,1,1).data;for(var e=0;e<4;e++){var v;v=e==1?j(b,true):e==2?j(b):e==3?j(j(b),true):[b[0],b[1],b[2]];c.fillStyle="rgb("+v.join(",")+")";c.fillRect(r*i+e%2*409,r*(h>>0)+(e>1?169:0),r,r)}}}window.onload=f;window.onmousedown=f;
          function f() {
	function f(rgb, blind) { // daltonize or simulate color
		var r = rgb[0],
			g = rgb[1],
			b = rgb[2],
			// RGB to LMS matrix conversion
			L = (17.8824 * r) + (43.5161 * g) + (4.11935 * b),
			M = (3.45565 * r) + (27.1554 * g) + (3.86714 * b),
			S = (0.0299566 * r) + (0.184309 * g) + (1.46709 * b),
			// Simulate color blindness in LMS space
			l = (2.02344 * M) + (-2.52581 * S),
			m = M,
			s = S,
			// LMS to RGB matrix conversion
			R = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
			G = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
			B = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);
		// Return protanope simulated color
		if(blind) return [R>>0,G>>0,B>>0];
		// Isolate invisible colors to color vision deficiency (calculate error matrix)
		R = r - R;
		G = g - G;
		B = b - B;
		// Shift colors towards visible spectrum (apply error modifications)
		// Add compensation to original values
		// Return daltonized color
		return [r >> 0, (((0.7 * R) + G) + g) >> 0, (((0.7 * R) + B) + b) >> 0];
	};
	var rand = Math.random, // cache object
		doc = document,
		element = doc.getElementById("c"), // grab <canvas>
		c = element.getContext("2d"), // get context
		w = (element.width = 900) / 199; // dimensions
	element.height = 520;
	doc.body.style.background = "#000";
	c.font = "48px arial"; // draw source pixels
	c.fillText("RED", 5, 380);
	d = c.getImageData(8, 344, 97, 37).data; // grab source pixels
	n = (o = d.length); while((n-=4)>-1) { // loop through draw commands
		var row = (n / o) * 37, // current pixel row
			col = row % 1 * 90 , // current pixel column
			b = d[n % o + 3]>70; // check whether pixel has alpha transparency (is this an ON or OFF pixel)
		// draw randomized color along the confusion line for a protanopic observer with variable saturation and lightness
		c.fillStyle = "hsl("+((b?145:5)+30*rand())+","+(90-50*rand())+"%,"+((b?70:90)-50*rand())+"%)"; 
		c.fillRect(0, 0, 1, 1);
		// convert color to RGB space, to LMS, and finally daltonize and/or simulate color blindness
		var rgb = c.getImageData(0, 0, 1, 1).data; 
		for(var j = 0; j < 4; j++) { // loop through display types
			var newcolor;
			if(j==1) newcolor = f(rgb, true); // simulated protanope
			else if(j==2) newcolor = f(rgb); // daltonized protanope
			else if(j==3) newcolor = f(f(rgb), true); // daltonized simulated protanope
			else newcolor = [rgb[0],rgb[1],rgb[2]];
			c.fillStyle = "rgb("+newcolor.join(",")+")"; // record color style
			c.fillRect(w * col + (j%2*409), w * (row>>0) + (j>1?169:0), w, w); // fill rect ;)
		}
	}
};
window.onload = f;
window.onmousedown = f;