diff --git a/project.js b/project.js
new file mode 100644
index 0000000000000000000000000000000000000000..aa0664a20a206251492f0f9f0797c3d38f735681
--- /dev/null
+++ b/project.js
@@ -0,0 +1,822 @@
+/*
+(CC-NC-BY) Jun-ho Roh 2019
+*/
+
+var gl;
+var fragsource;
+var vertexsource;
+var vm_value= new Array();
+var timer;
+var pm_value = new Array();
+var near,far;
+var fov_up, fov_down, fov_left, fov_right;
+var is_cal;
+var mm_value = new Array();
+var is_pause;
+var out = new Array();
+var proj_matrix = perspectiveFromFieldOfView(out, [30.0, 30.0, 30.0, 30.0], 2, 20.0);
+var view_matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,-5,1];
+var mov_matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1];
+
+
+//make 4d identity matrix
+function idMatrix(m) {
+    m[0] = 1; m[1] = 0; m[2] = 0; m[3] = 0; 
+    m[4] = 0; m[5] = 1; m[6] = 0; m[7] = 0; 
+    m[8] = 0; m[9] = 0; m[10] = 1; m[11] = 0; 
+    m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; 
+}
+
+ /**
+   * Multiplies two mat4s
+   *
+   * @param {mat4} out the receiving matrix
+   * @param {mat4} a the first operand
+   * @param {mat4} b the second operand
+   * @returns {mat4} out
+   */
+function multiply$3(out, a, b) {
+    var a00 = a[0],
+        a01 = a[1],
+        a02 = a[2],
+        a03 = a[3];
+    var a10 = a[4],
+        a11 = a[5],
+        a12 = a[6],
+        a13 = a[7];
+    var a20 = a[8],
+        a21 = a[9],
+        a22 = a[10],
+        a23 = a[11];
+    var a30 = a[12],
+       
+        a31 = a[13],
+        a32 = a[14],
+        a33 = a[15]; // Cache only the current line of the second matrix
+
+    var b0 = b[0],
+        b1 = b[1],
+        b2 = b[2],
+        b3 = b[3];
+
+    out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
+    out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
+    out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
+    out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
+    b0 = b[4];
+    b1 = b[5];
+    b2 = b[6];
+    b3 = b[7];
+    out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
+    out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
+    out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
+    out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
+    b0 = b[8];
+    b1 = b[9];
+    b2 = b[10];
+    b3 = b[11];
+    out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
+    out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
+    out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
+    out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
+    b0 = b[12];
+    b1 = b[13];
+    b2 = b[14];
+    b3 = b[15];
+    out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
+    out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
+    out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
+    out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
+    return out;
+  }
+
+/**
+   * Translate a mat4 by the given vector
+   *
+   * @param {mat4} out the receiving matrix
+   * @param {mat4} a the matrix to translate
+   * @param {vec3} v vector to translate by
+   * @returns {mat4} out
+*/
+function translate$2(out, a, v) {
+    var x = v[0],
+        y = v[1],
+        z = v[2];
+    var a00, a01, a02, a03;
+    var a10, a11, a12, a13;
+    var a20, a21, a22, a23;
+
+    if (a === out) {
+      out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
+      out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
+      out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
+      out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
+    } else {
+      a00 = a[0];
+      a01 = a[1];
+      a02 = a[2];
+      a03 = a[3];
+      a10 = a[4];
+      a11 = a[5];
+      a12 = a[6];
+      a13 = a[7];
+      a20 = a[8];
+      a21 = a[9];
+      a22 = a[10];
+      a23 = a[11];
+      out[0] = a00;
+      out[1] = a01;
+      out[2] = a02;
+      out[3] = a03;
+      out[4] = a10;
+      out[5] = a11;
+      out[6] = a12;
+      out[7] = a13;
+      out[8] = a20;
+      out[9] = a21;
+      out[10] = a22;
+      out[11] = a23;
+      out[12] = a00 * x + a10 * y + a20 * z + a[12];
+      out[13] = a01 * x + a11 * y + a21 * z + a[13];
+      out[14] = a02 * x + a12 * y + a22 * z + a[14];
+      out[15] = a03 * x + a13 * y + a23 * z + a[15];
+    }
+
+    return out;
+  }
+
+  /**
+   * Scales the mat4 by the dimensions in the given vec3 not using vectorization
+   *
+   * @param {mat4} out the receiving matrix
+   * @param {mat4} a the matrix to scale
+   * @param {vec3} v the vec3 to scale the matrix by
+   * @returns {mat4} out
+   **/
+function scale$3(out, a, v) {
+    var x = v[0],
+        y = v[1],
+        z = v[2];
+    out[0] = a[0] * x;
+    out[1] = a[1] * x;
+    out[2] = a[2] * x;
+    out[3] = a[3] * x;
+    out[4] = a[4] * y;
+    out[5] = a[5] * y;
+    out[6] = a[6] * y;
+    out[7] = a[7] * y;
+    out[8] = a[8] * z;
+    out[9] = a[9] * z;
+    out[10] = a[10] * z;
+    out[11] = a[11] * z;
+    out[12] = a[12];
+    out[13] = a[13];
+    out[14] = a[14];
+    out[15] = a[15];
+    return out;
+}
+
+
+  /**
+   * Rotates a mat4 by the given angle around the given axis
+   *
+   * @param {mat4} out the receiving matrix
+   * @param {mat4} a the matrix to rotate
+   * @param {Number} rad the angle to rotate the matrix by
+   * @param {vec3} axis the axis to rotate around
+   * @returns {mat4} out
+   */
+function rotate$3(out, a, rad, axis) {
+    var x = axis[0],
+        y = axis[1],
+        z = axis[2];
+    var len = Math.hypot(x, y, z);
+    var s, c, t;
+    var a00, a01, a02, a03;
+    var a10, a11, a12, a13;
+    var a20, a21, a22, a23;
+    var b00, b01, b02;
+    var b10, b11, b12;
+    var b20, b21, b22;
+
+    if (len < 1e-6) {
+      return null;
+    }
+
+    len = 1 / len;
+    x *= len;
+    y *= len;
+    z *= len;
+    s = Math.sin(rad);
+    c = Math.cos(rad);
+    t = 1 - c;
+    a00 = a[0];
+    a01 = a[1];
+    a02 = a[2];
+    a03 = a[3];
+    a10 = a[4];
+    a11 = a[5];
+    a12 = a[6];
+    a13 = a[7];
+    a20 = a[8];
+    a21 = a[9];
+    a22 = a[10];
+    a23 = a[11]; // Construct the elements of the rotation matrix
+
+    b00 = x * x * t + c;
+    b01 = y * x * t + z * s;
+    b02 = z * x * t - y * s;
+    b10 = x * y * t - z * s;
+    b11 = y * y * t + c;
+    b12 = z * y * t + x * s;
+    b20 = x * z * t + y * s;
+    b21 = y * z * t - x * s;
+    b22 = z * z * t + c; // Perform rotation-specific matrix multiplication
+
+    out[0] = a00 * b00 + a10 * b01 + a20 * b02;
+    out[1] = a01 * b00 + a11 * b01 + a21 * b02;
+    out[2] = a02 * b00 + a12 * b01 + a22 * b02;
+    out[3] = a03 * b00 + a13 * b01 + a23 * b02;
+    out[4] = a00 * b10 + a10 * b11 + a20 * b12;
+    out[5] = a01 * b10 + a11 * b11 + a21 * b12;
+    out[6] = a02 * b10 + a12 * b11 + a22 * b12;
+    out[7] = a03 * b10 + a13 * b11 + a23 * b12;
+    out[8] = a00 * b20 + a10 * b21 + a20 * b22;
+    out[9] = a01 * b20 + a11 * b21 + a21 * b22;
+    out[10] = a02 * b20 + a12 * b21 + a22 * b22;
+    out[11] = a03 * b20 + a13 * b21 + a23 * b22;
+
+    if (a !== out) {
+      // If the source and destination differ, copy the unchanged last row
+      out[12] = a[12];
+      out[13] = a[13];
+      out[14] = a[14];
+      out[15] = a[15];
+    }
+
+    return out;
+}
+
+
+/**
+   * Generates a perspective projection matrix with the given field of view.
+   * This is primarily useful for generating projection matrices to be used
+   * with the still experiemental WebVR API.
+   *
+   * @param {mat4} out mat4 frustum matrix will be written into
+   * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees
+   * @param {number} near Near bound of the frustum
+   * @param {number} far Far bound of the frustum
+   * @returns {mat4} out
+   */
+function perspectiveFromFieldOfView(out, fov, near, far) {
+    var upTan = Math.tan(fov[0]* Math.PI / 180.0);
+    var downTan = Math.tan(fov[1] * Math.PI / 180.0);
+    var leftTan = Math.tan(fov[2] * Math.PI / 180.0);
+    var rightTan = Math.tan(fov[3] * Math.PI / 180.0);
+    var xScale = 2.0 / (leftTan + rightTan);
+    var yScale = 2.0 / (upTan + downTan);
+    out[0] = xScale;
+    out[1] = 0.0;
+    out[2] = 0.0;
+    out[3] = 0.0;
+    out[4] = 0.0;
+    out[5] = yScale;
+    out[6] = 0.0;
+    out[7] = 0.0;
+    out[8] = -((leftTan - rightTan) * xScale * 0.5);
+    out[9] = (upTan - downTan) * yScale * 0.5;
+    out[10] = far / (near - far);
+    out[11] = -1.0;
+    out[12] = 0.0;
+    out[13] = 0.0;
+    out[14] = far * near / (near - far);
+    out[15] = 0.0;
+    return out;
+}
+
+
+function testGLError(functionLastCalled) {
+
+    var lastError = gl.getError();
+
+    if (lastError != gl.NO_ERROR) {
+        alert(functionLastCalled + " failed (" + lastError + ")");
+        return false;
+    }
+
+    return true;
+}
+
+function initialiseGL(canvas) {
+    try {
+ // Try to grab the standard context. If it fails, fallback to experimental
+        gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
+        gl.viewport(0, 0, canvas.width, canvas.height);
+    }
+    catch (e) {
+    }
+
+    if (!gl) {
+        alert("Unable to initialise WebGL. Your browser may not support it");
+        return false;
+    }
+
+    return true;
+}
+
+var shaderProgram;
+
+function initialiseBuffer() {
+		
+    var vertexData = [
+		-0.5, 0.5, 0.5,		1.0, 1.0, 1.0, 0.5,		0.0, 1.0,//3
+        0.5, 0.5, 0.5,		1.0, 1.0, 1.0, 0.5,		1.0, 1.0,//1
+		0.5, 0.5, -0.5,		1.0, 1.0, 1.0, 0.5,		1.0, 1.0,//2
+				
+		-0.5, 0.5, 0.5,		1.0, 1.0, 1.0, 0.5,		0.0, 1.0,//3
+		0.5, 0.5, -0.5,		1.0, 1.0, 1.0, 0.5,		1.0, 1.0,//2
+		-0.5, 0.5, -0.5,	1.0, 1.0, 1.0, 0.5,		0.0, 1.0,//4
+		 
+		0.5, 0.5, -0.5,		0.0, 0.0, 0.0, 0.5,		1.0, 1.0,//2
+		0.5, -0.5, -0.5,	0.0, 0.0, 0.0, 0.5,		1.0, 0.0,//6
+		-0.5,-0.5,-0.5,		0.0, 0.0, 0.0, 0.5,		0.0, 0.0,//8
+		   
+		-0.5, 0.5, -0.5,	0.0, 0.0, 0.0, 0.5,		0.0, 1.0,//4
+		0.5, 0.5, -0.5,		0.0, 0.0, 0.0, 0.5,		1.0, 1.0,//2
+		-0.5,-0.5,-0.5,		0.0, 0.0, 0.0, 0.5,		0.0, 0.0,//8
+			
+		0.5, -0.5, 0.5,		1.0, 0.5, 0.0, 0.5,		0.0, 1.0,//5
+		0.5, -0.5, -0.5,	1.0, 0.5, 0.0, 0.5,		0.0, 1.0,//6
+		0.5, 0.5, -0.5,		1.0, 0.5, 0.0, 0.5,		1.0, 1.0,//2
+
+		0.5, -0.5, 0.5,		1.0, 0.5, 0.0, 0.5,		0.0, 1.0,//5
+		0.5, 0.5, -0.5,		1.0, 0.5, 0.0, 0.5,		1.0, 1.0,//2
+		0.5, 0.5, 0.5,		1.0, 0.5, 0.0, 0.5,		1.0, 1.0,//1
+				 
+		-0.5, 0.5, -0.5,	1.0, 0.0, 0.0, 0.5,		0.0, 1.0,//4
+		-0.5,-0.5, -0.5,	1.0, 0.0, 0.0, 0.5,		0.0, 0.0,//8
+		-0.5, -0.5, 0.5,	1.0, 0.0, 0.0, 0.5,		0.0, 0.0,//7
+		
+		-0.5, 0.5, 0.5,		1.0, 0.0, 0.0, 0.5,		0.0, 1.0,//3
+		-0.5, 0.5, -0.5,	1.0, 0.0, 0.0, 0.5,		0.0, 1.0,//4
+		-0.5, -0.5, 0.5,	1.0, 0.0, 0.0, 0.5,		0.0, 0.0,//7
+		
+		-0.5, -0.5, 0.5,	0.0, 0.0, 1.0, 0.5,		0.0, 0.0,//7
+		0.5, -0.5, 0.5,		0.0, 0.0, 1.0, 0.5,		1.0, 0.0,//5
+		0.5, 0.5, 0.5,		0.0, 0.0, 1.0, 0.5,		1.0, 1.0,//1
+				 
+		-0.5, -0.5, 0.5,	0.0, 0.0, 1.0, 0.5,		0.0, 0.0,//7
+		0.5, 0.5, 0.5,		0.0, 0.0, 1.0, 0.5,		1.0, 1.0,//1
+		-0.5, 0.5, 0.5,		0.0, 0.0, 1.0, 0.5,		0.0, 1.0,//3
+		
+		 0.5, -0.5, -0.5,	0.0, 1.0, 0.0, 0.5,		1.0, 0.0,//6
+		 0.5, -0.5, 0.5,	0.0, 1.0, 0.0, 0.5,		1.0, 0.0,//5
+		-0.5, -0.5, 0.5,	0.0, 1.0, 0.0, 0.5,		0.0, 0.0,//7
+		
+		-0.5,-0.5, -0.5,	0.0, 1.0, 0.0, 0.5,		0.0, 0.0,//8
+		 0.5, -0.5, -0.5,	0.0, 1.0, 0.0, 0.5,		1.0, 0.0,//6
+		-0.5, -0.5, 0.5,	0.0, 1.0, 0.0, 0.5,		0.0, 0.0,//7
+    ];
+	
+    // Generate a buffer object
+    gl.vertexBuffer = gl.createBuffer();
+    // Bind buffer as a vertex buffer so we can fill it with data
+    gl.bindBuffer(gl.ARRAY_BUFFER, gl.vertexBuffer);
+    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW);
+    return testGLError("initialiseBuffers");
+}
+
+function initialiseShaders() {
+    
+    gl.fragShader = gl.createShader(gl.FRAGMENT_SHADER);
+    gl.shaderSource(gl.fragShader, fragsource.value);
+    gl.compileShader(gl.fragShader);
+    if (!gl.getShaderParameter(gl.fragShader, gl.COMPILE_STATUS)) {
+        alert("Failed to compile the fragment shader.\n" + gl.getShaderInfoLog(gl.fragShader));
+        return false;
+    }
+
+    gl.vertexShader = gl.createShader(gl.VERTEX_SHADER);
+    gl.shaderSource(gl.vertexShader, vertexsource.value);
+    gl.compileShader(gl.vertexShader);
+    if (!gl.getShaderParameter(gl.vertexShader, gl.COMPILE_STATUS)) {
+        alert("Failed to compile the vertex shader.\n" + gl.getShaderInfoLog(gl.vertexShader));
+        return false;
+    }
+
+    gl.programObject = gl.createProgram();
+
+    // Attach the fragment and vertex shaders to it
+    gl.attachShader(gl.programObject, gl.fragShader);
+    gl.attachShader(gl.programObject, gl.vertexShader);
+
+    // Bind the custom vertex attribute "myVertex" to location 0
+    gl.bindAttribLocation(gl.programObject, 0, "myVertex");
+    gl.bindAttribLocation(gl.programObject, 1, "myColor");
+	gl.bindAttribLocation(gl.programObject, 2, "myUV");
+
+    // Link the program
+    gl.linkProgram(gl.programObject);
+
+    if (!gl.getProgramParameter(gl.programObject, gl.LINK_STATUS)) {
+        alert("Failed to link the program.\n" + gl.getProgramInfoLog(gl.programObject));
+        return false;
+    }
+
+    gl.useProgram(gl.programObject);
+
+    return testGLError("initialiseShaders");
+}
+
+
+rotValue = 0.0; 
+mainRotXValue = 0.0;
+mainRotYValue = 0.0; 
+mainRotZValue = 0.0;
+moonRotXValue = 0.0;
+moonRotYValue = 0.0;
+moonRotZValue = 0.0;
+animRotValue = 0.0;
+mainAnimRotXValue = 0.0;
+mainAnimRotYValue = 0.0;
+mainAnimRotZValue = 0.0;
+moonAnimRotXValue = 0.0;
+moonAnimRotYValue = 0.0;
+moonAnimRotZValue = 0.0;
+
+transX = 0.0;
+transY = 0.0;
+transZ = 0.0;
+frames = 1;
+
+moonTransX = 0.0;
+moonTransY = 0.0;
+moonTransZ = 0.0;
+
+function mainAnimPause()
+{
+	mainAnimRotXValue = 0.0;
+          mainAnimRotYValue = 0.0;
+	mainAnimRotZValue = 0.0;
+}
+function resetMainPos()
+{
+	transX = 0.0;
+	transY = 0.0;
+	transZ = 0.0;
+	document.getElementById("webTrX").innerHTML = "transX : " + transX.toFixed(4);
+	document.getElementById("webTrY").innerHTML = "transY : " + transY.toFixed(4);
+	document.getElementById("webTrZ").innerHTML = "transZ : " + transZ.toFixed(4);
+
+}
+function moonAnimPause()
+{
+	moonAnimRotXValue = 0.0;
+          moonAnimRotYValue = 0.0;
+	moonAnimRotZValue = 0.0;
+}
+function resetMoonPos()
+{
+	moonTransX = 0.0;
+	moonTransY = 0.0;
+	moonTransZ = 0.0;
+	document.getElementById("mwebTrX").innerHTML = "transX : " + moonTransX.toFixed(4);
+	document.getElementById("mwebTrY").innerHTML = "transY : " + moonTransY.toFixed(4);
+	document.getElementById("mwebTrZ").innerHTML = "transZ : " + moonTransZ.toFixed(4);
+
+}
+
+
+function rotXYZ(matrix, a, b, c)
+{
+    rotAxis = [1,0,0];
+    rotate$3(mov_matrix, mov_matrix, a, rotAxis);
+    rotAxis = [0,1,0];
+    rotate$3(mov_matrix, mov_matrix, b, rotAxis);
+    rotAxis = [0,0,1];
+    rotate$3(mov_matrix, mov_matrix, c, rotAxis);
+}
+
+function animRotate()
+{
+	animRotValue += 0.01;
+}
+
+function mainAnimXRotate()
+{
+	mainAnimRotXValue += 0.01;
+}
+function mainAnimYRotate()
+{
+	mainAnimRotYValue += 0.01;
+}
+function mainAnimZRotate()
+{
+	mainAnimRotZValue += 0.01;
+}
+function moonAnimXRotate()
+{
+	moonAnimRotXValue += 0.01;
+}
+function moonAnimYRotate()
+{
+	moonAnimRotYValue += 0.01;
+}
+function moonAnimZRotate()
+{
+	moonAnimRotZValue += 0.01;
+}
+function trXinc()
+{
+	transX += 0.01;
+	document.getElementById("webTrX").innerHTML = "transX : " + transX.toFixed(4);
+}
+function trYinc()
+{
+	transY += 0.01;
+	document.getElementById("webTrY").innerHTML = "transY : " + transY.toFixed(4);
+}
+function trZinc()
+{
+	transZ += 0.01;
+	document.getElementById("webTrZ").innerHTML = "transZ : " + transZ.toFixed(4);
+}
+function trXdec()
+{
+	transX -= 0.01;
+	document.getElementById("webTrX").innerHTML = "transX : " + transX.toFixed(4);
+}
+function trYdec()
+{
+	transY -= 0.01;
+	document.getElementById("webTrY").innerHTML = "transY : " + transY.toFixed(4);
+}
+function trZdec()
+{
+	transZ -= 0.01;
+	document.getElementById("webTrZ").innerHTML = "transZ : " + transZ.toFixed(4);
+}
+function mtrXinc()
+{
+	moonTransX += 0.01;
+	document.getElementById("mwebTrX").innerHTML = "transX : " + moonTransX.toFixed(4);
+}
+function mtrYinc()
+{
+	moonTransY += 0.01;
+	document.getElementById("mwebTrY").innerHTML = "transY : " + moonTransY.toFixed(4);
+}
+function mtrZinc()
+{
+	moonTransZ += 0.01;
+	document.getElementById("mwebTrZ").innerHTML = "transZ : " + moonTransZ.toFixed(4);
+}
+function mtrXdec()
+{
+	moonTransX -= 0.01;
+	document.getElementById("mwebTrX").innerHTML = "transX : " + moonTransX.toFixed(4);
+}
+function mtrYdec()
+{
+	moonTransY -= 0.01;
+	document.getElementById("mwebTrY").innerHTML = "transY : " + moonTransY.toFixed(4);
+}
+function mtrZdec()
+{
+	moonTransZ -= 0.01;
+	document.getElementById("mwebTrZ").innerHTML = "transZ : " + moonTransZ.toFixed(4);
+}
+
+
+//mouse events
+var windowHalfX=0
+var beforeLoc = [0, 0];
+function onDocumentMouseDown(event){
+    event.preventDefault();                                                
+    document.addEventListener('mousemove',onDocumentMouseMove, false );
+    document.addEventListener('mouseup', onDocumentMouseUp, false);
+    document.addEventListener('mouseout', onDocumentMouseOut, false);
+    beforeLoc = [event.clientX - windowHalfX, event.clientY - windowHalfX];
+}
+
+function onDocumentMouseMove(event){
+    mouseLoc = [event.clientX-windowHalfX, event.clientY-windowHalfX];
+    //window.LookAtCamera(view_matrix, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+    rotate$3(view_matrix, view_matrix, (mouseLoc[0]-beforeLoc[0])*0.01, [0, 1, 0]);
+    rotate$3(view_matrix, view_matrix, (mouseLoc[1]-beforeLoc[1])*0.01, [1, 0, 0]);
+    for(var i = 0; i < 16; i++){
+        vm_value[i].value = view_matrix[i];
+    }
+    beforeLoc = mouseLoc
+}
+
+//remove event listener when drag out or end drag
+function onDocumentMouseUp(event){                                            
+    document.removeEventListener( 'mousemove', onDocumentMouseMove, false ); 
+    document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
+    document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
+}
+
+function onDocumentMouseOut(event){
+    document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
+    document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
+    document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
+}
+
+//render func
+function renderScene() {  
+    frames += 1 ;
+
+    var Pmatrix = gl.getUniformLocation(gl.programObject, "Pmatrix");
+    var Vmatrix = gl.getUniformLocation(gl.programObject, "Vmatrix");
+    var Mmatrix = gl.getUniformLocation(gl.programObject, "Mmatrix");
+
+    //auto calculate proj_matrix
+    if(is_cal.checked == true){
+        var tmp = new Array();
+        perspectiveFromFieldOfView(tmp, [fov_up.value, fov_down.value, fov_left.value, fov_right.value], near.value, far.value);
+        for(var i = 0; i < 16; i++)
+            pm_value[i].value = tmp[i];
+    }
+
+    //get matrix value from table
+    for(var i = 0; i < 16; i++){
+        view_matrix[i] = vm_value[i].value;
+        proj_matrix[i] = pm_value[i].value;
+    }
+
+    gl.uniformMatrix4fv(Pmatrix, false, proj_matrix);
+    gl.uniformMatrix4fv(Vmatrix, false, view_matrix);
+
+
+    if (!testGLError("gl.uniformMatrix4fv")) {
+        return false;
+    }
+
+    gl.enableVertexAttribArray(0);
+    gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 36, 0);
+    gl.enableVertexAttribArray(1);
+    gl.vertexAttribPointer(1, 4, gl.FLOAT, gl.FALSE, 36, 12);
+    gl.enableVertexAttribArray(2);
+    gl.vertexAttribPointer(2, 2, gl.FLOAT, gl.FALSE, 36, 28);
+
+
+    if (!testGLError("gl.vertexAttribPointer")) {
+        return false;
+    }
+    gl.enable(gl.DEPTH_TEST);
+    gl.depthFunc(gl.LEQUAL); 
+    // gl.enable(gl.CULL_FACE);
+    gl.enable(gl.BLEND);
+    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+    gl.blendEquation(gl.FUNC_ADD);
+
+    gl.clearColor(0.6, 0.8, 1.0, 1.0);
+    gl.clearDepth(1.0); 
+    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+
+
+    //main square
+    if(is_pause.checked == true){
+        for(var i = 0; i < 16; i++)
+            mov_matrix[i] = mm_value[i].value;
+    }
+    if(is_pause.checked == false){
+        idMatrix(mov_matrix);
+        for(var i = 0; i < 16; i++)
+            mm_value[i].value = mov_matrix[i];
+        rotXYZ(mov_matrix, mainRotXValue, mainRotYValue, mainRotZValue);
+        translate$2(mov_matrix, mov_matrix, [transX, transY, transZ]);
+        for(var i = 0; i < 16; i++)
+            mm_value[i].value = mov_matrix[i];
+    }
+    
+    gl.uniformMatrix4fv(Mmatrix, false, mov_matrix);
+    gl.drawArrays(gl.TRIANGLES, 0, 36);
+    
+    //----------------------------------------
+    //small square
+    var tmp = mov_matrix.slice();
+    translate$2(mov_matrix, mov_matrix, [.75, .75, .75]); 
+    scale$3(mov_matrix, mov_matrix, [0.25, 0.25, 0.25]);
+    rotXYZ(mov_matrix, moonRotXValue, moonRotYValue, moonRotZValue);
+    translate$2(mov_matrix, mov_matrix, [moonTransX, moonTransY, moonTransZ]);
+    gl.uniformMatrix4fv(Mmatrix, false, mov_matrix);
+    gl.drawArrays(gl.TRIANGLES, 0, 36);
+    mov_matrix = tmp.slice();
+
+    var tmp = mov_matrix.slice();
+    translate$2(mov_matrix, mov_matrix, [.75, .75, -.75]); 
+    scale$3(mov_matrix, mov_matrix, [0.25, 0.25, 0.25]);
+    rotXYZ(mov_matrix, moonRotXValue, moonRotYValue, moonRotZValue);
+    translate$2(mov_matrix, mov_matrix, [moonTransX, moonTransY, moonTransZ]);
+    gl.uniformMatrix4fv(Mmatrix, false, mov_matrix);
+    gl.drawArrays(gl.TRIANGLES, 0, 36);
+    mov_matrix = tmp.slice();
+
+    var tmp = mov_matrix.slice();
+    translate$2(mov_matrix, mov_matrix, [-.75, .75, .75]); 
+    scale$3(mov_matrix, mov_matrix, [0.25, 0.25, 0.25]);
+    rotXYZ(mov_matrix, moonRotXValue, moonRotYValue, moonRotZValue);
+    translate$2(mov_matrix, mov_matrix, [moonTransX, moonTransY, moonTransZ]);
+    gl.uniformMatrix4fv(Mmatrix, false, mov_matrix);
+    gl.drawArrays(gl.TRIANGLES, 0, 36);
+    mov_matrix = tmp.slice();
+
+    var tmp = mov_matrix.slice();
+    translate$2(mov_matrix, mov_matrix, [-.75, .75, -.75]); 
+    scale$3(mov_matrix, mov_matrix, [0.25, 0.25, 0.25]);
+    rotXYZ(mov_matrix, moonRotXValue, moonRotYValue, moonRotZValue);
+    translate$2(mov_matrix, mov_matrix, [moonTransX, moonTransY, moonTransZ]);
+    gl.uniformMatrix4fv(Mmatrix, false, mov_matrix);
+    gl.drawArrays(gl.TRIANGLES, 0, 36);
+    mov_matrix = tmp.slice();
+    //end small square
+    //--------------------------------------------------
+
+    //rotate value
+    mainRotXValue += mainAnimRotXValue;
+    mainRotYValue += mainAnimRotYValue; 
+    mainRotZValue += mainAnimRotZValue;
+    moonRotXValue += moonAnimRotXValue; 
+    moonRotYValue += moonAnimRotYValue; 
+    moonRotZValue += moonAnimRotZValue;
+    rotValue += animRotValue; 
+    //end rotate value
+
+
+    if (!testGLError("gl.drawArrays")) {
+        return false;
+    }
+
+    return true;
+}
+
+
+
+//---------------------------------------
+// main function
+function main() {
+
+    var canvas = document.getElementById("maincanvas");
+    fragsource = document.getElementById("fragmentSource");
+    vertexsource = document.getElementById("vertexSource");
+    fov_up = document.getElementById("fov_up");
+    fov_down = document.getElementById("fov_down");
+    fov_left = document.getElementById("fov_left");
+    fov_right = document.getElementById("fov_right");
+    near = document.getElementById("near");
+    far = document.getElementById("far");
+    is_cal = document.getElementById("is_cal");
+    is_pause = document.getElementById("is_pause");
+    timer = document.getElementById("timer");
+    canvas.addEventListener('mousedown', onDocumentMouseDown, false);
+    
+    for (var i=0;i<16;i++){
+        vm_value[i] = document.getElementById("vmatrix"+i);
+        pm_value[i] = document.getElementById("pmatrix"+i);
+        mm_value[i] = document.getElementById("mmatrix"+i);
+    }
+    
+    console.log("Start");
+
+    if (!initialiseGL(canvas)) {
+        return;
+    }
+
+    if (!initialiseBuffer()) {
+        return;
+    }
+
+    if (!initialiseShaders()) {
+        return;
+    }
+
+
+    /*
+    // Render loop
+    // 함수 renderLoop함수는 정의와 동시에 실행이 되며
+    // 타이머 값이 0이하일 경우 랜더링을 정지한다.(0.5초만큼 대기 후 자기자신을 호출)
+    // 타이머 값이 0보다 클경우 renderScene을 통해 랜더링 후 타이머 값만큼 대기 후
+    // 자기자신을 호출한다. window.requestAnimationFrame은 실행 최적화 
+    */
+    (function renderLoop(param) {
+        if(timer.value <= 0){
+            window.setTimeout(renderLoop,500);
+        }
+        else if (renderScene()) {
+            
+            window.setTimeout(window.requestAnimationFrame, timer.value * 1000, renderLoop);
+        }
+    })();
+    
+}
+//end main
+//---------------------------------------------
+function apply()
+{
+    main();
+
+}