c.T=c.translate,c.Z=c.rotate,c.m=c.moveTo,c.l=c.lineTo,r=new AudioContext,T=s=0;setInterval("a.width=J=innerWidth;a.height=K=innerHeight;D=.5*(S=Math.sin)((N=Date.now())/500)-.5;A=(P=Math.PI)/4*(C=Math.cos)(N/1500)+P/4;B=N/10%(3*R);c.clearRect(0,0,J,K);c.T(-B,0);for(e=0;e<K/R*3/2;e++)for(f=0;n=0,f<J/R;f++){c.T(U=f*3*R+(e%2>0?R*3/2:0),V=e*R*S(P/3)),h=[P*2/3,-P,-P*2/3,-P/3,0,P/3];for(i=0;i<P*5/3;n++)c.lineCap='butt',c.lineWidth=9,c.strokeStyle='hsl('+(((5-n)*60+N/10)%360)+',99%,50%)',L=S(j=i+P/3)*R,M=C(i)*R,Q=(C(j)*R+M)/2,O=(S(i)*R+L)/2,c.beginPath(),c.T(u=Q+(Q-M)*D,v=O-(O-L)*D),c.Z(y=h[n]+A),c.m(0,0),c.l(H=R/2*(1-D)*S(P/3)/S(P*2/3-A),0),c.Z(-y),c.T(-u,-v),c.T(w=Q-(Q-M)*D,x=O+(O-L)*D),c.Z(z=h[n]+P-A),c.m(0,0),c.l(H,0),c.Z(-z),c.T(-w,-x),c.stroke(),i=j;c.T(-U,-V)}c.T(B,0)",1);setInterval("if(s.type)s.disconnect();(s=r.createOscillator()).connect(r.destination);s.frequency.value=Math.pow(2,((W=\"EAAAYEEEFFFFnAAAE@A@YEEEF@F@nAAA\".charCodeAt(T/2)>>(T++%2)*3&7)+16)/12)*(W>0?440:0);T%=64;s.start()",R=150)
          // JS1K ENTRY
// Title: Harmony
// by Muhammad Rifqi Priyo Susanto
// This source code mostly telling tricks used in this demo.
/*
	Below are list of global one-character variable used in this demo.
	a: (JS1k) canvas
	b: (JS1k) body
	c: (JS1k) CanvasRenderingContext2D
	d: (JS1k) document
	e: loop
	f: loop
	g: (JS1k) CanvasRenderingContext3D
	h: at[]
	i: loop
	j: loop (next)
	n: counter
	r: AudioContext
	s: Oscillator
	u: ux
	v: uy
	w: vx
	x: vy
	y: ur
	z: vr
	A: ray's angle
	B: translation animation
	C: Math.cos
	D: distance between rays
	H: Hanken's length
	J: window.innerWidth
	K: window.innerHeight
	L: jy
	M: ix
	N: Date.now()
	O: my
	P: Math.PI
	Q: mx
	R: Hexagon's size
	S: Math.sin
	T: audio's time
	U: Center of hexagon in x axis
	V: Center of hexagon in y axis
	W: audio's data
	Z: draw loop
*/
// Initialise some values.
// Some shortcuts for canvas.
c.T = c.translate, c.Z = c.rotate, c.m = c.moveTo, c.l = c.lineTo,
// No need to add round-bracket if it has no argument.
r = new AudioContext,
T = s = 0;
// DRAWING //
// The drawing loop.
// This demo is an example of islamic geometric pattern with hexagonal tiling.
// Mostly inspired by this video: https://youtu.be/sJ6pMLp_IaI
setInterval( function () {
	// Set the canvas size into correct width and height while also assign them
	// into variables.
	a.width = J = innerWidth;
	a.height = K = innerHeight;
	// Assign a function or value into a variable while also using it.
	// Distance and angle is calculated using Date.now().
	// I was experimenting with the value, so these numbers are "magic numbers".
	D = .5 * ( S = Math.sin )( ( N = Date.now() ) / 500 ) - .5;
	A = ( P = Math.PI ) / 4 * ( C = Math.cos )( N / 1500 ) + P / 4;
	// Translation for the tiles. We use modulo 3 * R,  so we only repeat the
	// tile movement and don't need to draw many hexagons.
	B = N / 10 % ( 3 * R );
	c.clearRect( 0, 0, J, K );
	c.T( -B, 0 );
	for ( e = 0; e < K / R * 3 / 2; e++ )
		for ( f = 0; n = 0, f < J / R; f++ ) {
			c.T( U = f * 3 * R + ( e % 2 > 0 ? R * 3 / 2 : 0 ), V = e * R * S( P / 3 ) ),
			// This array contains rotation offset for each side of hexagons.
			h = [ P * 2 / 3, -P, -P * 2 / 3, -P / 3, 0, P / 3 ];
			// Old trick: use comma to separate command to save two curly-brackets.
			for ( i = 0; i < P * 5 / 3; n++ )
				c.lineCap = 'round',
				// We use biggest number which can fit in one byte.
				c.lineWidth = 9,
				// Instead of writing 100%, we can slightly reduce it and use 99%.
				// Because one byte is expensive.
				c.strokeStyle = 'hsl(' + ( ( ( 5 - n ) * 60 + N / 10 ) % 360 ) + ',99%,50%)',
				// These messy things are for drawing two lines at each side
				// of hexagon.
				L = S( j = i + P / 3 ) * R,
				M = C( i ) * R,
				Q = ( C( j ) * R + M ) / 2,
				O = ( S( i ) * R + L ) / 2,
				// We can use just one beginPath() to draw two lines.
				c.beginPath(),
				// We use Manhattan distance instead of Euclidean distance to
				// save bytes also increasing performance.
				c.T( u = Q + ( Q - M ) * D, v = O - ( O - L ) * D ),
				c.Z( y = h[ n ] + A ),
				c.m( 0, 0 ),
				c.l( H = R / 2 * ( 1 - D ) * S( P / 3 ) / S( P * 2 / 3 - A ), 0 ),
				c.Z( -y ),
				c.T( -u, -v ),
				c.T( w = Q - ( Q - M ) * D, x = O + ( O - L ) * D ),
				c.Z( z = h[ n ] + P - A ),
				c.m( 0, 0 ),
				c.l( H, 0 ),
				c.Z( -z ),
				c.T( -w, -x ),
				c.stroke(),
				i = j;
			c.T( -U, -V )
		}
	c.T( B, 0 )
// Actually, some browsers support to not include second argument, but seems
// like it is not supported in Firefox.
}, 1 );
// AUDIO //
// The song you hear is from Vidya Vidya - Safari Fruits. Only some parts included.
// (https://youtu.be/PbIjuqd4ENY)
// It is not copyrighted sound, so I can use it. Also, I can't make good song.
setInterval( function () {
		// Rather than checking if it's undefined or not, we check value
		// inside OscillatorNode.
		if ( s.type )
			s.disconnect();
		( s = r.createOscillator() ).connect( r.destination );
		// We use note to frequency equation:
		// freq = base * 2^((note - 49) / 12)
		s.frequency.value = Math.pow(
			2,
			// This string is actually song data, packed.
			// This song used in this demo only ranging 6 notes, so we can pack
			// it like this:
			// |---------8 bits---------|
			//  0 1    1 1 0      0 0 0
			// mark   note (6)   no-notes
			// Since do (C6) is note number 64, we can simplify the equation:
			// freq = base * 2^((note + 16) / 12)
			// Played note = 63 + value
			// To simplify things, we place first note at rightmost bits, so we
			// can shift right 0 bit for first note and then 3 bits for
			// second note.
			( ( W = "EAAAYEEEFFFFnAAAE@A@YEEEF@F@nAAA".charCodeAt( T / 2 ) >>
					( T++ % 2 ) * 3 & 7 ) + 16 ) / 12
			// If the value is zero, it means it doesn't play anything.
		) * (W > 0 ? 440 : 0);
		T %= 64;
		s.start()
// This R variable is actually also used in drawing loop.
}, R = 150 );
// More explanation will be in my blog post.