Apache
tcp/80
openresty
tcp/443
Open service 90.156.201.18:443 · divorex.ru
2026-01-26 04:41
HTTP/1.1 400 Bad Request Server: openresty Date: Mon, 26 Jan 2026 04:41:32 GMT Content-Type: text/html Content-Length: 252 Connection: close Page title: 400 The plain HTTP request was sent to HTTPS port <html> <head><title>400 The plain HTTP request was sent to HTTPS port</title></head> <body> <center><h1>400 Bad Request</h1></center> <center>The plain HTTP request was sent to HTTPS port</center> <hr><center>openresty</center> </body> </html>
Open service 2a00:15f8:a000:5:1:13:8:4ed8:443 · divorex.ru
2026-01-26 04:41
HTTP/1.1 400 Bad Request Server: openresty Date: Mon, 26 Jan 2026 04:41:33 GMT Content-Type: text/html Content-Length: 252 Connection: close Page title: 400 The plain HTTP request was sent to HTTPS port <html> <head><title>400 The plain HTTP request was sent to HTTPS port</title></head> <body> <center><h1>400 Bad Request</h1></center> <center>The plain HTTP request was sent to HTTPS port</center> <hr><center>openresty</center> </body> </html>
Open service 2a00:15f8:a000:5:1:11:8:4ed8:443 · divorex.ru
2026-01-26 04:41
HTTP/1.1 400 Bad Request Server: openresty Date: Mon, 26 Jan 2026 04:41:32 GMT Content-Type: text/html Content-Length: 252 Connection: close Page title: 400 The plain HTTP request was sent to HTTPS port <html> <head><title>400 The plain HTTP request was sent to HTTPS port</title></head> <body> <center><h1>400 Bad Request</h1></center> <center>The plain HTTP request was sent to HTTPS port</center> <hr><center>openresty</center> </body> </html>
Open service 2a00:15f8:a000:5:1:14:8:4ed8:80 · divorex.ru
2026-01-26 04:41
HTTP/1.1 200 OK
Date: Mon, 26 Jan 2026 04:41:32 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 8387
Connection: close
Vary: Accept-Encoding
Server: Apache
Last-Modified: Mon, 21 Jul 2025 09:29:52 GMT
ETag: "20c3-63a6d1e29d1fc"
Accept-Ranges: bytes
Cache-Control: max-age=0
Expires: Mon, 26 Jan 2026 04:41:32 GMT
Page title: Графовая древовидная структура
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Графовая древовидная структура</title>
<style>
body {
margin: 0;
overflow: hidden;
font-family: sans-serif;
}
canvas {
position: absolute;
top: 0; left: 0;
z-index: 0;
}
#controls {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
background: rgba(255,255,255,0.9);
padding: 10px;
border-radius: 8px;
}
button {
margin: 2px;
padding: 6px 12px;
font-size: 16px;
}
</style>
</head>
<body>
<div id="controls">
<button onclick="newNode()">Новый узел</button>
<button onclick="deleteActiveNode()">Удалить</button>
<button onclick="zoomIn()">+</button>
<button onclick="zoomOut()">-</button>
</div>
<canvas id="graphCanvas"></canvas>
<script>
const canvas = document.getElementById("graphCanvas");
const ctx = canvas.getContext("2d");
let nodes = [];
let edges = [];
let scale = 1;
let activeNode = null;
let activeEdge = null;
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
class Node {
constructor(x, y, id) {
this.id = id;
this.radius = Math.max(canvas.width, canvas.height) / 40 * scale;
this.x = Math.max(this.radius, Math.min(x, canvas.width - this.radius));
this.y = Math.max(this.radius, Math.min(y, canvas.height - this.radius));
this.color = 'green';
this.textColor = 'white';
this.fontSize = this.radius / 2;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this === activeNode ? 'orange' : this.color;
ctx.fill();
ctx.font = `${this.fontSize}px Arial`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = this.textColor;
ctx.fillText(this.id, this.x, this.y);
}
isInside(x, y) {
return Math.hypot(this.x - x, this.y - y) <= this.radius;
}
}
class Edge {
constructor(from, to) {
this.from = from;
this.to = to;
this.type = 'line'; // line | arrow | reverse-arrow
this.color = 'blue';
}
draw() {
const dx = this.to.x - this.from.x;
const dy = this.to.y - this.from.y;
const angle = Math.atan2(dy, dx);
const startX = this.from.x + Math.cos(angle) * this.from.radius;
const startY = this.from.y + Math.sin(angle) * this.from.radius;
const endX = this.to.x - Math.cos(angle) * this.to.radius;
const endY = this.to.y - Math.sin(angle) * this.to.radius;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.strokeStyle = this === activeEdge ? 'orange' : this.color;
ctx.lineWidth = this.from.radius / 10;
ctx.stroke();
if (this.type === 'arrow') {
drawArrowHead(endX, endY, angle);
} else if (this.type === 'reverse-arrow') {
drawArrowHead(startX, startY, angle + Math.PI);
}
}
}
function drawArrowHead(x, y, angle) {
const headlen = nodes[0]?.radius / 2 || 10;
const left = angle - Math.PI / 6;
const right = angle + Math.PI / 6;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(left), y - headlen * Math.sin(left));
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(right), y - headlen * Math.sin(right));
ctx.strokeStyle = activeEdge?.type !== 'line' ? 'orange' : 'blue';
ctx.lineWidth = 2;
ctx.stroke();
}
function getNodeAt(x, y) {
return nodes.find(node => node.isInside(x, y));
}
func
Open service 2a00:15f8:a000:5:1:12:8:4ed8:80 · divorex.ru
2026-01-26 04:41
HTTP/1.1 200 OK
Date: Mon, 26 Jan 2026 04:41:32 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 8387
Connection: close
Vary: Accept-Encoding
Server: Apache
Last-Modified: Mon, 21 Jul 2025 09:29:52 GMT
ETag: "20c3-63a6d1e29d1fc"
Accept-Ranges: bytes
Cache-Control: max-age=0
Expires: Mon, 26 Jan 2026 04:41:32 GMT
Page title: Графовая древовидная структура
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Графовая древовидная структура</title>
<style>
body {
margin: 0;
overflow: hidden;
font-family: sans-serif;
}
canvas {
position: absolute;
top: 0; left: 0;
z-index: 0;
}
#controls {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
background: rgba(255,255,255,0.9);
padding: 10px;
border-radius: 8px;
}
button {
margin: 2px;
padding: 6px 12px;
font-size: 16px;
}
</style>
</head>
<body>
<div id="controls">
<button onclick="newNode()">Новый узел</button>
<button onclick="deleteActiveNode()">Удалить</button>
<button onclick="zoomIn()">+</button>
<button onclick="zoomOut()">-</button>
</div>
<canvas id="graphCanvas"></canvas>
<script>
const canvas = document.getElementById("graphCanvas");
const ctx = canvas.getContext("2d");
let nodes = [];
let edges = [];
let scale = 1;
let activeNode = null;
let activeEdge = null;
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
class Node {
constructor(x, y, id) {
this.id = id;
this.radius = Math.max(canvas.width, canvas.height) / 40 * scale;
this.x = Math.max(this.radius, Math.min(x, canvas.width - this.radius));
this.y = Math.max(this.radius, Math.min(y, canvas.height - this.radius));
this.color = 'green';
this.textColor = 'white';
this.fontSize = this.radius / 2;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this === activeNode ? 'orange' : this.color;
ctx.fill();
ctx.font = `${this.fontSize}px Arial`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = this.textColor;
ctx.fillText(this.id, this.x, this.y);
}
isInside(x, y) {
return Math.hypot(this.x - x, this.y - y) <= this.radius;
}
}
class Edge {
constructor(from, to) {
this.from = from;
this.to = to;
this.type = 'line'; // line | arrow | reverse-arrow
this.color = 'blue';
}
draw() {
const dx = this.to.x - this.from.x;
const dy = this.to.y - this.from.y;
const angle = Math.atan2(dy, dx);
const startX = this.from.x + Math.cos(angle) * this.from.radius;
const startY = this.from.y + Math.sin(angle) * this.from.radius;
const endX = this.to.x - Math.cos(angle) * this.to.radius;
const endY = this.to.y - Math.sin(angle) * this.to.radius;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.strokeStyle = this === activeEdge ? 'orange' : this.color;
ctx.lineWidth = this.from.radius / 10;
ctx.stroke();
if (this.type === 'arrow') {
drawArrowHead(endX, endY, angle);
} else if (this.type === 'reverse-arrow') {
drawArrowHead(startX, startY, angle + Math.PI);
}
}
}
function drawArrowHead(x, y, angle) {
const headlen = nodes[0]?.radius / 2 || 10;
const left = angle - Math.PI / 6;
const right = angle + Math.PI / 6;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(left), y - headlen * Math.sin(left));
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(right), y - headlen * Math.sin(right));
ctx.strokeStyle = activeEdge?.type !== 'line' ? 'orange' : 'blue';
ctx.lineWidth = 2;
ctx.stroke();
}
function getNodeAt(x, y) {
return nodes.find(node => node.isInside(x, y));
}
func
Open service 90.156.201.18:80 · divorex.ru
2026-01-26 04:41
HTTP/1.1 200 OK
Date: Mon, 26 Jan 2026 04:41:32 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 8387
Connection: close
Vary: Accept-Encoding
Server: Apache
Last-Modified: Mon, 21 Jul 2025 09:29:52 GMT
ETag: "20c3-63a6d1e29d1fc"
Accept-Ranges: bytes
Cache-Control: max-age=0
Expires: Mon, 26 Jan 2026 04:41:32 GMT
Page title: Графовая древовидная структура
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Графовая древовидная структура</title>
<style>
body {
margin: 0;
overflow: hidden;
font-family: sans-serif;
}
canvas {
position: absolute;
top: 0; left: 0;
z-index: 0;
}
#controls {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
background: rgba(255,255,255,0.9);
padding: 10px;
border-radius: 8px;
}
button {
margin: 2px;
padding: 6px 12px;
font-size: 16px;
}
</style>
</head>
<body>
<div id="controls">
<button onclick="newNode()">Новый узел</button>
<button onclick="deleteActiveNode()">Удалить</button>
<button onclick="zoomIn()">+</button>
<button onclick="zoomOut()">-</button>
</div>
<canvas id="graphCanvas"></canvas>
<script>
const canvas = document.getElementById("graphCanvas");
const ctx = canvas.getContext("2d");
let nodes = [];
let edges = [];
let scale = 1;
let activeNode = null;
let activeEdge = null;
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
class Node {
constructor(x, y, id) {
this.id = id;
this.radius = Math.max(canvas.width, canvas.height) / 40 * scale;
this.x = Math.max(this.radius, Math.min(x, canvas.width - this.radius));
this.y = Math.max(this.radius, Math.min(y, canvas.height - this.radius));
this.color = 'green';
this.textColor = 'white';
this.fontSize = this.radius / 2;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this === activeNode ? 'orange' : this.color;
ctx.fill();
ctx.font = `${this.fontSize}px Arial`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = this.textColor;
ctx.fillText(this.id, this.x, this.y);
}
isInside(x, y) {
return Math.hypot(this.x - x, this.y - y) <= this.radius;
}
}
class Edge {
constructor(from, to) {
this.from = from;
this.to = to;
this.type = 'line'; // line | arrow | reverse-arrow
this.color = 'blue';
}
draw() {
const dx = this.to.x - this.from.x;
const dy = this.to.y - this.from.y;
const angle = Math.atan2(dy, dx);
const startX = this.from.x + Math.cos(angle) * this.from.radius;
const startY = this.from.y + Math.sin(angle) * this.from.radius;
const endX = this.to.x - Math.cos(angle) * this.to.radius;
const endY = this.to.y - Math.sin(angle) * this.to.radius;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.strokeStyle = this === activeEdge ? 'orange' : this.color;
ctx.lineWidth = this.from.radius / 10;
ctx.stroke();
if (this.type === 'arrow') {
drawArrowHead(endX, endY, angle);
} else if (this.type === 'reverse-arrow') {
drawArrowHead(startX, startY, angle + Math.PI);
}
}
}
function drawArrowHead(x, y, angle) {
const headlen = nodes[0]?.radius / 2 || 10;
const left = angle - Math.PI / 6;
const right = angle + Math.PI / 6;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(left), y - headlen * Math.sin(left));
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(right), y - headlen * Math.sin(right));
ctx.strokeStyle = activeEdge?.type !== 'line' ? 'orange' : 'blue';
ctx.lineWidth = 2;
ctx.stroke();
}
function getNodeAt(x, y) {
return nodes.find(node => node.isInside(x, y));
}
func
Open service 90.156.201.12:443 · divorex.ru
2026-01-26 04:41
HTTP/1.1 400 Bad Request Server: openresty Date: Mon, 26 Jan 2026 04:41:32 GMT Content-Type: text/html Content-Length: 252 Connection: close Page title: 400 The plain HTTP request was sent to HTTPS port <html> <head><title>400 The plain HTTP request was sent to HTTPS port</title></head> <body> <center><h1>400 Bad Request</h1></center> <center>The plain HTTP request was sent to HTTPS port</center> <hr><center>openresty</center> </body> </html>
Open service 2a00:15f8:a000:5:1:11:8:4ed8:80 · divorex.ru
2026-01-26 04:41
HTTP/1.1 200 OK
Date: Mon, 26 Jan 2026 04:41:33 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 8387
Connection: close
Vary: Accept-Encoding
Server: Apache
Last-Modified: Mon, 21 Jul 2025 09:29:52 GMT
ETag: "20c3-63a6d1e29d1fc"
Accept-Ranges: bytes
Cache-Control: max-age=0
Expires: Mon, 26 Jan 2026 04:41:33 GMT
Page title: Графовая древовидная структура
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Графовая древовидная структура</title>
<style>
body {
margin: 0;
overflow: hidden;
font-family: sans-serif;
}
canvas {
position: absolute;
top: 0; left: 0;
z-index: 0;
}
#controls {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
background: rgba(255,255,255,0.9);
padding: 10px;
border-radius: 8px;
}
button {
margin: 2px;
padding: 6px 12px;
font-size: 16px;
}
</style>
</head>
<body>
<div id="controls">
<button onclick="newNode()">Новый узел</button>
<button onclick="deleteActiveNode()">Удалить</button>
<button onclick="zoomIn()">+</button>
<button onclick="zoomOut()">-</button>
</div>
<canvas id="graphCanvas"></canvas>
<script>
const canvas = document.getElementById("graphCanvas");
const ctx = canvas.getContext("2d");
let nodes = [];
let edges = [];
let scale = 1;
let activeNode = null;
let activeEdge = null;
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
class Node {
constructor(x, y, id) {
this.id = id;
this.radius = Math.max(canvas.width, canvas.height) / 40 * scale;
this.x = Math.max(this.radius, Math.min(x, canvas.width - this.radius));
this.y = Math.max(this.radius, Math.min(y, canvas.height - this.radius));
this.color = 'green';
this.textColor = 'white';
this.fontSize = this.radius / 2;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this === activeNode ? 'orange' : this.color;
ctx.fill();
ctx.font = `${this.fontSize}px Arial`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = this.textColor;
ctx.fillText(this.id, this.x, this.y);
}
isInside(x, y) {
return Math.hypot(this.x - x, this.y - y) <= this.radius;
}
}
class Edge {
constructor(from, to) {
this.from = from;
this.to = to;
this.type = 'line'; // line | arrow | reverse-arrow
this.color = 'blue';
}
draw() {
const dx = this.to.x - this.from.x;
const dy = this.to.y - this.from.y;
const angle = Math.atan2(dy, dx);
const startX = this.from.x + Math.cos(angle) * this.from.radius;
const startY = this.from.y + Math.sin(angle) * this.from.radius;
const endX = this.to.x - Math.cos(angle) * this.to.radius;
const endY = this.to.y - Math.sin(angle) * this.to.radius;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.strokeStyle = this === activeEdge ? 'orange' : this.color;
ctx.lineWidth = this.from.radius / 10;
ctx.stroke();
if (this.type === 'arrow') {
drawArrowHead(endX, endY, angle);
} else if (this.type === 'reverse-arrow') {
drawArrowHead(startX, startY, angle + Math.PI);
}
}
}
function drawArrowHead(x, y, angle) {
const headlen = nodes[0]?.radius / 2 || 10;
const left = angle - Math.PI / 6;
const right = angle + Math.PI / 6;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(left), y - headlen * Math.sin(left));
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(right), y - headlen * Math.sin(right));
ctx.strokeStyle = activeEdge?.type !== 'line' ? 'orange' : 'blue';
ctx.lineWidth = 2;
ctx.stroke();
}
function getNodeAt(x, y) {
return nodes.find(node => node.isInside(x, y));
}
func
Open service 90.156.201.28:443 · divorex.ru
2026-01-26 04:41
HTTP/1.1 400 Bad Request Server: openresty Date: Mon, 26 Jan 2026 04:41:32 GMT Content-Type: text/html Content-Length: 252 Connection: close Page title: 400 The plain HTTP request was sent to HTTPS port <html> <head><title>400 The plain HTTP request was sent to HTTPS port</title></head> <body> <center><h1>400 Bad Request</h1></center> <center>The plain HTTP request was sent to HTTPS port</center> <hr><center>openresty</center> </body> </html>
Open service 90.156.201.98:443 · divorex.ru
2026-01-26 04:41
HTTP/1.1 400 Bad Request Server: openresty Date: Mon, 26 Jan 2026 04:41:31 GMT Content-Type: text/html Content-Length: 252 Connection: close Page title: 400 The plain HTTP request was sent to HTTPS port <html> <head><title>400 The plain HTTP request was sent to HTTPS port</title></head> <body> <center><h1>400 Bad Request</h1></center> <center>The plain HTTP request was sent to HTTPS port</center> <hr><center>openresty</center> </body> </html>
Open service 90.156.201.28:80 · divorex.ru
2026-01-26 04:41
HTTP/1.1 200 OK
Date: Mon, 26 Jan 2026 04:41:32 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 8387
Connection: close
Vary: Accept-Encoding
Server: Apache
Last-Modified: Mon, 21 Jul 2025 09:29:52 GMT
ETag: "20c3-63a6d1e29d1fc"
Accept-Ranges: bytes
Cache-Control: max-age=0
Expires: Mon, 26 Jan 2026 04:41:32 GMT
Page title: Графовая древовидная структура
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Графовая древовидная структура</title>
<style>
body {
margin: 0;
overflow: hidden;
font-family: sans-serif;
}
canvas {
position: absolute;
top: 0; left: 0;
z-index: 0;
}
#controls {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
background: rgba(255,255,255,0.9);
padding: 10px;
border-radius: 8px;
}
button {
margin: 2px;
padding: 6px 12px;
font-size: 16px;
}
</style>
</head>
<body>
<div id="controls">
<button onclick="newNode()">Новый узел</button>
<button onclick="deleteActiveNode()">Удалить</button>
<button onclick="zoomIn()">+</button>
<button onclick="zoomOut()">-</button>
</div>
<canvas id="graphCanvas"></canvas>
<script>
const canvas = document.getElementById("graphCanvas");
const ctx = canvas.getContext("2d");
let nodes = [];
let edges = [];
let scale = 1;
let activeNode = null;
let activeEdge = null;
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
class Node {
constructor(x, y, id) {
this.id = id;
this.radius = Math.max(canvas.width, canvas.height) / 40 * scale;
this.x = Math.max(this.radius, Math.min(x, canvas.width - this.radius));
this.y = Math.max(this.radius, Math.min(y, canvas.height - this.radius));
this.color = 'green';
this.textColor = 'white';
this.fontSize = this.radius / 2;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this === activeNode ? 'orange' : this.color;
ctx.fill();
ctx.font = `${this.fontSize}px Arial`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = this.textColor;
ctx.fillText(this.id, this.x, this.y);
}
isInside(x, y) {
return Math.hypot(this.x - x, this.y - y) <= this.radius;
}
}
class Edge {
constructor(from, to) {
this.from = from;
this.to = to;
this.type = 'line'; // line | arrow | reverse-arrow
this.color = 'blue';
}
draw() {
const dx = this.to.x - this.from.x;
const dy = this.to.y - this.from.y;
const angle = Math.atan2(dy, dx);
const startX = this.from.x + Math.cos(angle) * this.from.radius;
const startY = this.from.y + Math.sin(angle) * this.from.radius;
const endX = this.to.x - Math.cos(angle) * this.to.radius;
const endY = this.to.y - Math.sin(angle) * this.to.radius;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.strokeStyle = this === activeEdge ? 'orange' : this.color;
ctx.lineWidth = this.from.radius / 10;
ctx.stroke();
if (this.type === 'arrow') {
drawArrowHead(endX, endY, angle);
} else if (this.type === 'reverse-arrow') {
drawArrowHead(startX, startY, angle + Math.PI);
}
}
}
function drawArrowHead(x, y, angle) {
const headlen = nodes[0]?.radius / 2 || 10;
const left = angle - Math.PI / 6;
const right = angle + Math.PI / 6;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(left), y - headlen * Math.sin(left));
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(right), y - headlen * Math.sin(right));
ctx.strokeStyle = activeEdge?.type !== 'line' ? 'orange' : 'blue';
ctx.lineWidth = 2;
ctx.stroke();
}
function getNodeAt(x, y) {
return nodes.find(node => node.isInside(x, y));
}
func
Open service 90.156.201.98:80 · divorex.ru
2026-01-26 04:41
HTTP/1.1 200 OK
Date: Mon, 26 Jan 2026 04:41:32 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 8387
Connection: close
Vary: Accept-Encoding
Server: Apache
Last-Modified: Mon, 21 Jul 2025 09:29:52 GMT
ETag: "20c3-63a6d1e29d1fc"
Accept-Ranges: bytes
Cache-Control: max-age=0
Expires: Mon, 26 Jan 2026 04:41:32 GMT
Page title: Графовая древовидная структура
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Графовая древовидная структура</title>
<style>
body {
margin: 0;
overflow: hidden;
font-family: sans-serif;
}
canvas {
position: absolute;
top: 0; left: 0;
z-index: 0;
}
#controls {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
background: rgba(255,255,255,0.9);
padding: 10px;
border-radius: 8px;
}
button {
margin: 2px;
padding: 6px 12px;
font-size: 16px;
}
</style>
</head>
<body>
<div id="controls">
<button onclick="newNode()">Новый узел</button>
<button onclick="deleteActiveNode()">Удалить</button>
<button onclick="zoomIn()">+</button>
<button onclick="zoomOut()">-</button>
</div>
<canvas id="graphCanvas"></canvas>
<script>
const canvas = document.getElementById("graphCanvas");
const ctx = canvas.getContext("2d");
let nodes = [];
let edges = [];
let scale = 1;
let activeNode = null;
let activeEdge = null;
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
class Node {
constructor(x, y, id) {
this.id = id;
this.radius = Math.max(canvas.width, canvas.height) / 40 * scale;
this.x = Math.max(this.radius, Math.min(x, canvas.width - this.radius));
this.y = Math.max(this.radius, Math.min(y, canvas.height - this.radius));
this.color = 'green';
this.textColor = 'white';
this.fontSize = this.radius / 2;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this === activeNode ? 'orange' : this.color;
ctx.fill();
ctx.font = `${this.fontSize}px Arial`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = this.textColor;
ctx.fillText(this.id, this.x, this.y);
}
isInside(x, y) {
return Math.hypot(this.x - x, this.y - y) <= this.radius;
}
}
class Edge {
constructor(from, to) {
this.from = from;
this.to = to;
this.type = 'line'; // line | arrow | reverse-arrow
this.color = 'blue';
}
draw() {
const dx = this.to.x - this.from.x;
const dy = this.to.y - this.from.y;
const angle = Math.atan2(dy, dx);
const startX = this.from.x + Math.cos(angle) * this.from.radius;
const startY = this.from.y + Math.sin(angle) * this.from.radius;
const endX = this.to.x - Math.cos(angle) * this.to.radius;
const endY = this.to.y - Math.sin(angle) * this.to.radius;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.strokeStyle = this === activeEdge ? 'orange' : this.color;
ctx.lineWidth = this.from.radius / 10;
ctx.stroke();
if (this.type === 'arrow') {
drawArrowHead(endX, endY, angle);
} else if (this.type === 'reverse-arrow') {
drawArrowHead(startX, startY, angle + Math.PI);
}
}
}
function drawArrowHead(x, y, angle) {
const headlen = nodes[0]?.radius / 2 || 10;
const left = angle - Math.PI / 6;
const right = angle + Math.PI / 6;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(left), y - headlen * Math.sin(left));
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(right), y - headlen * Math.sin(right));
ctx.strokeStyle = activeEdge?.type !== 'line' ? 'orange' : 'blue';
ctx.lineWidth = 2;
ctx.stroke();
}
function getNodeAt(x, y) {
return nodes.find(node => node.isInside(x, y));
}
func
Open service 90.156.201.12:80 · divorex.ru
2026-01-26 04:41
HTTP/1.1 200 OK
Date: Mon, 26 Jan 2026 04:41:32 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 8387
Connection: close
Vary: Accept-Encoding
Server: Apache
Last-Modified: Mon, 21 Jul 2025 09:29:52 GMT
ETag: "20c3-63a6d1e29d1fc"
Accept-Ranges: bytes
Cache-Control: max-age=0
Expires: Mon, 26 Jan 2026 04:41:32 GMT
Page title: Графовая древовидная структура
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Графовая древовидная структура</title>
<style>
body {
margin: 0;
overflow: hidden;
font-family: sans-serif;
}
canvas {
position: absolute;
top: 0; left: 0;
z-index: 0;
}
#controls {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
background: rgba(255,255,255,0.9);
padding: 10px;
border-radius: 8px;
}
button {
margin: 2px;
padding: 6px 12px;
font-size: 16px;
}
</style>
</head>
<body>
<div id="controls">
<button onclick="newNode()">Новый узел</button>
<button onclick="deleteActiveNode()">Удалить</button>
<button onclick="zoomIn()">+</button>
<button onclick="zoomOut()">-</button>
</div>
<canvas id="graphCanvas"></canvas>
<script>
const canvas = document.getElementById("graphCanvas");
const ctx = canvas.getContext("2d");
let nodes = [];
let edges = [];
let scale = 1;
let activeNode = null;
let activeEdge = null;
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
class Node {
constructor(x, y, id) {
this.id = id;
this.radius = Math.max(canvas.width, canvas.height) / 40 * scale;
this.x = Math.max(this.radius, Math.min(x, canvas.width - this.radius));
this.y = Math.max(this.radius, Math.min(y, canvas.height - this.radius));
this.color = 'green';
this.textColor = 'white';
this.fontSize = this.radius / 2;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this === activeNode ? 'orange' : this.color;
ctx.fill();
ctx.font = `${this.fontSize}px Arial`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = this.textColor;
ctx.fillText(this.id, this.x, this.y);
}
isInside(x, y) {
return Math.hypot(this.x - x, this.y - y) <= this.radius;
}
}
class Edge {
constructor(from, to) {
this.from = from;
this.to = to;
this.type = 'line'; // line | arrow | reverse-arrow
this.color = 'blue';
}
draw() {
const dx = this.to.x - this.from.x;
const dy = this.to.y - this.from.y;
const angle = Math.atan2(dy, dx);
const startX = this.from.x + Math.cos(angle) * this.from.radius;
const startY = this.from.y + Math.sin(angle) * this.from.radius;
const endX = this.to.x - Math.cos(angle) * this.to.radius;
const endY = this.to.y - Math.sin(angle) * this.to.radius;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.strokeStyle = this === activeEdge ? 'orange' : this.color;
ctx.lineWidth = this.from.radius / 10;
ctx.stroke();
if (this.type === 'arrow') {
drawArrowHead(endX, endY, angle);
} else if (this.type === 'reverse-arrow') {
drawArrowHead(startX, startY, angle + Math.PI);
}
}
}
function drawArrowHead(x, y, angle) {
const headlen = nodes[0]?.radius / 2 || 10;
const left = angle - Math.PI / 6;
const right = angle + Math.PI / 6;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(left), y - headlen * Math.sin(left));
ctx.moveTo(x, y);
ctx.lineTo(x - headlen * Math.cos(right), y - headlen * Math.sin(right));
ctx.strokeStyle = activeEdge?.type !== 'line' ? 'orange' : 'blue';
ctx.lineWidth = 2;
ctx.stroke();
}
function getNodeAt(x, y) {
return nodes.find(node => node.isInside(x, y));
}
func