1458 lines
37 KiB
HTML
1458 lines
37 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<title>Chains</title>
|
|
<meta charset='utf-8' />
|
|
<link rel="shortcut icon" href="/HTML/PIC/chains.png" type="image/png">
|
|
</head>
|
|
<body>
|
|
|
|
<script>
|
|
window.RUN_CLIENT=1;
|
|
window.RUN_SERVER=0;
|
|
if(typeof global === 'object')
|
|
{
|
|
global.RUN_CLIENT=1;
|
|
global.RUN_SERVER=0;
|
|
}
|
|
</script>
|
|
|
|
<script type="text/javascript" src="/HTML/JS/coinlib.js"></script>
|
|
<script type="text/javascript" src="../HTML/JS/client.js"></script>
|
|
|
|
<script type="text/javascript">
|
|
var sessionid;
|
|
var SaveIdArr=["idUseSound"];
|
|
function SetNewSession(cursessionid)
|
|
{
|
|
sessionid=cursessionid;
|
|
}
|
|
|
|
function LoadValues()
|
|
{
|
|
LoadValuesByArr(SaveIdArr);
|
|
}
|
|
function SaveValues()
|
|
{
|
|
SaveValuesByArr(SaveIdArr);
|
|
}
|
|
|
|
|
|
window.onload=function()
|
|
{
|
|
LoadValues();
|
|
|
|
SetPause(0);
|
|
setInterval(UpdateData,500);
|
|
|
|
|
|
|
|
var obj = document.getElementById("BlockChainGraph");
|
|
obj.addEventListener('mousedown', function(event)
|
|
{
|
|
|
|
event.preventDefault();
|
|
var mouse=getMouse(obj,event);
|
|
DoBlockInfo(mouse.x,mouse.y, event);
|
|
}, false);
|
|
obj.addEventListener('mouseup', function(event)
|
|
{
|
|
|
|
event.preventDefault();
|
|
var mouse=getMouse(obj,event);
|
|
DoBlockInfoUp(mouse.x,mouse.y, event);
|
|
}, false);
|
|
|
|
|
|
obj.addEventListener('dblclick', function(event)
|
|
{
|
|
|
|
event.preventDefault();
|
|
var mouse=getMouse(obj,event);
|
|
DoDblClick(mouse.x,mouse.y, event);
|
|
}, false);
|
|
|
|
//InitViewBlock();
|
|
InitMoveBlock();
|
|
|
|
//COMMON MOUSE MOVING
|
|
window.onmousemove = function(event)
|
|
{
|
|
moveBlock(event);
|
|
}
|
|
|
|
|
|
window.onkeydown = function (e)
|
|
{
|
|
if(e.keyCode===27)
|
|
{
|
|
window.close();
|
|
}
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var Colorlist=
|
|
[
|
|
"LightCyan",
|
|
"Lavender",
|
|
"Moccasin",
|
|
"Honeydew",
|
|
"Honeydew",
|
|
"OldLace",
|
|
"PaleGoldenrod",
|
|
"#bffb70",
|
|
];
|
|
|
|
|
|
var domenlist=[{name:"",color:"LightCyan",port:0}];
|
|
|
|
|
|
|
|
function SetError(Str)
|
|
{
|
|
SetStatus("<DIV align='left' style='color:red'><B>"+Str+"</B></DIV>");
|
|
}
|
|
function SetStatus(Str)
|
|
{
|
|
var id = document.getElementById("idStatus");
|
|
id.innerHTML=Str;
|
|
}
|
|
|
|
|
|
var GlErr="";
|
|
var MaxRed=0;
|
|
|
|
var COLUMN_WIDTH=60;
|
|
var BLOCK_WIDTH_COUNT=0;
|
|
var LineWidth=2;
|
|
var AllDrawArray=[];
|
|
var AllDrawMapXY={};
|
|
var MaxZ=0;
|
|
var nWork=0;
|
|
var IsDevelopAccount;
|
|
|
|
|
|
function InitDrawPaper()
|
|
{
|
|
AllDrawArray=[];
|
|
AllDrawMapXY={};
|
|
var obj = document.getElementById("BlockChainGraph");
|
|
var ctx = obj.getContext('2d');
|
|
ctx.fillStyle = "#FFF";
|
|
ctx.fillRect(0, 0, obj.width, obj.height);
|
|
BLOCK_WIDTH_COUNT=obj.width/COLUMN_WIDTH;
|
|
}
|
|
|
|
function GetHName(Block,MaxNum)
|
|
{
|
|
if(!Block)
|
|
return ""
|
|
|
|
if(Block.Type==="N")
|
|
{
|
|
var Str=Block.Name;
|
|
if(Str==="")
|
|
Str=Block.addrStr.substr(0,6);
|
|
return Str;
|
|
}
|
|
|
|
|
|
|
|
if(Block.bSave)//Block.BlockNum<MaxNum-8
|
|
{
|
|
var Name=GetStrFromHash(Block.SumHash);
|
|
return Name;
|
|
}
|
|
else
|
|
if(Block.BlockNum<MaxNum-4)
|
|
return "S:"+GetStrFromHash(Block.SeqHash);
|
|
else
|
|
return "T:"+GetStrFromHash(Block.TreeHash);
|
|
}
|
|
|
|
function CopyBlockParam(BlockNew,BlockOld)
|
|
{
|
|
if(BlockNew && BlockOld)
|
|
{
|
|
BlockNew.z=BlockOld.z;
|
|
//BlockNew.guid=BlockOld.guid;
|
|
BlockNew.View=BlockOld.View;
|
|
}
|
|
|
|
BlockNew.SumPow=BlockNew.SumPow;
|
|
}
|
|
|
|
var WasStartLoadBlockTime;
|
|
var MapHotNodes={};
|
|
function SetResult(Data,CurBlockNum,MaxBlockNum,NodeNum)
|
|
{
|
|
if(!Data)
|
|
return;
|
|
if(!Data.BlockChain)
|
|
return;
|
|
|
|
if($("idUseSound").checked && WasStartLoadBlockTime!==Data.StartLoadBlockTime)
|
|
{
|
|
WasStartLoadBlockTime=Data.StartLoadBlockTime;
|
|
//SetStatus("Data.LoadedChainCount="+Data.LoadedChainCount)
|
|
$("sound_click").play();
|
|
}
|
|
|
|
|
|
if(IsDevelopAccount!==Data.IsDevelopAccount)
|
|
if(Data.IsDevelopAccount)
|
|
SetStatus("DEV MODE")
|
|
|
|
IsDevelopAccount=Data.IsDevelopAccount;
|
|
|
|
var NodeParam=domenlist[NodeNum];
|
|
if(NodeParam.sessionid!=Data.sessionid)
|
|
{
|
|
SetNewSession(Data.sessionid);
|
|
|
|
MapHotNodes={};
|
|
NodeParam.MapBlockLoaded={};
|
|
NodeParam.ChainList=[];
|
|
NodeParam.MapBlockChain={};
|
|
NodeParam.sessionid=Data.sessionid;
|
|
MaxRed=0;
|
|
}
|
|
|
|
|
|
var MinBlockNum=MaxBlockNum-BLOCK_WIDTH_COUNT;
|
|
if(MinBlockNum<0)
|
|
MinBlockNum=0;
|
|
|
|
|
|
for(var i=0;i<Data.LoadedBlocks.length;i++)
|
|
{
|
|
var Block=Data.LoadedBlocks[i];
|
|
if(!Block || Block.BlockNum<MinBlockNum || Block.BlockNum>MaxBlockNum)
|
|
continue;
|
|
|
|
var BlockOld=NodeParam.MapBlockLoaded[Block.guid];
|
|
CopyBlockParam(Block,BlockOld);
|
|
|
|
NodeParam.MapBlockLoaded[Block.guid]=Block;
|
|
}
|
|
|
|
for(var i=0;i<Data.LoadedChainList.length;i++)
|
|
{
|
|
var chain=Data.LoadedChainList[i];
|
|
if(!chain || chain.BlockNum<MinBlockNum || chain.BlockNum>MaxBlockNum+BLOCK_WIDTH_COUNT)
|
|
continue;
|
|
|
|
var chainOld=NodeParam.ChainList[chain.id];
|
|
CopyBlockParam(chain,chainOld)
|
|
NodeParam.ChainList[chain.id]=chain;
|
|
}
|
|
//NodeParam.ChainList=Data.LoadedChainList;
|
|
|
|
var Map2={};
|
|
for(var i=0;i<Data.BlockChain.length;i++)
|
|
{
|
|
var Block=Data.BlockChain[i];
|
|
if(!Block || Block.BlockNum<MinBlockNum || Block.BlockNum>MaxBlockNum)
|
|
continue;
|
|
|
|
Map2[Block.BlockNum]=Block;
|
|
|
|
var BlockOld=NodeParam.MapBlockChain[Block.BlockNum];
|
|
CopyBlockParam(Block,BlockOld)
|
|
}
|
|
NodeParam.MapBlockChain=Map2;
|
|
|
|
|
|
|
|
|
|
SetNodesResult(Data.ArrTree);
|
|
|
|
DrawChannels(NodeParam,NodeNum,CurBlockNum,MinBlockNum,MaxBlockNum,Data.BlockChain,Data.LoadedChainList);
|
|
}
|
|
|
|
var ArrHotNodes=[];
|
|
function SetNodesResult(SetArr)
|
|
{
|
|
ArrHotNodes=[];
|
|
|
|
if(!SetArr)
|
|
return;
|
|
for(var Level=0;Level<SetArr.length;Level++)
|
|
{
|
|
var Arr=SetArr[Level];
|
|
if(Arr)
|
|
for(var i=0;i<Arr.length;i++)
|
|
{
|
|
var Node=Arr[i];
|
|
if(!Node || !Node.Hot)
|
|
continue;
|
|
|
|
Node.guid=Node.id;
|
|
Node.Prepared=1;
|
|
var NodeOld=MapHotNodes[Node.guid];
|
|
CopyNodeParam(Node,NodeOld);
|
|
MapHotNodes[Node.guid]=Node;
|
|
|
|
if(!Node.Color)
|
|
Node.Color=getRandomColor();
|
|
|
|
ArrHotNodes.push(Node);
|
|
}
|
|
}
|
|
}
|
|
|
|
function CopyNodeParam(NodeNew,NodeOld)
|
|
{
|
|
if(NodeNew && NodeOld)
|
|
{
|
|
NodeNew.z=NodeOld.z;
|
|
//NodeNew.guid=NodeOld.guid;
|
|
NodeNew.View=NodeOld.View;
|
|
NodeNew.Color=NodeOld.Color;
|
|
|
|
if(!NodeOld.TransferBlockNumFixPrev)
|
|
NodeOld.TransferBlockNumFixPrev=0;
|
|
if(!NodeOld.TransferSizePrev)
|
|
NodeOld.TransferSizePrev=0;
|
|
|
|
|
|
NodeNew.TransferBlockNumFixPrev=NodeOld.TransferBlockNumFixPrev;
|
|
NodeNew.TransferSizePrev=NodeOld.TransferSizePrev;
|
|
NodeNew.SizeView=NodeOld.SizeView;
|
|
|
|
|
|
if(NodeNew.TransferBlockNumFixPrev!==NodeNew.TransferBlockNumFix)
|
|
{
|
|
NodeNew.SizeView=NodeNew.TransferSize-NodeNew.TransferSizePrev;
|
|
if(!NodeNew.TransferBlockNumFixPrev)
|
|
NodeNew.SizeView=0;
|
|
NodeNew.TransferBlockNumFixPrev=NodeNew.TransferBlockNumFix;
|
|
NodeNew.TransferSizePrev=NodeNew.TransferSize;
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
function DrawChannels(NodeParam,NodeNum,CurBlockNum,MinBlockNum,MaxBlockNum,BlockChain,ChainList)
|
|
{
|
|
var color=NodeParam.color;
|
|
|
|
var obj = document.getElementById("BlockChainGraph");
|
|
var ctx = obj.getContext('2d');
|
|
|
|
var arrBlocks=[];
|
|
|
|
var StartDrawNum=MaxBlockNum-2;
|
|
|
|
//Основной блокчейн
|
|
var CountBlock=0;
|
|
var LastBlock;
|
|
var DY=150;
|
|
for(var i=BlockChain.length;i>=0;i--)
|
|
{
|
|
var Block=BlockChain[i];
|
|
if(!Block || Block.BlockNum<MinBlockNum || Block.BlockNum>MaxBlockNum)
|
|
continue;
|
|
|
|
CountBlock++;
|
|
if(CalcDrawBlock(obj,ctx,StartDrawNum,"H",DY,NodeNum,Block,100,color))
|
|
{
|
|
LastBlock=Block;
|
|
arrBlocks.push(Block);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//ноды
|
|
if(ArrHotNodes.length)
|
|
{
|
|
var SumSizeView=0;
|
|
for(var i=0;i<ArrHotNodes.length;i++)
|
|
{
|
|
var Node=ArrHotNodes[i];
|
|
if(!Node.SizeView)
|
|
Node.SizeView=0;
|
|
SumSizeView+=Node.SizeView;
|
|
}
|
|
var AvgSizeView=SumSizeView/ArrHotNodes.length;
|
|
if(!AvgSizeView)
|
|
AvgSizeView=1;
|
|
|
|
for(var i=0;i<ArrHotNodes.length;i++)
|
|
{
|
|
var Node=ArrHotNodes[i];
|
|
//Node.BlockNum=ArrHotNodes.length-i;
|
|
Node.BlockNum=i;
|
|
|
|
if(CalcDrawBlock(obj,ctx,ArrHotNodes.length-1,"N",0,0,Node,50,Node.Color.color2))
|
|
{
|
|
arrBlocks.push(Node);
|
|
|
|
var x1,x2,y1,y2;
|
|
|
|
var TransferBlockNum=Node.TransferBlockNum;
|
|
if(Node.TransferBlockNumFix!==CurBlockNum)
|
|
{
|
|
Node.SizeView=0;
|
|
continue;
|
|
}
|
|
|
|
|
|
var Block=NodeParam.MapBlockChain[Node.TransferBlockNum];
|
|
if(!Block)
|
|
continue;
|
|
|
|
x1=Node.x+Node.width/2;
|
|
y1=Node.y+Node.height;
|
|
x2=Block.x+Block.width/2;
|
|
y2=Block.y;
|
|
|
|
//линии
|
|
ctx.strokeStyle = Node.Color.color1;//color;
|
|
ctx.lineWidth=Math.log2(1+Node.SizeView/AvgSizeView/2);
|
|
if(ctx.lineWidth<0.2)
|
|
ctx.lineWidth=0.2;
|
|
if(ctx.lineWidth>6)
|
|
ctx.lineWidth=6;
|
|
|
|
ctx.beginPath();
|
|
ctx.moveTo(x1, y1);
|
|
ctx.lineTo(x2,y2);
|
|
ctx.stroke();
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if(LastBlock)
|
|
{
|
|
var MaxCount=3;
|
|
DY+=(LastBlock.height+10)*domenlist.length;
|
|
DY+=(LastBlock.height+10)*MaxCount*NodeNum;
|
|
|
|
//Загружаемые цепочки из других нод
|
|
var CountChain=0;
|
|
for(var n=0;n<ChainList.length;n++)
|
|
{
|
|
var Chain=ChainList[n];
|
|
if(!Chain || Chain.BlockNum<MinBlockNum || Chain.BlockNum>MaxBlockNum+BLOCK_WIDTH_COUNT)
|
|
continue;
|
|
|
|
CountChain++;
|
|
|
|
|
|
//загруженные блоки
|
|
var CountBlock=0;
|
|
var bWas=false;
|
|
var Block=NodeParam.MapBlockLoaded[Chain.HashMaxStr];
|
|
while(Block)
|
|
{
|
|
if(!Block || Block.BlockNum<MinBlockNum || Block.BlockNum>MaxBlockNum)
|
|
break;
|
|
|
|
if(CalcDrawBlock(obj,ctx,StartDrawNum,"B",DY,Block.chainid,Block,MaxCount,color))
|
|
{
|
|
bWas=true;
|
|
arrBlocks.push(Block);
|
|
}
|
|
CountBlock++;
|
|
if(CountBlock>500)
|
|
{
|
|
GlErr="ERROR: CountBlock>500";
|
|
break;
|
|
}
|
|
|
|
Block=NodeParam.MapBlockLoaded[Block.BlockDown];
|
|
}
|
|
|
|
}
|
|
|
|
for(var n=0;n<ChainList.length;n++)
|
|
{
|
|
var Chain=ChainList[n];
|
|
if(!Chain || Chain.BlockNum<MinBlockNum)
|
|
continue;
|
|
|
|
//Заголовок цепочки
|
|
if(CalcDrawBlock(obj,ctx,StartDrawNum,"C",DY,Chain.id,Chain,MaxCount,color))//!bWas &&
|
|
{
|
|
arrBlocks.push(Chain);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
for(var i=0;i<arrBlocks.length;i++)
|
|
{
|
|
Block=arrBlocks[i];
|
|
var PrevBlock=NodeParam.MapBlockLoaded[Block.BlockDown];
|
|
if(PrevBlock && PrevBlock.nWork===nWork && PrevBlock.Type===Block.Type)
|
|
{
|
|
ctx.strokeStyle = "rgb(0,0,0)";//color;
|
|
ctx.lineWidth=LineWidth;
|
|
ctx.beginPath();
|
|
ctx.moveTo(PrevBlock.x+PrevBlock.width/2, PrevBlock.y+PrevBlock.height/2);
|
|
ctx.lineTo(Block.x+Block.width/2, Block.y+Block.height/2);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
}
|
|
|
|
arrBlocks.sort(function (a,b)
|
|
{
|
|
return a.z-b.z;
|
|
});
|
|
for(var i=0;i<arrBlocks.length;i++)
|
|
{
|
|
Block=arrBlocks[i];
|
|
DrawBlock(ctx,Block);
|
|
}
|
|
}
|
|
|
|
|
|
function CalcDrawBlock(obj,ctx,MaxBlockNum,Type,DY,Line,Block,MaxCount,colorFill)
|
|
{
|
|
if(Block.nWork===nWork)
|
|
return true;
|
|
//Block.Comment1="W="+Block.nWork;
|
|
|
|
Block.MaxBlockNum=MaxBlockNum;
|
|
|
|
var Pos=MaxBlockNum-Block.BlockNum;
|
|
var width=COLUMN_WIDTH-10;
|
|
var height=60;
|
|
|
|
if(Type==="N")
|
|
{
|
|
height=60;
|
|
//width=50;
|
|
}
|
|
|
|
|
|
var x=obj.width-((Pos+1)*(width+10));
|
|
if(x<0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Block.nWork=nWork;
|
|
var y=(Line%MaxCount)*(height+25)+1+DY;
|
|
|
|
while(true)
|
|
{
|
|
var keyXY=""+x+":"+y;
|
|
if(!AllDrawMapXY[keyXY])
|
|
{
|
|
AllDrawMapXY[keyXY]=1;
|
|
break;
|
|
}
|
|
y=y+15;
|
|
x=x+5;
|
|
}
|
|
|
|
Block.x=x;
|
|
Block.y=y;
|
|
Block.width=width;
|
|
Block.height=height;
|
|
if(Type==="H")
|
|
{
|
|
Block.height=height+16;
|
|
}
|
|
else
|
|
if(Type==="C")
|
|
{
|
|
Block.x+=10;
|
|
Block.y-=12;
|
|
}
|
|
else
|
|
if(Type==="B")
|
|
{
|
|
Block.height-=16;
|
|
Block.width-=10;
|
|
}
|
|
|
|
Block.Type=Type;
|
|
Block.colorFill=colorFill;
|
|
|
|
if(!Block.z)
|
|
{
|
|
MaxZ++;
|
|
Block.z=MaxZ;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
function DrawBlock(ctx,Block)//------------------------------------------------------------------------------------ DrawBlock
|
|
{
|
|
if(x<0)
|
|
return;
|
|
if(Block.nWork!==nWork)
|
|
return;
|
|
|
|
var x=Block.x;
|
|
var y=Block.y;
|
|
ctx.lineWidth=2;
|
|
|
|
ctx.strokeStyle="#000";
|
|
if(Block.bSave)
|
|
ctx.strokeStyle="#1C1";
|
|
else
|
|
{
|
|
if(Block.Mining)
|
|
ctx.strokeStyle="#9b712a";
|
|
else
|
|
if(Block.Prepared)
|
|
ctx.strokeStyle="#66F";
|
|
else
|
|
if(Block.Type==="H" && !Block.Active)
|
|
ctx.strokeStyle="#e6bd40";
|
|
else
|
|
ctx.strokeStyle="#ca00ca";
|
|
}
|
|
|
|
if(Block.Type==="B" && (Block.TreeLoaded || Block.FindBlockDB))
|
|
ctx.strokeStyle="green";
|
|
else
|
|
if(Block.Type==="B" && Block.AddToLoad && !Block.TreeLoaded)
|
|
ctx.strokeStyle="red";
|
|
|
|
|
|
ctx.beginPath();
|
|
|
|
if(Block.CheckPoint)
|
|
ctx.fillStyle="#f0ffb9";
|
|
else
|
|
ctx.fillStyle = Block.colorFill;
|
|
|
|
if((Block.Type==="B" || Block.Type==="C") && !Block.Main)
|
|
ctx.fillStyle = "#FFF";
|
|
|
|
|
|
ctx.fillRect(x, y, Block.width, Block.height);
|
|
ctx.strokeRect(x, y, Block.width, Block.height);
|
|
if(Block.Type==="C")
|
|
{
|
|
ctx.moveTo(Block.x+Block.width-10, Block.y+Block.height);
|
|
ctx.lineTo(Block.x+Block.width, Block.y+Block.height-10);
|
|
}
|
|
|
|
|
|
var header=GetHName(Block,Block.MaxBlockNum)
|
|
|
|
|
|
ctx.fillStyle = "#000";
|
|
if(Block.Type==="H" && Block.HasErr)
|
|
{
|
|
ctx.fillStyle="#F00";
|
|
}
|
|
ctx.font="12px sans-serif";
|
|
if(Block.Type==="H")
|
|
ctx.fillText(header,x+8,y+10);
|
|
else
|
|
ctx.fillText(header,x+2,y+10);
|
|
ctx.font="10px sans-serif";
|
|
|
|
ctx.fillStyle = "#000";
|
|
|
|
if(Block.Type!="N")
|
|
ctx.fillText(""+Block.BlockNum,x+2,y+10+16);
|
|
|
|
if(Block.Type==="H")
|
|
{
|
|
if(Block.TrCount)
|
|
{
|
|
ctx.fillText("TH:"+GetStrFromHash(Block.TreeHash),x+2,y+10+32);
|
|
ctx.fillText("Tr:"+Block.TrCount,x+2,y+10+48);
|
|
}
|
|
else
|
|
{
|
|
ctx.fillText("-----",x+16,y+10+32);
|
|
}
|
|
|
|
//ctx.fillText("P:"+Block.SumPow.toFixed(0),x+2,y+10+48+16);
|
|
|
|
var y2=y+10+48+16;
|
|
var Miner=Block.MinerName;
|
|
if(!Miner)
|
|
Miner=Block.MinerID;
|
|
ctx.fillText(Miner,x+2,y2);
|
|
|
|
|
|
var L1=30;
|
|
if(Block.Power>=L1)
|
|
{
|
|
ctx.strokeRect(x, y2-12, L1, 2);
|
|
if(Block.Power>=36)
|
|
ctx.strokeStyle = "#ff353b";
|
|
else
|
|
ctx.strokeStyle = "#fb8";
|
|
|
|
ctx.strokeRect(x+L1, y2-12, Block.Power-L1, 2);
|
|
}
|
|
else
|
|
{
|
|
ctx.strokeRect(x, y2-12, Block.Power, 2);
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
if(Block.Type==="C")
|
|
{
|
|
ctx.fillText("id:"+Block.chainid,x+2,y+10+32);
|
|
ctx.fillText(Block.Comment2,x+2,y+10+32+16);
|
|
}
|
|
else
|
|
if(Block.Type==="B")
|
|
{
|
|
ctx.fillText("id:"+Block.chainid,x+2,y+10+32);
|
|
}
|
|
else
|
|
if(Block.Type==="N")
|
|
{
|
|
y+=40;
|
|
ctx.fillText("T:"+Block.TransferCount,x+2,y);
|
|
|
|
y+=16;
|
|
ctx.fillText("Kb:"+Math.floor(10*Block.SizeView)/10,x+2,y);
|
|
|
|
// y+=20;
|
|
// if(Block.TransferBlockNum)
|
|
// ctx.fillText("B:"+Block.TransferBlockNum,x+2,y);
|
|
}
|
|
|
|
|
|
ctx.stroke();
|
|
|
|
AllDrawArray.push(Block);
|
|
|
|
if(Block.View)
|
|
UpdateBlockView(Block);
|
|
}
|
|
|
|
//LIB FROM INET
|
|
function getRandomColor()
|
|
{
|
|
var letters = '0123456789ABCDEF'.split('');
|
|
var color1 = '#';
|
|
var color2 = '#';
|
|
for (var i = 0; i < 6; i++)
|
|
{
|
|
var rnd=Math.random();
|
|
color1 += letters[Math.round(2+rnd * 7)];
|
|
color2 += letters[Math.round(8+rnd * 7)];
|
|
}
|
|
return {color1:color1,color2:color2};
|
|
}
|
|
|
|
function getRandomColor2()
|
|
{
|
|
//skip green
|
|
var ranges = [[0, 60], [180, 359]];
|
|
//get max random
|
|
var total = 0, i;
|
|
for (i = 0; i < ranges.length; i += 1) {
|
|
total += ranges[i][1]-ranges[i][0] + 1;
|
|
}
|
|
//get random hue index
|
|
var randomHue = Math.floor(Math.random() * total);
|
|
//convert index to actual hue
|
|
var pos = 0;
|
|
for (i = 0; i < ranges.length; i += 1) {
|
|
pos = ranges[i][0];
|
|
if (randomHue + pos <= ranges[i][1]) {
|
|
randomHue += pos;
|
|
break;
|
|
} else {
|
|
randomHue -= (ranges[i][1] - ranges[i][0] + 1);
|
|
}
|
|
}
|
|
return 'hsl(' + randomHue + ',100%,50%)';
|
|
}
|
|
|
|
function wrapText(context, text, marginLeft, marginTop, maxWidth, lineHeight)
|
|
{
|
|
//Exmpl:wrapText(ctx, text, x, y+20, Block.width, 12);
|
|
var words = text.split(" ");
|
|
var countWords = words.length;
|
|
var line = "";
|
|
|
|
for (var n = 0; n < countWords; n++)
|
|
{
|
|
var testLine = line + words[n] + " ";
|
|
var testWidth = context.measureText(testLine).width;
|
|
if (testWidth > maxWidth)
|
|
{
|
|
context.fillText(line, marginLeft, marginTop);
|
|
line = words[n] + " ";
|
|
marginTop += lineHeight;
|
|
}
|
|
else {
|
|
line = testLine;
|
|
}
|
|
}
|
|
context.fillText(line, marginLeft, marginTop);
|
|
}
|
|
|
|
|
|
//MOVE DIV
|
|
var blockMove;
|
|
var delta_x = 0;
|
|
var delta_y = 0;
|
|
function InitMoveBlock()
|
|
{
|
|
window.onmouseup = clearMoveXY;
|
|
window.addEventListener("onmouseup", clearMoveXY, false);
|
|
window.addEventListener("onmousemove", moveBlock, false);
|
|
|
|
window.onmousedown = saveMoveXY;
|
|
window.addEventListener("onmousedown", saveMoveXY, false);
|
|
|
|
}
|
|
/* При нажатии кнопки мыши попадаем в эту функцию */
|
|
function saveMoveXY(obj_event)
|
|
{
|
|
blockMove=undefined;
|
|
|
|
/* Получаем текущие координаты курсора */
|
|
if (obj_event)
|
|
{
|
|
if(obj_event.srcElement && obj_event.srcElement.className.indexOf("header")>=0)
|
|
{
|
|
obj_event.preventDefault();
|
|
blockMove=obj_event.srcElement.parentNode;
|
|
|
|
x = obj_event.pageX;
|
|
y = obj_event.pageY;
|
|
|
|
/* Узнаём текущие координаты блока */
|
|
var x_block = blockMove.offsetLeft;
|
|
var y_block = blockMove.offsetTop;
|
|
/* Узнаём смещение */
|
|
delta_x = x_block - x;
|
|
delta_y = y_block - y;
|
|
|
|
SetMaxZIndex(blockMove)
|
|
}
|
|
if(obj_event.srcElement && obj_event.srcElement.className.indexOf("vdata")>=0)
|
|
{
|
|
//obj_event.preventDefault();
|
|
SetMaxZIndex(obj_event.srcElement.parentNode)
|
|
}
|
|
}
|
|
}
|
|
function clearMoveXY()
|
|
{
|
|
//window.onmousedown = undefined;
|
|
blockMove=undefined;
|
|
}
|
|
function moveBlock(obj_event)
|
|
{
|
|
if(!blockMove)
|
|
return;
|
|
|
|
/* Получаем новые координаты курсора мыши */
|
|
if (obj_event)
|
|
{
|
|
x = obj_event.pageX;
|
|
y = obj_event.pageY;
|
|
}
|
|
else
|
|
{
|
|
x = window.event.clientX;
|
|
y = window.event.clientY;
|
|
if (ie)
|
|
{
|
|
y -= 2;
|
|
x -= 2;
|
|
}
|
|
}
|
|
/* Вычисляем новые координаты блока */
|
|
new_x = delta_x + x;
|
|
new_y = delta_y + y;
|
|
blockMove.style.top = new_y + "px";
|
|
blockMove.style.left = new_x + "px";
|
|
}
|
|
|
|
|
|
//LIB
|
|
//LIB
|
|
//LIB
|
|
//LIB
|
|
function GetStrFromHash(Str)
|
|
{
|
|
if(typeof Str==="string")
|
|
//return Str.substr(2,4);
|
|
return Str.substr(0,4);
|
|
else
|
|
return "";
|
|
}
|
|
|
|
function getMouse(canvas,e)
|
|
{
|
|
|
|
var x = e.clientX - getTrueOffsetLeft(canvas);
|
|
if(window.pageXOffset)
|
|
x=x+window.pageXOffset;
|
|
|
|
var y = e.clientY - getTrueOffsetTop(canvas);
|
|
if(window.pageYOffset)
|
|
y=y+window.pageYOffset
|
|
var coord= {x:x,y:y};
|
|
return coord;
|
|
};
|
|
function getTrueOffsetLeft(ele)
|
|
{
|
|
var n = 0;
|
|
while (ele)
|
|
{
|
|
n += ele.offsetLeft || 0;
|
|
ele = ele.offsetParent;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
function getTrueOffsetTop(ele)
|
|
{
|
|
var n = 0;
|
|
while (ele)
|
|
{
|
|
n += ele.offsetTop || 0;
|
|
ele = ele.offsetParent;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
|
|
function random(max)
|
|
{
|
|
ret=Math.floor(Math.random()*max);
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
|
|
//DIALOG
|
|
//DIALOG
|
|
//DIALOG
|
|
|
|
|
|
var bPause;
|
|
function SetPause(SetMode)
|
|
{
|
|
if(SetMode===undefined)
|
|
{
|
|
bPause=!bPause;
|
|
}
|
|
else
|
|
{
|
|
bPause=SetMode;
|
|
}
|
|
var item = document.getElementById("idRun");
|
|
if(bPause)
|
|
item.value="Continue view";
|
|
else
|
|
item.value="Pause view";
|
|
}
|
|
|
|
function SetWidth()
|
|
{
|
|
var id = document.getElementById("LineWidth");
|
|
LineWidth=id.value;
|
|
}
|
|
|
|
|
|
//VIEW BLOCK
|
|
|
|
var ArrViewBlock=[];
|
|
var MaxZIndex=10;
|
|
function SetMaxZIndex(Block)
|
|
{
|
|
MaxZIndex++;
|
|
Block.style["z-index"]=MaxZIndex;
|
|
}
|
|
function InitViewBlock()
|
|
{
|
|
window.onkeydown = cancelViewBlock;
|
|
}
|
|
function cancelViewBlock(e)
|
|
{
|
|
if(e.keyCode===27 && ArrViewBlock.length)
|
|
{
|
|
var name=ArrViewBlock[ArrViewBlock.length-1];
|
|
ArrViewBlock.length=ArrViewBlock.length-1;
|
|
CloseView(name);
|
|
}
|
|
|
|
if(!ArrViewBlock.length)
|
|
MaxZIndex=10;
|
|
}
|
|
|
|
|
|
function AddView(Str)
|
|
{
|
|
var id = document.getElementById("viewer");
|
|
id.innerHTML+=Str;
|
|
}
|
|
function CloseView(id)
|
|
{
|
|
var name="b"+id;
|
|
var parentElem = document.getElementById("viewer");
|
|
var child=document.getElementById(name);
|
|
if(child)
|
|
parentElem.removeChild(child)
|
|
}
|
|
function SetViewBlock(Block,event)
|
|
{
|
|
InitViewBlock();
|
|
|
|
var name=Block.Type.trim()+Block.guid;
|
|
var coord=getMouse(window,event);
|
|
var x=coord.x;
|
|
var y=coord.y;
|
|
if(x<=0 && y<=0)
|
|
return;
|
|
|
|
x-=100;
|
|
y+=10;
|
|
// if(y<310)
|
|
// y=310;
|
|
|
|
var element = document.getElementById("b"+name);
|
|
if(!element)
|
|
{
|
|
var Str='<DIV id="b'+name+'" class="vblock"> ' +
|
|
'<DIV id="h'+name+'" class="header"></DIV> ' +
|
|
'<INPUT id="c'+name+'" type="button" class="vclose" onclick=CloseView("'+name+'") value="X"> ' +
|
|
'<DIV id="d'+name+'" class="vdata"></DIV> ' +
|
|
'</DIV>';
|
|
AddView(Str);
|
|
ArrViewBlock.push(name);
|
|
|
|
element = document.getElementById("b"+name);
|
|
}
|
|
var header=document.getElementById("h"+name);
|
|
var closer=document.getElementById("c"+name);
|
|
var data = document.getElementById("d"+name);
|
|
|
|
element.style.left=""+x+ "px";
|
|
element.style.top=""+y+ "px";
|
|
element.style.height="100px";
|
|
SetMaxZIndex(element);
|
|
|
|
|
|
|
|
header.style.background=Block.colorFill;
|
|
closer.style.background=Block.colorFill;
|
|
data.style.background=Block.colorFill;
|
|
|
|
UpdateBlockView(Block);
|
|
}
|
|
|
|
function UpdateBlockView(Block)
|
|
{
|
|
var name=Block.Type+Block.guid;
|
|
var header=document.getElementById("h"+name);
|
|
if(!header)
|
|
return;
|
|
|
|
var data = document.getElementById("d"+name);
|
|
|
|
Block.View=1;
|
|
var Str0;
|
|
if(Block.SumHash)
|
|
{
|
|
Str0=GetStrFromHash(Block.SumHash)+" : "+Block.Type;
|
|
}
|
|
else
|
|
if(Block.Type==="N")
|
|
{
|
|
Str0=GetHName(Block);
|
|
}
|
|
else
|
|
{
|
|
Str0="H:"+GetStrFromHash(Block.Hash)+" : "+Block.Type;
|
|
}
|
|
|
|
header.innerText=Str0;
|
|
|
|
|
|
var Str="";
|
|
if(IsDevelopAccount && Block.Type==="H")
|
|
{
|
|
Str+='<INPUT type="button" onclick="SetCheckPoint('+Block.BlockNum+')" class="" value="=Set CheckPoint="><BR>';
|
|
}
|
|
|
|
if(Block.Type!="N")
|
|
{
|
|
Str += RetOpenBlock(Block.BlockNum,Block.TrDataLen);
|
|
Str +="\nSave:"+Block.bSave;
|
|
}
|
|
else
|
|
{
|
|
Str +="\nBlock"+Block.TransferBlockNum;
|
|
|
|
Block.Info=undefined;
|
|
Block.addrStr=Block.addrStr.substr(0,12)+"...";
|
|
Str += JSON.stringify(Block,"",2);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var rootinfo;
|
|
if(Block.Type==="C")
|
|
{
|
|
var rootid="";
|
|
if(Block.root)
|
|
{
|
|
rootid=""+Block.root.id;
|
|
if(Block.root.StopSend)
|
|
rootid=rootid+" StopSend";
|
|
if(Block.root.GetFindDB)
|
|
rootid=rootid+" FindDB";
|
|
|
|
rootinfo=Block.root.Info;
|
|
}
|
|
Str+="\nid:"+Block.id;//+" num:"+Block.num;
|
|
Str+="\nrootid:"+rootid;
|
|
Str+="\nStopSend:"+Block.StopSend;
|
|
Str+="\nFindDB:"+Block.GetFindDB;
|
|
Str+="\nHashMaxStr:"+Block.HashMaxStr;
|
|
}
|
|
else
|
|
if(Block.Type!="N")
|
|
{
|
|
if(Block.chainid)
|
|
Str+="\nid:"+Block.chainid;
|
|
else
|
|
if(Block.id)
|
|
Str+="\nid:"+Block.id;
|
|
|
|
Str+="\nTrCount:"+Block.TrCount;
|
|
Str+="\nTreeH:"+GetStrFromHash(Block.TreeHash);
|
|
Str+="\nTrDataLen:"+Block.TrDataLen;
|
|
Str+="\nSumH:"+GetStrFromHash(Block.SumHash);
|
|
|
|
|
|
|
|
Str+="\nMiner:"+Block.MinerID+". "+Block.MinerName;
|
|
Str+="\nPow:"+Block.Power;
|
|
Str+="\nSumPow:"+Block.SumPow;
|
|
|
|
if(!Block.TreeLoaded)
|
|
Block.TreeLoaded="";
|
|
if(!Block.AddToLoad)
|
|
Block.AddToLoad="";
|
|
if(!Block.LoadDB)
|
|
Block.LoadDB="";
|
|
|
|
|
|
//Str+="\nArrLength:"+Block.ArrLength;
|
|
|
|
if(Block.Type==="B")
|
|
{
|
|
Str+="\nTreeLoaded:"+Block.TreeLoaded;
|
|
// Str+="\nAddToLoad:"+Block.AddToLoad;
|
|
// Str+="\nLoadDB:"+Block.LoadDB;
|
|
Str+="\nMain:"+Block.Main;
|
|
Str+="\nBlockDown:"+Block.BlockDown;
|
|
}
|
|
}
|
|
if(Block.Type!="N")
|
|
{
|
|
Str+="\nHash:"+GetStrFromHash(Block.Hash);
|
|
|
|
if(!Block.Comment1)
|
|
Block.Comment1="";
|
|
if(!Block.Comment2)
|
|
Block.Comment2=""
|
|
Str+="\n"+Block.Comment1;
|
|
Str+="\n"+Block.Comment2;
|
|
|
|
|
|
|
|
|
|
if(Block.Info)
|
|
Str+="\n"+Block.Info;
|
|
if(rootinfo)
|
|
Str+="\n\n--------ROOT "+Block.root.id+" max:"+Block.root.BlockNumMax+":\n"+rootinfo;
|
|
}
|
|
|
|
|
|
Str=Str.replace(/[\n]/g, "<BR>");
|
|
|
|
|
|
//data.innerText=Str;
|
|
data.innerHTML=Str;
|
|
}
|
|
|
|
|
|
//обработка нажатия кнопки мышки на узле
|
|
function DoBlockInfo(Fx,Fy,event)
|
|
{
|
|
var Block=GetBlockByXY(Fx,Fy);
|
|
|
|
if(Block)
|
|
{
|
|
MaxZ++;
|
|
Block.z=MaxZ;
|
|
|
|
var obj = document.getElementById("BlockChainGraph");
|
|
var ctx = obj.getContext('2d');
|
|
DrawBlock(ctx,Block);
|
|
}
|
|
}
|
|
function DoBlockInfoUp(Fx,Fy,event)
|
|
{
|
|
var Block=GetBlockByXY(Fx,Fy);
|
|
if(Block)
|
|
{
|
|
SetViewBlock(Block, event)
|
|
}
|
|
}
|
|
|
|
function DoDblClick(Fx,Fy, event)
|
|
{
|
|
var Block=GetBlockByXY(Fx,Fy);
|
|
if(Block)
|
|
{
|
|
//SetViewBlock(Block, event)
|
|
}
|
|
}
|
|
|
|
|
|
function GetBlockByXY(Fx,Fy)
|
|
{
|
|
//ищем блок
|
|
var Array=AllDrawArray;
|
|
for(var i=0;i<Array.length;i++)
|
|
{
|
|
var item=Array[i];
|
|
if(item.x<=Fx && item.x+item.width>=Fx
|
|
&& item.y<=Fy && item.y+item.height>=Fy)
|
|
{
|
|
return item;
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
|
|
|
|
|
|
//INIT
|
|
var strReload="reload/";
|
|
var ResDataArr=[];
|
|
function UpdateData()
|
|
{
|
|
if(bPause)
|
|
return;
|
|
|
|
if(ResDataArr.length)
|
|
{
|
|
var Data=ResDataArr[0];
|
|
var MaxNum=Data.CurrentBlockNum;
|
|
nWork++;
|
|
|
|
InitDrawPaper();
|
|
|
|
var StrInfo="";
|
|
StrInfo+="<DIV class='nodestatus'>"
|
|
StrInfo+="Blocks:"+MaxNum+" "+GlErr+"</B>";
|
|
StrInfo+="</DIV>"
|
|
|
|
for(var n=0;n<ResDataArr.length;n++)
|
|
{
|
|
var Data=ResDataArr[n];
|
|
if(Data)
|
|
{
|
|
var Domen=domenlist[Data.NumArr];
|
|
SetResult(Data,MaxNum,Data.LastCurrentBlockNum,Data.NumArr);
|
|
|
|
var mem=Math.floor(Data.memoryUsage.heapTotal/1000000);
|
|
var color=Domen.color;
|
|
|
|
|
|
StrInfo+="<DIV class='nodestatus' style='background:'"+color+"'>";
|
|
if(Domen.name!=="")
|
|
StrInfo+="<A href='"+Domen.name+"'>";
|
|
|
|
Data.DELTA_CURRENT_TIME=Math.floor(Data.DELTA_CURRENT_TIME)/1000;
|
|
|
|
if(Domen.Hot)
|
|
{
|
|
StrInfo+="dt:"+Data.DELTA_CURRENT_TIME+"}";
|
|
if(Domen.name!=="")
|
|
StrInfo+="</A>";
|
|
StrInfo+=" Mem: <B>"+mem+"</B>Mb";
|
|
}
|
|
else
|
|
{
|
|
StrInfo+="dt:"+Data.DELTA_CURRENT_TIME;
|
|
if(Domen.name!=="")
|
|
StrInfo+="</A>";
|
|
StrInfo+=" Mem: "+mem+"Mb";
|
|
}
|
|
StrInfo+="</DIV>"
|
|
|
|
|
|
}
|
|
}
|
|
//SetStatus(StrInfo);
|
|
document.getElementById("idTitle").innerHTML=StrInfo;
|
|
|
|
// var mem=Math.floor(window.performance.memory.usedJSHeapSize/1000)/1000;
|
|
// var memfree=Math.floor(window.performance.memory.totalJSHeapSize/1000)/1000;
|
|
//SetStatus("MaxNum:"+MaxNum+" memory="+mem+" Mb free="+memfree+" Mb")
|
|
}
|
|
ResDataArr=[];
|
|
GetData("GetBlockChain",strReload,function (Data,Str)
|
|
{
|
|
if(typeof Data==="object" && Data.result)
|
|
{
|
|
Data.NumArr=0;
|
|
ResDataArr[0]=Data;
|
|
}
|
|
});
|
|
//CallDataChain(ResDataArr,0,strReload);
|
|
strReload="";
|
|
}
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
<style type="text/css">
|
|
#topframe
|
|
{
|
|
z-index:1000;
|
|
position:fixed;
|
|
top:0px;
|
|
left:0px;
|
|
text-align: center;
|
|
width:1200px;
|
|
}
|
|
|
|
#idTitle,idStatus
|
|
{
|
|
width:1700px;
|
|
height:20px;
|
|
text-align: left;
|
|
}
|
|
|
|
#idRun
|
|
{
|
|
width:100px;
|
|
}
|
|
|
|
#BlockChainGraph
|
|
{
|
|
z-index:0;
|
|
}
|
|
div.vblock
|
|
{
|
|
z-index:10;
|
|
position: absolute;
|
|
}
|
|
div.header
|
|
{
|
|
cursor: move;
|
|
float:left;
|
|
width:175px;
|
|
height: 20px;
|
|
text-align: center;
|
|
border: 1px solid #000;
|
|
background: #DEE1AE;
|
|
}
|
|
input.vclose
|
|
{
|
|
right: 0px;
|
|
width:25px;
|
|
height: 21px;
|
|
background: #c6c996;
|
|
}
|
|
div.vdata
|
|
{
|
|
position: relative;
|
|
cursor:auto;
|
|
padding: 5px;
|
|
top: 0px;
|
|
width:190px;
|
|
border: 1px solid #000;
|
|
font-size: small;
|
|
|
|
}
|
|
div.nodestatus
|
|
{
|
|
position: relative;
|
|
float:left;
|
|
padding: 1px;
|
|
height:16px;
|
|
width:300px;
|
|
border: 1px solid #d1e3fe;
|
|
background: #f0f7fe;
|
|
text-align: center;
|
|
}
|
|
|
|
</style>
|
|
|
|
<DIV id="topframe">
|
|
<INPUT type="button" style="float:left" onclick="SetPause()" id="idRun">
|
|
|
|
|
|
|
|
<DIV id="idTitle"> </DIV>
|
|
<DIV id="idStatus"> </DIV>
|
|
</DIV>
|
|
<DIV id="viewer">
|
|
</DIV>
|
|
|
|
|
|
<BR>
|
|
<BR>
|
|
|
|
|
|
|
|
<INPUT type="checkbox" onchange = "SaveValues()" id="idUseSound">Use sound alert<BR>
|
|
<BR>
|
|
|
|
<canvas width='1800' height='500' id='BlockChainGraph'></canvas>
|
|
|
|
|
|
<!--<input type="button" onclick='$("sound_click").play();' value="sndMsg"/>-->
|
|
|
|
|
|
<audio style="visibility: hidden;" controls="controls" id="sound_bt">
|
|
<source src="soundbt.mp3" type="audio/mpeg"/>
|
|
</audio>
|
|
|
|
<audio style="visibility: hidden;" controls="controls" id="sound_click">
|
|
<source src="click.mp3" type="audio/mpeg"/>
|
|
</audio>
|
|
|
|
|
|
</body>
|
|
</html>
|
|
|
|
|