User:Lbattich/canvas experiments: Difference between revisions
No edit summary |
No edit summary |
||
(7 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
The idea is to create a webpage that would generate abstract images, inspired in the proun/suprematist works of El Lissitzky. such as this one: | The idea is to create a webpage that would generate abstract images, inspired in the proun/suprematist works of El Lissitzky. such as this one: | ||
[[File:220px-A_Prounen_by_El_Lissitzky_c.1925.jpg]] | |||
The tests are pretty far from that goal yet, but hey, the goal is not quite the important here perhaps... | |||
==other tests== | |||
* [http://lucasbattich.com/tests/canvas1.html prototype 1] | |||
* [http://lucasbattich.com/tests/canvas2.html prototype 2] | |||
== test 3 == | |||
* [http://lucasbattich.com/tests/proun03.html Random shapes and what-may Xperiment numero3] | |||
Not quite related to Lissitzky's Prouns anymore... :) | |||
Move mouse from left to right to change speed. Press 'p' key to save as jpg image. | |||
<source lang="html4strict"> | |||
<!DOCTYPE html> | |||
<!-- | |||
_ | |||
| |_ _ ___ __ _ ___ | |||
| | | | |/ __/ _` / __| | |||
| | |_| | (_| (_| \__ \ | |||
|_|\__,_|\___\__,_|___/ | |||
_ _ _ _ _ | |||
| |__ __ _| |_| |_(_) ___| |__ | |||
| '_ \ / _` | __| __| |/ __| '_ \ | |||
| |_) | (_| | |_| |_| | (__| | | | | |||
|_.__/ \__,_|\__|\__|_|\___|_| |_| | |||
PROUN GENERATOR - PROTOTYPE | |||
by LUCAS BATTICH, 2014 | |||
--> | |||
<html> | |||
<head> | |||
<script src="jquery-1.11.1.min.js"></script> | |||
<meta content="text/html; charset=utf-8" http-equiv="content-type"> | |||
<meta name="author" content="Lucas Battich"> | |||
<meta name="description" content="PROUN GENERATOR - PROTOTYPE by LUCAS BATTICH, 2014"> | |||
<title>PROUN GENERATOR - PROTOTYPE</title> | |||
</head> | |||
<body style="text-align:center; background-color:black"> | |||
<canvas id="proun" onclick="start()"> | |||
Aw noes! Your browser does not support the HTML5 canvas tag - try using | |||
Chrome or Safari. Tech up! </canvas> | |||
<script language="JavaScript"> | |||
var x=document.getElementById("proun"); //declare global var x for canvas | |||
var position | |||
var on=0; | |||
var ctx=x.getContext("2d"); | |||
//x.width=window.innerWidth-30; | |||
//x.height=window.innerHeight-30; | |||
//window.onload = function(){start();setInterval(function(){choose()},1000)}; | |||
start(); | |||
window.onkeydown = function(event) { | |||
var e = event.keyCode; | |||
if (e==80 /*p*/){save();} | |||
} | |||
$(x).mousemove(function(e){ | |||
position = Math.round(100*(e.clientX/x.width)); | |||
if (on==0){ | |||
on=1; | |||
choose(); | |||
} | |||
//console.log("move",e.clientX,e.clientY,position,on); | |||
}) | |||
function start() | |||
{ | |||
x.width=window.innerWidth-30; | |||
x.height=window.innerHeight-30; | |||
ctx.fillStyle=colourme()+"1)"; //first colour | |||
ctx.fillRect(0,0,x.width,x.height); | |||
ctx.fill(); | |||
on=0; | |||
} | |||
//choose btw different shapes | |||
function choose(time) { | |||
var time = position*10; | |||
var numb=Math.floor(Math.random()*5); | |||
if (numb==0){four()} | |||
else if (numb==1){multi()} | |||
else if (numb==2){circle()} | |||
else if (numb==3){line()} | |||
else if (numb==4){curve()}; | |||
if (on==1){ | |||
setTimeout(function(){choose()},time); | |||
//console.log("move",e.clientX,e.clientY,position,on); | |||
} | |||
} | |||
//functions: | |||
// circle: | |||
function circle() | |||
{ | |||
var xc,yc,radio; | |||
yc=Math.floor((x.height+1)*Math.random()); | |||
xc=Math.floor((x.width+1)*Math.random()); | |||
radio=Math.floor((200)*Math.random()); | |||
ctx.beginPath(); | |||
ctx.arc(xc,yc,radio,0,2*Math.PI); | |||
var grd=ctx.createLinearGradient(xc-radio,yc-radio,xc+radio,yc+radio); | |||
grd.addColorStop(0,colourme()+"1)"); | |||
grd.addColorStop(1,colourme()+"1)"); | |||
ctx.strokeStyle=grd; | |||
ctx.lineWidth=Math.floor((20)*Math.random()); | |||
ctx.stroke(); | |||
} | |||
//create a 4 sided shape, filled with gradient | |||
function four() | |||
{ | |||
var y1=Math.floor((x.height+1)*Math.random()); | |||
var x1=Math.floor((x.width+1)*Math.random()); | |||
ctx.beginPath(); | |||
ctx.moveTo(x1,y1); | |||
for (i=0;i<4;i++){ | |||
y1=Math.floor((x.height+1)*Math.random()); | |||
x1=Math.floor((x.width+1)*Math.random()); | |||
ctx.lineTo(x1,y1); | |||
} | |||
ctx.closePath(); | |||
var grd=ctx.createLinearGradient(x.width/2,y1,x1,x.height); | |||
grd.addColorStop(0,colourme()+"1)"); | |||
grd.addColorStop(1,colourme()+"1)"); | |||
ctx.fillStyle=grd; | |||
ctx.fill(); | |||
} | |||
//make a curve | |||
function curve() | |||
{ | |||
var yc=Math.floor((x.height+1)*Math.random()); | |||
var xc=Math.floor((x.width+1)*Math.random()); | |||
var radio=Math.floor((200)*Math.random()); | |||
var angle1=4*Math.random(); | |||
var angle2=4*Math.random(); | |||
console.log(yc,xc,angle1,angle2); | |||
ctx.beginPath(); | |||
ctx.arc(xc,yc,radio,angle1,angle2); | |||
var grd=ctx.createLinearGradient(xc-radio,yc+radio,xc+radio,yc-radio); | |||
grd.addColorStop(0,colourme()+"1)"); | |||
grd.addColorStop(1,colourme()+"1)"); | |||
ctx.strokeStyle=grd; | |||
ctx.lineWidth=Math.floor((30)*Math.random()); | |||
ctx.stroke(); | |||
} | |||
//line | |||
function line() | |||
{ | |||
var y1=Math.floor((x.height+1)*Math.random()); | |||
var x1=Math.floor((x.width+1)*Math.random()); | |||
var y2=Math.floor((x.height+1)*Math.random()); | |||
var x2=Math.floor((x.width+1)*Math.random()); | |||
ctx.beginPath(); | |||
ctx.moveTo(x1,y1); | |||
ctx.lineTo(x2,y2); | |||
ctx.closePath(); | |||
var grd=ctx.createLinearGradient(x1,y1,x2,y2); | |||
grd.addColorStop(0,colourme()+"1)"); | |||
grd.addColorStop(1,colourme()+"1)"); | |||
ctx.strokeStyle=grd; | |||
ctx.lineWidth=Math.floor((50)*Math.random()); | |||
ctx.stroke(); | |||
} | |||
//create a multi sided shape, filled with gradient | |||
function multi() | |||
{ | |||
var y1=Math.floor((x.height+1)*Math.random()); | |||
var x1=Math.floor((x.width+1)*Math.random()); | |||
ctx.beginPath(); | |||
ctx.moveTo(x1,y1); | |||
for (i=0;i<10;i++){ | |||
y1=Math.floor((x.height+1)*Math.random()); | |||
x1=Math.floor((x.width+1)*Math.random()); | |||
ctx.lineTo(x1,y1); | |||
} | |||
ctx.closePath(); | |||
var grd=ctx.createLinearGradient(x.width/2,y1,x1,x.height); | |||
grd.addColorStop(0,colourme()+"1)"); | |||
grd.addColorStop(1,colourme()+"1)"); | |||
ctx.fillStyle=grd; | |||
ctx.fill(); | |||
} | |||
//choose a random colour | |||
function colourme() | |||
{ | |||
var a = Math.floor(256*Math.random()); | |||
var b = Math.floor(256*Math.random()); | |||
var c = Math.floor(256*Math.random()); | |||
var colour = "rgba("+a+","+b+","+c+","; | |||
return colour; | |||
} | |||
//save as jpg when key 'p' is pressed | |||
function save() | |||
{ | |||
var d = x.toDataURL("image/jpeg"); | |||
var w = window.open(); | |||
var link = w.document.createElement('a'); | |||
link.href = d | |||
link.download="proun.jpg"; | |||
if (document.createEvent) { | |||
var e = document.createEvent('MouseEvents'); | |||
e.initEvent('click' ,true ,true); | |||
link.dispatchEvent(e); | |||
return true; | |||
} | |||
} | |||
</script> | |||
</body> | |||
</html> | |||
</source> | |||
== test 2== | |||
* [http://lucasbattich.com/tests/proun02.html Proun experiment 2] | |||
== test 1 == | == test 1 == | ||
* [http://lucasbattich.com/tests/proun01.html Proun experiment 1] | * [http://lucasbattich.com/tests/proun01.html Proun experiment 1] | ||
The page displays a shape every second, either 4-seides shape or a circle (position, sizes and colours are randomly decided by the code). | |||
Click the page to restart. Press the "p" key to save the current state as a jpg image. | |||
< | <source lang="html4strict"> | ||
<!DOCTYPE html> | |||
<!-- | |||
_ | |||
| |_ _ ___ __ _ ___ | |||
| | | | |/ __/ _` / __| | |||
| | |_| | (_| (_| \__ \ | |||
|_|\__,_|\___\__,_|___/ | |||
_ _ _ _ _ | |||
| |__ __ _| |_| |_(_) ___| |__ | |||
| '_ \ / _` | __| __| |/ __| '_ \ | |||
| |_) | (_| | |_| |_| | (__| | | | | |||
|_.__/ \__,_|\__|\__|_|\___|_| |_| | |||
PROUN GENERATOR - PROTOTYPE | |||
by LUCAS BATTICH, 2014 | |||
--> | |||
<html> | |||
<head> | |||
<meta content="text/html; charset=utf-8" http-equiv="content-type"> | |||
<meta name="author" content="Lucas Battich"> | |||
<meta name="description" content="PROUN GENERATOR - PROTOTYPE by LUCAS BATTICH, 2014"> | |||
<title>PROUN GENERATOR - PROTOTYPE</title> | |||
</head> | |||
<body style="text-align:center; background-color:black"> | |||
<canvas id="proun" onclick="start()"> | |||
Aw noes! Your browser does not support the HTML5 canvas tag - try using | |||
Chrome or Safari. Tech up! </canvas> | |||
<p id="d"></p> | |||
<script language="JavaScript"> | |||
var x=document.getElementById("proun"); //declare global var x for canvas | var x=document.getElementById("proun"); //declare global var x for canvas | ||
var y1,y2,y3,x1,m1; | var y1,y2,y3,x1,m1; | ||
var ctx=x.getContext("2d"); | var ctx=x.getContext("2d"); | ||
window.onload = function(){start();setInterval(function(){choose()}, | window.onload = function(){start();setInterval(function(){choose()},1000)}; | ||
//window.onload = function(){start()}; | |||
window.onkeydown = function(event) { | |||
var e = event.keyCode; | |||
if (e==80 /*p*/){save();} | |||
} | |||
function start() | function start() | ||
{ | { | ||
Line 27: | Line 300: | ||
ctx.fillRect(0,0,x.width,x.height); | ctx.fillRect(0,0,x.width,x.height); | ||
ctx.fill(); | ctx.fill(); | ||
choose(); | |||
} | } | ||
//choose btw different shapes | //choose btw different shapes | ||
function choose() { | function choose() { | ||
var numb=Math.floor(Math.random()*4); | var numb=Math.floor(Math.random()*4); | ||
if (numb==0){ | if (numb==0){circle()} | ||
else if (numb==1){ | else if (numb==1){circle()} | ||
else if (numb==2){four()} | else if (numb==2){four()} | ||
else if (numb==3){four()} | else if (numb==3){four()} | ||
} | } | ||
//functions: | //functions: | ||
//create a 4 sided shape | |||
// circle: | |||
function circle() | |||
{ | |||
var xc,yc,radio; | |||
yc=Math.floor((x.height+1)*Math.random()); | |||
xc=Math.floor((x.width+1)*Math.random()); | |||
radio=Math.floor((200)*Math.random()); | |||
ctx.beginPath(); | |||
ctx.arc(xc,yc,radio,0,2*Math.PI); | |||
ctx.stroke(); | |||
} | |||
//create a 4 sided shape, filled with gradient | |||
function four() | function four() | ||
{ | { | ||
Line 50: | Line 334: | ||
ctx.beginPath(); | ctx.beginPath(); | ||
ctx.moveTo(x4,y4); | ctx.moveTo(x4,y4); | ||
y4=Math.floor((x.height+1)*Math.random()); | y4=Math.floor((x.height+1)*Math.random()); | ||
x4=Math.floor((x.width+1)*Math.random()); | x4=Math.floor((x.width+1)*Math.random()); | ||
Line 69: | Line 350: | ||
ctx.fill(); | ctx.fill(); | ||
} | } | ||
//choose a random colour | |||
// | |||
function colourme() | function colourme() | ||
{ | { | ||
Line 80: | Line 360: | ||
return colour; | return colour; | ||
} | } | ||
</ | |||
//save as jpg when key 'p' is pressed | |||
function save() | |||
{ | |||
var d = x.toDataURL("image/jpeg"); | |||
var w = window.open(); | |||
var link = w.document.createElement('a'); | |||
link.href = d | |||
link.download="proun.jpg"; | |||
if (document.createEvent) { | |||
var e = document.createEvent('MouseEvents'); | |||
e.initEvent('click' ,true ,true); | |||
link.dispatchEvent(e); | |||
return true; | |||
} | |||
} | |||
</script> | |||
</body> | |||
</html> | |||
</source> |
Latest revision as of 11:05, 7 October 2014
The idea is to create a webpage that would generate abstract images, inspired in the proun/suprematist works of El Lissitzky. such as this one:
The tests are pretty far from that goal yet, but hey, the goal is not quite the important here perhaps...
other tests
test 3
Not quite related to Lissitzky's Prouns anymore... :)
Move mouse from left to right to change speed. Press 'p' key to save as jpg image.
<!DOCTYPE html>
<!--
_
| |_ _ ___ __ _ ___
| | | | |/ __/ _` / __|
| | |_| | (_| (_| \__ \
|_|\__,_|\___\__,_|___/
_ _ _ _ _
| |__ __ _| |_| |_(_) ___| |__
| '_ \ / _` | __| __| |/ __| '_ \
| |_) | (_| | |_| |_| | (__| | | |
|_.__/ \__,_|\__|\__|_|\___|_| |_|
PROUN GENERATOR - PROTOTYPE
by LUCAS BATTICH, 2014
-->
<html>
<head>
<script src="jquery-1.11.1.min.js"></script>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<meta name="author" content="Lucas Battich">
<meta name="description" content="PROUN GENERATOR - PROTOTYPE by LUCAS BATTICH, 2014">
<title>PROUN GENERATOR - PROTOTYPE</title>
</head>
<body style="text-align:center; background-color:black">
<canvas id="proun" onclick="start()">
Aw noes! Your browser does not support the HTML5 canvas tag - try using
Chrome or Safari. Tech up! </canvas>
<script language="JavaScript">
var x=document.getElementById("proun"); //declare global var x for canvas
var position
var on=0;
var ctx=x.getContext("2d");
//x.width=window.innerWidth-30;
//x.height=window.innerHeight-30;
//window.onload = function(){start();setInterval(function(){choose()},1000)};
start();
window.onkeydown = function(event) {
var e = event.keyCode;
if (e==80 /*p*/){save();}
}
$(x).mousemove(function(e){
position = Math.round(100*(e.clientX/x.width));
if (on==0){
on=1;
choose();
}
//console.log("move",e.clientX,e.clientY,position,on);
})
function start()
{
x.width=window.innerWidth-30;
x.height=window.innerHeight-30;
ctx.fillStyle=colourme()+"1)"; //first colour
ctx.fillRect(0,0,x.width,x.height);
ctx.fill();
on=0;
}
//choose btw different shapes
function choose(time) {
var time = position*10;
var numb=Math.floor(Math.random()*5);
if (numb==0){four()}
else if (numb==1){multi()}
else if (numb==2){circle()}
else if (numb==3){line()}
else if (numb==4){curve()};
if (on==1){
setTimeout(function(){choose()},time);
//console.log("move",e.clientX,e.clientY,position,on);
}
}
//functions:
// circle:
function circle()
{
var xc,yc,radio;
yc=Math.floor((x.height+1)*Math.random());
xc=Math.floor((x.width+1)*Math.random());
radio=Math.floor((200)*Math.random());
ctx.beginPath();
ctx.arc(xc,yc,radio,0,2*Math.PI);
var grd=ctx.createLinearGradient(xc-radio,yc-radio,xc+radio,yc+radio);
grd.addColorStop(0,colourme()+"1)");
grd.addColorStop(1,colourme()+"1)");
ctx.strokeStyle=grd;
ctx.lineWidth=Math.floor((20)*Math.random());
ctx.stroke();
}
//create a 4 sided shape, filled with gradient
function four()
{
var y1=Math.floor((x.height+1)*Math.random());
var x1=Math.floor((x.width+1)*Math.random());
ctx.beginPath();
ctx.moveTo(x1,y1);
for (i=0;i<4;i++){
y1=Math.floor((x.height+1)*Math.random());
x1=Math.floor((x.width+1)*Math.random());
ctx.lineTo(x1,y1);
}
ctx.closePath();
var grd=ctx.createLinearGradient(x.width/2,y1,x1,x.height);
grd.addColorStop(0,colourme()+"1)");
grd.addColorStop(1,colourme()+"1)");
ctx.fillStyle=grd;
ctx.fill();
}
//make a curve
function curve()
{
var yc=Math.floor((x.height+1)*Math.random());
var xc=Math.floor((x.width+1)*Math.random());
var radio=Math.floor((200)*Math.random());
var angle1=4*Math.random();
var angle2=4*Math.random();
console.log(yc,xc,angle1,angle2);
ctx.beginPath();
ctx.arc(xc,yc,radio,angle1,angle2);
var grd=ctx.createLinearGradient(xc-radio,yc+radio,xc+radio,yc-radio);
grd.addColorStop(0,colourme()+"1)");
grd.addColorStop(1,colourme()+"1)");
ctx.strokeStyle=grd;
ctx.lineWidth=Math.floor((30)*Math.random());
ctx.stroke();
}
//line
function line()
{
var y1=Math.floor((x.height+1)*Math.random());
var x1=Math.floor((x.width+1)*Math.random());
var y2=Math.floor((x.height+1)*Math.random());
var x2=Math.floor((x.width+1)*Math.random());
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.closePath();
var grd=ctx.createLinearGradient(x1,y1,x2,y2);
grd.addColorStop(0,colourme()+"1)");
grd.addColorStop(1,colourme()+"1)");
ctx.strokeStyle=grd;
ctx.lineWidth=Math.floor((50)*Math.random());
ctx.stroke();
}
//create a multi sided shape, filled with gradient
function multi()
{
var y1=Math.floor((x.height+1)*Math.random());
var x1=Math.floor((x.width+1)*Math.random());
ctx.beginPath();
ctx.moveTo(x1,y1);
for (i=0;i<10;i++){
y1=Math.floor((x.height+1)*Math.random());
x1=Math.floor((x.width+1)*Math.random());
ctx.lineTo(x1,y1);
}
ctx.closePath();
var grd=ctx.createLinearGradient(x.width/2,y1,x1,x.height);
grd.addColorStop(0,colourme()+"1)");
grd.addColorStop(1,colourme()+"1)");
ctx.fillStyle=grd;
ctx.fill();
}
//choose a random colour
function colourme()
{
var a = Math.floor(256*Math.random());
var b = Math.floor(256*Math.random());
var c = Math.floor(256*Math.random());
var colour = "rgba("+a+","+b+","+c+",";
return colour;
}
//save as jpg when key 'p' is pressed
function save()
{
var d = x.toDataURL("image/jpeg");
var w = window.open();
var link = w.document.createElement('a');
link.href = d
link.download="proun.jpg";
if (document.createEvent) {
var e = document.createEvent('MouseEvents');
e.initEvent('click' ,true ,true);
link.dispatchEvent(e);
return true;
}
}
</script>
</body>
</html>
test 2
test 1
The page displays a shape every second, either 4-seides shape or a circle (position, sizes and colours are randomly decided by the code). Click the page to restart. Press the "p" key to save the current state as a jpg image.
<!DOCTYPE html>
<!--
_
| |_ _ ___ __ _ ___
| | | | |/ __/ _` / __|
| | |_| | (_| (_| \__ \
|_|\__,_|\___\__,_|___/
_ _ _ _ _
| |__ __ _| |_| |_(_) ___| |__
| '_ \ / _` | __| __| |/ __| '_ \
| |_) | (_| | |_| |_| | (__| | | |
|_.__/ \__,_|\__|\__|_|\___|_| |_|
PROUN GENERATOR - PROTOTYPE
by LUCAS BATTICH, 2014
-->
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<meta name="author" content="Lucas Battich">
<meta name="description" content="PROUN GENERATOR - PROTOTYPE by LUCAS BATTICH, 2014">
<title>PROUN GENERATOR - PROTOTYPE</title>
</head>
<body style="text-align:center; background-color:black">
<canvas id="proun" onclick="start()">
Aw noes! Your browser does not support the HTML5 canvas tag - try using
Chrome or Safari. Tech up! </canvas>
<p id="d"></p>
<script language="JavaScript">
var x=document.getElementById("proun"); //declare global var x for canvas
var y1,y2,y3,x1,m1;
var ctx=x.getContext("2d");
window.onload = function(){start();setInterval(function(){choose()},1000)};
//window.onload = function(){start()};
window.onkeydown = function(event) {
var e = event.keyCode;
if (e==80 /*p*/){save();}
}
function start()
{
x.width=window.innerWidth-30;
x.height=window.innerHeight-30;
ctx.fillStyle=colourme()+"1)"; //first colour
ctx.fillRect(0,0,x.width,x.height);
ctx.fill();
choose();
}
//choose btw different shapes
function choose() {
var numb=Math.floor(Math.random()*4);
if (numb==0){circle()}
else if (numb==1){circle()}
else if (numb==2){four()}
else if (numb==3){four()}
}
//functions:
// circle:
function circle()
{
var xc,yc,radio;
yc=Math.floor((x.height+1)*Math.random());
xc=Math.floor((x.width+1)*Math.random());
radio=Math.floor((200)*Math.random());
ctx.beginPath();
ctx.arc(xc,yc,radio,0,2*Math.PI);
ctx.stroke();
}
//create a 4 sided shape, filled with gradient
function four()
{
var x4,y4;
y4=Math.floor((x.height+1)*Math.random());
x4=Math.floor((x.width+1)*Math.random());
ctx.beginPath();
ctx.moveTo(x4,y4);
y4=Math.floor((x.height+1)*Math.random());
x4=Math.floor((x.width+1)*Math.random());
ctx.lineTo(x4,y4);
y4=Math.floor((x.height+1)*Math.random());
x4=Math.floor((x.width+1)*Math.random());
ctx.lineTo(x4,y4);
y4=Math.floor((x.height+1)*Math.random());
x4=Math.floor((x.width+1)*Math.random());
ctx.lineTo(x4,y4);
ctx.closePath();
var grd=ctx.createLinearGradient(x.width/2,y4,x4,x.height);
grd.addColorStop(0,colourme()+"1)");
grd.addColorStop(1,colourme()+"1)");
ctx.fillStyle=grd;
ctx.fill();
}
//choose a random colour
function colourme()
{
var a = Math.floor(256*Math.random());
var b = Math.floor(256*Math.random());
var c = Math.floor(256*Math.random());
var colour = "rgba("+a+","+b+","+c+",";
return colour;
}
//save as jpg when key 'p' is pressed
function save()
{
var d = x.toDataURL("image/jpeg");
var w = window.open();
var link = w.document.createElement('a');
link.href = d
link.download="proun.jpg";
if (document.createEvent) {
var e = document.createEvent('MouseEvents');
e.initEvent('click' ,true ,true);
link.dispatchEvent(e);
return true;
}
}
</script>
</body>
</html>