29 Commits
lab4 ... hw5

Author SHA1 Message Date
73ea28eab6 finished table controls 2025-12-12 11:35:56 +10:00
ea0b091c8a table added 2025-12-12 10:57:38 +10:00
c53abdb678 added table controls 2025-12-12 10:10:30 +10:00
2b4a36c1ff details BEM 2025-12-11 22:26:18 +10:00
03e7b28167 details page in progress 2025-12-11 21:58:56 +10:00
a25b444c01 stylus mixins 2025-12-11 20:47:40 +10:00
d54afa7b2e BEM naming 2025-12-11 20:41:43 +10:00
01dfe8011d main page working 2025-12-11 19:59:17 +10:00
deeb9dbd5c added stylus template 2025-12-10 12:24:54 +10:00
b653d69e77 updating styles 2025-11-28 10:15:15 +10:00
6720bfd450 adding pages 2025-11-28 01:31:50 +10:00
726b6e7adb aboba mv node 2025-11-28 01:23:28 +10:00
093d57a619 starting hw 2025-11-28 01:23:09 +10:00
d468d0efb4 added lab5 2025-11-28 00:47:07 +10:00
dc039301f6 margin fix for images 2025-11-27 22:07:43 +10:00
fa9ac16021 fixed images 2025-11-27 22:06:00 +10:00
e1e6e066ce added footer 2025-11-14 13:18:52 +10:00
977735a6a3 lab-4 2025-11-14 12:52:31 +10:00
58427fae25 basic structure added for lab4 2025-11-14 02:37:59 +10:00
654e9d2734 updated hw 2025-11-14 02:23:20 +10:00
9aadb0ce16 possibly added hw 2025-11-14 02:13:50 +10:00
b3ebd075b2 adding real lab4 2025-11-14 01:03:54 +10:00
c32a4a6fc2 OMAGAH O HELL NAH WTF MAAAN 2025-11-14 00:33:21 +10:00
c36e781e05 preparations for hw 2025-11-14 00:32:28 +10:00
dd9ee56a1a stray divs removed 2025-11-13 17:00:08 +10:00
80176d2a2e Merge branch 'lab4' 2025-11-13 16:56:40 +10:00
62f1791203 Merge branch 'hw3' 2025-11-13 16:47:36 +10:00
abc37ce5a0 hw3 done 2025-11-13 16:42:59 +10:00
a8f0326fa0 hw3 start 2025-10-31 10:12:28 +10:00
92 changed files with 14900 additions and 3155 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
node_modules
to_reform

View File

@@ -1,37 +0,0 @@
import csv
def create_html_table_from_csv(csv_path, html_path):
try:
with open(csv_path, 'r', newline='', encoding='utf-8') as csv_file:
reader = csv.reader(csv_file)
header = next(reader)
with open(html_path, 'w', encoding='utf-8') as html_file:
html_file.write('<table class="data-table">\n')
html_file.write('<thead>\n')
html_file.write('<tr>\n')
for column_header in header:
html_file.write(f'<th>{column_header}</th>\n')
html_file.write('</tr>\n')
html_file.write('</thead>\n')
html_file.write('<tbody>\n')
for row in reader:
html_file.write('<tr>\n')
for cell in row:
html_file.write(f'<td>{cell}</td>\n')
html_file.write('</tr>\n')
html_file.write('</tbody>\n')
html_file.write('</table>\n')
print(f"Successfully created {html_path} from {csv_path}")
except:
pass
if __name__ == '__main__':
csv_file_name = 'temp_sensor_data.csv'
html_file_name = 'test.html'
create_html_table_from_csv(csv_file_name, html_file_name)

View File

@@ -1,104 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
Embedded Details
</title>
</head>
<body bgcolor="#F0F8FF">
<details>
<summary>Menu</summary>
<ul>
<li><a href="./index.html">Home</a></li>
<li><a href="./embeded_details.html"><h4>Embeded Details</h4></a></li>
<li><a href="./opencv_details.html">OpenCV Details</a></li>
<li><a href="./photography_details.html">Photography Details</a></li>
<li><a href="./table.html">Table with filters (not working yet)</a></li>
<li><a href="./images/institute.png">Institute</a></li>
</ul>
</details>
<h2 align="center">Embedded Details</h2>
<hr width="800" align="center">
<p align="center">
<img src="./images/esp32.png" alt="ESP32" height="150">
<img src="./images/arduino.png" alt="Arduino" height="150">
<img src="./images/stm32.png" alt="STM32" height="150">
</p>
<p align="justify">My programming path started with embeded systems,
i love all the low level things that Mcu could do with just a little bit of code,
sometimes build or flashing progress could take some time to get a hand of , but after that everething usualy
goes smooth</p>
<p align="justify">The first MCU i tried was a ATmega328P,
after some time i was surprised with the debug capabilities on the Stm32
and now i'm working with esp32-s3 , that's a good chip, has internal JTAG and all the shiny wireless interfaces
but feels faulty
for some reason <i> regular segfaults with CDC</i></p>
<h3 align="center">Microcontroller Comparison Table</h3>
<table border="1" align="center" cellpadding="6" cellspacing="0">
<tr>
<th>Board/MCU</th>
<th>UART Count</th>
<th>Dynamic UART Assignment</th>
<th>ADC Channels</th>
<th>Debug Support</th>
<th>Flash Size</th>
<th>Wireless Connectivity</th>
</tr>
<tr>
<td>ESP32</td>
<td>3</td>
<td>Yes (via IO MUX)</td>
<td>18</td>
<td>JTAG, Serial</td>
<td>4MB (typical)</td>
<td>Wi-Fi, Bluetooth</td>
</tr>
<tr>
<td>ESP32-S3</td>
<td>3</td>
<td>Yes (via IO MUX)</td>
<td>20</td>
<td>JTAG, Serial</td>
<td>8MB (typical)</td>
<td>Wi-Fi, Bluetooth LE</td>
</tr>
<tr>
<td>ESP-01</td>
<td>1</td>
<td>No</td>
<td>1</td>
<td>Serial only</td>
<td>512KB/1MB</td>
<td>Wi-Fi</td>
</tr>
<tr>
<td>Arduino Uno (ATmega328P)</td>
<td>1</td>
<td>No</td>
<td>6</td>
<td>Serial, DebugWire</td>
<td>32KB</td>
<td>None</td>
</tr>
<tr>
<td>Blue Pill (STM32F103C8T6)</td>
<td>3</td>
<td>Yes (remappable)</td>
<td>10</td>
<td>SWD, Serial</td>
<td>64KB/128KB</td>
<td>None</td>
</tr>
</table>
<p align="right"> no rpi pico here , the build system has won over my temper</p>
</body>
</html>

214
index.css
View File

@@ -1,214 +0,0 @@
/* menu part */
.menu {
border-top: double 4px silver;
border-bottom: double 4px silver;
text-align: right;
font-size: 0;
}
.menu-item {
display: inline-block;
width: 8%;
height: 3em;
line-height: 3em; /* to align to center */
text-align: center;
vertical-align: middle;
margin: 0 1%;
overflow: hidden;
text-overflow: ellipsis ;
font-size: medium;
}
.menu .selected {
color: green;
font-weight: bold;
border-left: double 4px silver;
border-right: double 4px silver;
}
.menu .menu-header {
color: green;
font-weight: bold;
float: left;
}
.menu a {
color: black;
}
/* 4 images part */
.images-container *{
border:solid thin black;
}
.images-container {
width: 90%;
height: 200pt;
margin: auto;
overflow: hidden;
}
.half-size {
width: 49%;
margin: 0.2%;
float: left;
}
.quarter-size {
width: 24%;
margin: 0.2%;
float: left;
}
.image-column-container {
width: 24%;
height:100%;
margin: 0.15%;
float: left;
}
.image-column-container > div {
width: 100%;
height: 50%;
margin-bottom: 1.4%;
overflow: hidden;
/* text-align: center; */
}
.images-container img{
width:100%
}
/* main block part */
.main-block{
width:80%;
margin:1.2% auto;
}
.main-column{
display: inline-block;
width:25%;
}
.main-center{
vertical-align: top;
width: 48%;
height:100%;
display: inline-block;
}
.img-margin-fix {
margin-right:10px;
}
.info-block{
height:10%;
padding: 5%;
}
.bg-aqua{
background: #80DEEA;
}
.bg-grey{
background: #B0BFC6;
}
.bg-blue{
background: #BBDEFA;
}
.bg-yellow{
background: #FFE0B2;
}
.info-block-header{
display: block;
margin:auto;
text-align: center;
font-size: 1.5em;
font-weight: bold;
}
.info-block-text{
display: block;
text-align: justify;
}
.info-block-image{
margin: 0% 5% 5%;
width:90%;
overflow: hidden;
}
.info-block-image >img{
width: 100%;
}
.rounded{
border-radius: 20px;
overflow: hidden;
}
.info-block-button{
float: right;
color:white;
background-color: #2294F4;
border-radius: 5px;
}
.button-left{
float: left;
}
.pad-down{
margin-top: 40%;
bottom: 0;
}
/* main block center part */
.center-upper, .center-lower, .center-center{
/* background-color: lightblue; DEBUG*/
margin:5%;
}
.info-block-image-small{
display: inline-block;
width: 20%;
height: 100%;
background-color:black ;
overflow: hidden;
vertical-align: top;
}
.info-block-image-small >img{
width: 100%;
}
.align-left{
text-align: left;
}
.align-right{
text-align: right;
}
.inline {
display: inline-block;
}
.info-block-wide-text-container{
width: 75%;
margin: 0 1%;
}
.link{
display: block;
color:gray;
margin-bottom: 0px;
white-space: nowrap;
}
.info-block-image-center{
display: inline-block;
width: 50%;
/* height: 100px; */
background-color:black ;
overflow: hidden;
vertical-align: top;
}
.info-block-image-center >img{
width: 100%;
}
.small-w{
vertical-align: top;
width: 23%;
}

View File

@@ -1,169 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
"Portfolio"
</title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div class="menu">
<div class="menu-item menu-header">Portfolio Site </div>
<a href="./index.html">
<div class="menu-item selected">Home</div>
</a>
<a href="./embeded_details.html">
<div class="menu-item">Embedded</div>
</a>
<a href="./opencv_details.html">
<div class="menu-item">OpenCV</div>
</a>
<a href="./photography_details.html">
<div class="menu-item">Photography</div>
</a>
<a href="./table.html">
<div class="menu-item">Table</div>
</a>
<a href="./images/institute.png">
<div class="menu-item">Institute</div>
</a>
</div>
<div class="images-container">
<div class="half-size">
<img src="./images/arduino.png" alt="Arduino">
</div>
<div class="quarter-size">
<img src="./images/esp32.png" alt="ESP32">
</div>
<div class="image-column-container">
<div>
<img src="./images/institute.png" alt="ESP32">
</div>
<div>
<img src="./images/arucos.png" alt="ESP32">
</div>
</div>
</div>
<div class="main-block">
<div class="main-column">
<div class="info-block rounded bg-aqua">
<span class="info-block-header">Embedded Systems</span>
<span class="info-block-text">THad a serval projects with different MCUs and wrote firmware for them.
My main stack consists of Platformio+EspIdf or Arduino, also tried STM32
</span>
<div class="info-block-image rounded">
<img src="./images/16x9/esp32.png" alt="ESP32">
</div>
<button type="button" class="info-block-button">More info»</button>
</div>
<div class="info-block rounded bg-grey pad-down">
<span class="info-block-header">OpenCV</span>
<span class="info-block-text">I love when programs are able to see things or recognise them
so i had serval projects involding image processing
Sadly i'm used to opencv binding in python and not C++ , but that is solvable)
</span>
<div class="info-block-image rounded">
<img src="./images/16x9/opencv.png" alt="ESP32">
</div>
<button type="button" class="info-block-button">More info»</button>
</div>
</div>
<div class="main-center">
<div class="center-upper">
<div class="info-block-image-small ">
<img src="./images/sqstm32.png" alt="stm32">
</div>
<div class="inline info-block-wide-text-container ">
<span class="info-block-header align-left">STM 32</span>
<span class="info-block-text ">Chinese STM32 microcontrollers are affordable and compatible with
STM32 tools but may face flashing issues due to bootloader differences. Proper connections and
reliable tools can help resolve these.</span>
</span>
<a class="link align-left" href="./index.html">More info»</a>
</div>
</div>
<div class="center-center">
<span class="info-block-header">Stephen King's books</span>
<span class="info-block-text inline small-w">Stephen King's books are a fascinating blend of horror,
suspense, and deep
character development. His storytelling captivates readers and keeps them on the edge of their
seats.</span>
<div class="info-block-image-center">
<img src="./images/institute.png" alt="ESP32">
</div>
<span class="info-block-text inline small-w">
Especially I love the institute, its architecture, and the vibrant community it fosters. The
institute has been a source of inspiration and growth for me, providing countless opportunities to
learn and collaborate.
<a class="link small-w" href="./index.html">More info»</a>
</span>
</div>
<div class="center-lower">
<div class="inline info-block-wide-text-container">
<span class="info-block-header align-right">Arucos</span>
<span class="info-block-text ">ArUco markers are widely used in computer vision for camera
calibration, pose estimation, and augmented reality applications. They are square fiducial
markers with a unique binary pattern that can be easily detected and identified in
images.</span>
</span>
<a class="link align-right" href="./index.html">More info»</a>
</div>
<div class="info-block-image-small">
<img src="./images/sqarucos.png" alt="ESP32">
</div>
</div>
</div>
<div class="main-column">
<div class="info-block rounded bg-blue">
<div class="info-block-image rounded">
<img src="./images/16x9/image0.png" alt="Photography">
</div>
<span class="info-block-header">Photography</span>
<span class="info-block-text">Capturing moments through the lens is a passion of mine. I enjoy exploring
different perspectives and techniques to create different visuals.</span>
<button type="button" class="info-block-button button-left">More info»</button>
</div>
<div class="info-block rounded bg-yellow pad-down">
<div class="info-block-image rounded">
<img src="./images/16x9/AQ_monitor.png" alt="Air Quality Monitor">
</div>
<span class="info-block-header">IoT and Air Quality Monitoring</span>
<span class="info-block-text">The Internet of Things (IoT) enables devices to communicate and share data
seamlessly. One of the applications is air quality monitoring, where sensors collect data on
pollutants and environmental conditions, providing real-time insights to improve health and
safety.</span>
<button type="button" class="info-block-button button-left">More info»</button>
</div>
</div>
</div>
<p>Author: Kulesh <br>
Group: Б9123-09.03.04</p>
</body>
</html>

6
labs/fake-lab4/css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

208
labs/fake-lab4/index.html Normal file
View File

@@ -0,0 +1,208 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Лабораторная работа Bootstrap</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/bootstrap.bundle.min.js"></script>
<style>
.lead{
text-align: justify;
}
@media (max-width: 576px) {
.lead{
font-size: 1rem;
}
}
</style>
</head>
<body>
<header>
<nav class="navbar navbar-expand-md bg-light navbar-light">
<!-- Заголовок -->
<a class="navbar-brand" href="#">Топ высотных зданий</a>
<!-- Кнопка для свернутого меню -->
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#menu">
<span class="navbar-toggler-icon"></span>
</button>
<!-- меню -->
<div class="collapse navbar-collapse" id="menu">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link active" href="#">Главная</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Список зданий</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Контакты</a>
</li>
</ul>
<!-- форма для поиска -->
<form class="d-flex">
<input class="form-control" type="text" placeholder="Найти">
<button class="btn btn-outline-success" type="submit">Найти</button>
</form>
</div>
</nav>
</header>
<div class="row gy-3 text-center d-none d-md-flex">
<div class="col-lg-2 col-md-4 col-6 img-fluid img-thumbnail">
<img src="images/image1.jpg" alt="">
</div>
<div class="col-lg-2 col-md-4 col-6 img-fluid img-thumbnail">
<img src="images/image2.jpg" alt="">
</div>
<div class="col-lg-2 col-md-4 col-6 img-fluid img-thumbnail">
<img src="images/image12.jpg" alt="">
</div>
<div class="col-lg-2 col-md-4 col-6 img-fluid img-thumbnail">
<img src="images/image4.jpg" alt="">
</div>
<div class="col-lg-2 col-md-4 col-6 img-fluid img-thumbnail">
<img src="images/image5.jpg" alt="">
</div>
<div class="col-lg-2 col-md-4 col-6 img-fluid img-thumbnail">
<img src="images/image6.jpg" alt="">
</div>
</div>
<div id="gallery" class="carousel slide carousel-dark d-block d-md-none " data-bs-ride="carousel">
<!-- Содержимое галереи -->
<div class="carousel-inner">
<div class="carousel-item active">
</div>
<div class="carousel-item ">
<img src="images/image1.jpg" class="d-block mx-auto" alt="">
</div>
<div class="carousel-item">
<img src="images/image2.jpg" class="d-block mx-auto" alt="">
</div>
<div class="carousel-item">
<img src="images/image12.jpg" class="d-block mx-auto" alt="">
</div>
<div class="carousel-item">
<img src="images/image4.jpg" class="d-block mx-auto" alt="">
</div>
<div class="carousel-item">
<img src="images/image5.jpg" class="d-block mx-auto" alt="">
</div>
<div class="carousel-item">
<img src="images/image6.jpg" class="d-block mx-auto" alt="">
</div>
</div>
<!-- Кнопки управления -->
<button class="carousel-control-prev" type="button" data-bs-target="#gallery" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Предыдущий</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#gallery" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Следующий</span>
</button>
</div>
<main class="container">
<div class="row">
<div class="col-md-9">
<h2>
CN Tower, <span class="text-muted">Торонто, Канада</span>
</h2>
<p class="lead">
553,3-метровая телевизионная башня. Была самым высоким свободно стоящим сооружением в мире с 1976 по
2007 год,
а также до сих пор остаётся таковым в Западном полушарии. Является символом Торонто.
</p>
<p class="lead">
Земляные работы для сооружения железобетонной конструкции с последующим
натяжением арматуры весом 130 000 т начались 12 февраля 1973 г., а уже 2 апреля 1975 г. возведение
башни было завершено.
</p>
<p class="lead">
Башня используется для телекоммуникационных нужд. Кроме того, башня используется как обзорная
площадка.
Также на башне имеется вращающийся ресторан.
</p>
<p class="lead">
На высоте 447 м находится астрономическая обсерватория.
</p>
</div>
<div class="col-md-3">
<img src="images/image9.jpg">
</div>
</div>
<div class="row order flex-row-reverse">
<div class="col-md-9">
<h2>
Бурдж-Халифа, <span class="text-muted">Дубай, ОАЭ</span>
</h2>
<p class="lead">
Небоскрёб высотой 828 метров, самое высокое сооружение в мире. Форма здания напоминает сталагмит.
</p>
<p class="lead">
Строительство небоскрёба началось в 2004 году и шло со скоростью 1—2 этажа в неделю. Ежедневно на строительстве
работало до 12 000 рабочих. На его создание ушло около 320 тыс. м³ бетона и более 60 тыс. тонн стальной арматуры.
Бетонные работы были завершены после возведения 160 этажа, далее шла сборка 180-метрового шпиля из металлических
конструкций.
</p>
<p class="lead">
Специально для «Бурдж-Халифа» была разработана особая марка бетона, который выдерживает температуру до +50 °C.
Бетонную смесь укладывали только ночью, а в раствор добавляли лёд.
</p>
</div>
<div class="col-md-3">
<img src="images/image13.jpg">
</div>
</div>
<div class="row">
<div class="col-md-9">
<h2>
Небесное дерево, <span class="text-muted">Токио, Япония</span>
</h2>
<p class="lead">
Телевизионная башня в районе Сумида самая высокая среди телебашен мира. Высота телебашни вместе с антенной составляет 634 метра.
Высота башни была выбрана так, чтобы цифры: 6 (на старом японском «му»), 3 («са»), 4 («си») были созвучны «Мусаси» —
названию исторической области, где находится современный Токио.
</p>
<p class="lead">
Здание напоминает пятиярусную пагоду, что хорошо сочетается с историческим районом Асакуса на другом берегу реки.
Основание башни напоминает штатив; с высоты примерно 350 м она имеет цилиндрическую форму, позволяющую наслаждаться
панорамными видами реки и города.
</p>
<p class="lead">
Имеются две наблюдательные площадки: одна на высоте 350 м (вместимостью 2000 человек), другая на высоте 450 м
(вместимостью 900 человек).
</p>
</div>
<div class="col-md-3">
<img src="images/image11.jpg">
</div>
</div>
</main>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

BIN
labs/lab4/images/c.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
labs/lab4/images/java.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
labs/lab4/images/prolog.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
labs/lab4/images/python.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
labs/lab4/images/ruby.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -8,201 +8,92 @@
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/bootstrap.bundle.min.js"></script>
<style>
.lead{
.lead {
text-align: justify;
}
@media (max-width: 576px) {
.lead{
font-size: 1rem;
}
}
</style>
</head>
<body>
<header>
<nav class="navbar navbar-expand-md bg-light navbar-light">
<!-- Заголовок -->
<a class="navbar-brand" href="#">Топ высотных зданий</a>
<!-- Кнопка для свернутого меню -->
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#menu">
<span class="navbar-toggler-icon"></span>
</button>
<!-- меню -->
<div class="collapse navbar-collapse" id="menu">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link active" href="#">Главная</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Список зданий</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Контакты</a>
</li>
</ul>
<!-- форма для поиска -->
<form class="d-flex">
<input class="form-control" type="text" placeholder="Найти">
<button class="btn btn-outline-success" type="submit">Найти</button>
</form>
<body class="container">
<div class="row bg-lg-light justify-content-center">
<div class="col-sm-12 col-md-6 col-xl-4 p-4 text-center">
<h3 class="bg-light d-sm-block d-lg-inline my-0 p-2">
JavaScript
</h3>
<div class="bg-light d-lg-flex align-self-center">
<p class="lead px-2 m-0">
разработан в 1996 году, автор - американский программист Брендан Айк.
</p>
<img src="images/javascript.jpg" class="d-block m-auto w-50">
</div>
</nav>
</header>
<div class="row gy-3 text-center d-none d-md-flex">
<div class="col-lg-2 col-md-4 col-6 img-fluid img-thumbnail">
<img src="images/image1.jpg" alt="">
</div>
<div class="col-lg-2 col-md-4 col-6 img-fluid img-thumbnail">
<img src="images/image2.jpg" alt="">
</div>
<div class="col-lg-2 col-md-4 col-6 img-fluid img-thumbnail">
<img src="images/image12.jpg" alt="">
</div>
<div class="col-lg-2 col-md-4 col-6 img-fluid img-thumbnail">
<img src="images/image4.jpg" alt="">
</div>
<div class="col-lg-2 col-md-4 col-6 img-fluid img-thumbnail">
<img src="images/image5.jpg" alt="">
</div>
<div class="col-lg-2 col-md-4 col-6 img-fluid img-thumbnail">
<img src="images/image6.jpg" alt="">
</div>
</div>
<div id="gallery" class="carousel slide carousel-dark d-block d-md-none " data-bs-ride="carousel">
<!-- Содержимое галереи -->
<div class="carousel-inner">
<div class="carousel-item active">
<div class="row bg-lg-light justify-content-center">
<div class="col-sm-12 col-md-6 col-xl-4 p-4 text-center">
<h3 class="bg-light d-sm-block d-lg-inline my-0 p-2">
Java
</h3>
<div class="bg-light d-lg-flex align-self-center">
<p class="lead px-2 m-0"></p>
разработан в 19901996 годах канадским программистом Джеймсом Гослингом.
</p>
<img src="images/java.jpg" class="d-block m-auto w-50">
</div>
<div class="carousel-item ">
<img src="images/image1.jpg" class="d-block mx-auto" alt="">
</div>
<div class="carousel-item">
<img src="images/image2.jpg" class="d-block mx-auto" alt="">
</div>
<div class="carousel-item">
<img src="images/image12.jpg" class="d-block mx-auto" alt="">
</div>
<div class="carousel-item">
<img src="images/image4.jpg" class="d-block mx-auto" alt="">
</div>
<div class="carousel-item">
<img src="images/image5.jpg" class="d-block mx-auto" alt="">
</div>
<div class="carousel-item">
<img src="images/image6.jpg" class="d-block mx-auto" alt="">
</div>
</div>
<div class="col-sm-12 col-md-6 col-xl-4 p-4 text-center">
<h3 class="bg-light d-sm-block d-lg-inline my-0 p-2">
C
</h3>
<div class="bg-light d-lg-flex align-self-center">
<p class="lead px-2 m-0">
разработан в 19691973 годах сотрудником Bell Labs Деннисом Ритчи.
</p>
<img src="images/c.jpg" class="d-block m-auto w-50">
</div>
</div>
</div>
<!-- Кнопки управления -->
<button class="carousel-control-prev" type="button" data-bs-target="#gallery" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Предыдущий</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#gallery" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Следующий</span>
</button>
<div class="row bg-lg-light justify-content-center">
<div class="col-sm-12 col-md-6 col-xl-4 p-4 text-center">
<h3 class="bg-light d-sm-block d-lg-inline my-0 p-2">
Prolog
</h3>
<div class="bg-light d-lg-flex align-self-center">
<p class="lead px-2 m-0">
разработан в 1972 году, автор - французский программист Ален Колмероэ.
</p>
<img src="images/prolog.jpg" class="d-block m-auto w-50">
</div>
</div>
<div class="col-sm-12 col-md-6 col-xl-4 p-4 text-center">
<h3 class="bg-light d-sm-block d-lg-inline my-0 p-2">
Python
</h3>
<div class="bg-light d-lg-flex align-self-center">
<p class="lead px-2 m-0">
создан в 19891991 годах голландским программистом Гвидо ван Россумом.
</p>
<img src="images/python.jpg" class="d-block m-auto w-50">
</div>
</div>
<div class="col-sm-12 col-md-6 col-xl-4 p-4 text-center">
<h3 class="bg-light d-sm-block d-lg-inline my-0 p-2">
Ruby
</h3>
<div class="bg-light d-lg-flex align-self-center">
<p class="lead px-2 m-0">
разработан в 1993-1995 годах, автор - японский программист Юкихиро Мацумото.
</p>
<img src="images/ruby.jpg" class="d-block m-auto w-50">
</div>
</div>
</div>
<main class="container">
<div class="row">
<div class="col-md-9">
<h2>
CN Tower, <span class="text-muted">Торонто, Канада</span>
</h2>
<p class="lead">
553,3-метровая телевизионная башня. Была самым высоким свободно стоящим сооружением в мире с 1976 по
2007 год,
а также до сих пор остаётся таковым в Западном полушарии. Является символом Торонто.
</p>
<p class="lead">
Земляные работы для сооружения железобетонной конструкции с последующим
натяжением арматуры весом 130 000 т начались 12 февраля 1973 г., а уже 2 апреля 1975 г. возведение
башни было завершено.
</p>
<p class="lead">
Башня используется для телекоммуникационных нужд. Кроме того, башня используется как обзорная
площадка.
Также на башне имеется вращающийся ресторан.
</p>
<p class="lead">
На высоте 447 м находится астрономическая обсерватория.
</p>
</div>
<div class="col-md-3">
<img src="images/image9.jpg">
</div>
</div>
<div class="row order flex-row-reverse">
<div class="col-md-9">
<h2>
Бурдж-Халифа, <span class="text-muted">Дубай, ОАЭ</span>
</h2>
<p class="lead">
Небоскрёб высотой 828 метров, самое высокое сооружение в мире. Форма здания напоминает сталагмит.
</p>
<p class="lead">
Строительство небоскрёба началось в 2004 году и шло со скоростью 1—2 этажа в неделю. Ежедневно на строительстве
работало до 12 000 рабочих. На его создание ушло около 320 тыс. м³ бетона и более 60 тыс. тонн стальной арматуры.
Бетонные работы были завершены после возведения 160 этажа, далее шла сборка 180-метрового шпиля из металлических
конструкций.
</p>
<p class="lead">
Специально для «Бурдж-Халифа» была разработана особая марка бетона, который выдерживает температуру до +50 °C.
Бетонную смесь укладывали только ночью, а в раствор добавляли лёд.
</p>
</div>
<div class="col-md-3">
<img src="images/image13.jpg">
</div>
</div>
<div class="row">
<div class="col-md-9">
<h2>
Небесное дерево, <span class="text-muted">Токио, Япония</span>
</h2>
<p class="lead">
Телевизионная башня в районе Сумида самая высокая среди телебашен мира. Высота телебашни вместе с антенной составляет 634 метра.
Высота башни была выбрана так, чтобы цифры: 6 (на старом японском «му»), 3 («са»), 4 («си») были созвучны «Мусаси» —
названию исторической области, где находится современный Токио.
</p>
<p class="lead">
Здание напоминает пятиярусную пагоду, что хорошо сочетается с историческим районом Асакуса на другом берегу реки.
Основание башни напоминает штатив; с высоты примерно 350 м она имеет цилиндрическую форму, позволяющую наслаждаться
панорамными видами реки и города.
</p>
<p class="lead">
Имеются две наблюдательные площадки: одна на высоте 350 м (вместимостью 2000 человек), другая на высоте 450 м
(вместимостью 900 человек).
</p>
</div>
<div class="col-md-3">
<img src="images/image11.jpg">
</div>
</div>
</main>
</body>
</html>

1
labs/lab5/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
node_modules

6695
labs/lab5/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

30
labs/lab5/package.json Normal file
View File

@@ -0,0 +1,30 @@
{
"name": "template_pug",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --mode production",
"serve": "webpack serve --open --mode development",
"dev": "webpack --mode development",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"chokidar": "^4.0.3",
"css-loader": "^6.8.1",
"filemanager-webpack-plugin": "^8.0.0",
"glob": "^11.0.3",
"html-webpack-plugin": "^5.5.3",
"pug": "^2.0.4",
"pug-loader": "^2.4.0",
"style-loader": "^3.3.3",
"stylus": "^0.61.0",
"stylus-loader": "^7.1.3",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
}
}

View File

@@ -0,0 +1,36 @@
block variables
- var title = 'Самые высокие здания и сооружения'
-
var dictMenu = {'Главная': 'index.html',
'Небоскребы' : "#",
'Башни': "#",
'Список': "#"
}
- var listImages = ['image1.jpg', 'image2.jpg', 'image3.jpg', 'image4.jpg', 'image5.jpg']
-
var listSections = [
{'header' : 'Бурдж-Халифа в Дубае, ОАЭ',
'image' : 'image7.jpg',
'text' : 'Небоскрёб высотой 828 метров, самое высокое сооружение в мире. Форма здания напоминает сталагмит.'
},
{'header' : 'Токийское небесное дерево, Япония',
'image' : 'image6.jpg',
'text' : 'Телевизионная башня в районе Сумида самая высокая среди телебашен мира. Высота телебашни вместе с антенной составляет 634 метра.'
},
{'header' : 'CN Tower, Канада',
'image' : 'image8.jpg',
'text' : 'Си-Эн Тауэр — самое высокое свободно стоящее сооружение в мире с 1976 по 2007 год. Его высота составляет 553,33 метра.'
}
]
-
var structures = [
{
menuItem: "Ворота Запада, США",
pict: "image1_big.jpg",
firstP: `Арка в Сент-Луисе, также известная под именем «Врата на запад» — мемориал, являющийся частью Джефферсоновского национального экспансиального мемориала, а также визитной карточкой Сент-Луиса, штат Миссури, США.`,
secondP: `Арка была спроектирована финско-американским архитектором Ээро Саариненом в 1947 году. Её высота 192 метра в самой высокой точке, ширина её основания также 192 метра.
Таким образом арка является самым высоким памятником на территории США. Её строительство началось 12 февраля 1963 года и было закончено 28 октября 1965 года. Памятник открылся для посетителей 24 июля 1967 года.`
}
]

View File

@@ -0,0 +1,2 @@
h2= 'Hello World!'
img(src= require("../images/img1.jpg"))

View File

@@ -0,0 +1,20 @@
include ../components/data.pug
mixin createMenu(menu, active)
each value, key in menu
if active == key
a.active(href= value)= key
else
a(href= value)= key
mixin createMenuBuild(menu, active)
each value, key in menu
a(href= value)= key
a.active(href= "")= active
mixin createSection()
each item in listSections
section
h3= item.header
img(src= require("../images/" + item.image))
p= item.text
a(href="#") &hellip;

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

1
labs/lab5/src/index.js Normal file
View File

@@ -0,0 +1 @@
import './styles/main.styl'

View File

@@ -0,0 +1,19 @@
extends template
block nav
title #{structures[0].menuItem}
nav
+createMenuBuild(dictMenu, structures[0].menuItem)
block header
h2= structures[0].menuItem
block content
img.big(src= require("../images/" + structures[0].pict))
section
p= structures[0].firstP
p= structures[0].secondP

View File

@@ -0,0 +1,19 @@
extends template
block nav
nav
+createMenu(dictMenu, 'Главная')
block content
div.images
each pict in listImages
a(href= "building.html")
img(src= require("../images/" + pict))
article
each item in listSections
section
h3= item.header
img(src= require("../images/" + item.image))
p= item.text
a(href="#") &hellip;

View File

@@ -0,0 +1,18 @@
include ../components/mixin.pug
include ../components/data.pug
doctype html
html(lang="ru")
head
title #{title}
body
block header
h2= title
block nav
block content
block footer
footer
h4 &copy; Пример html-страницы

View File

@@ -0,0 +1,84 @@
colorText = #6f6d6d
back(size)
background-color #f1f1f1
box-shadow 4px 5px 10px rgba(0, 0, 0, 0.4)
padding: size + "%"
margin 0 0 1% 0
html
color colorText
nav
back(0)
text-align right
& a
display inline-block
padding 1%
color colorText
text-decoration: none
&:hover
&.active
background-color #f87777
color #f8f8f8
div.images
display grid
grid-template-columns repeat(5, 1fr)
grid-gap 0.5%
back(1)
& img
width: 100%
@media (max-width: 600px)
grid-template-rows repeat(5, 1fr)
grid-template-columns 1fr
& img
width 80%
margin auto
article
width 80%
margin auto
display grid
grid-template-columns repeat(3, 1fr)
grid-gap 4%
@media (max-width: 600px)
grid-template-rows repeat(3, 1fr)
grid-template-columns 1fr
& section
display grid
grid-template-columns 1fr 2fr
grid-gap 2%
align-items center
back(2)
& h3
grid-column 1/3
margin 0
text-align center
& img
width: 100%
footer
background-color colorText
color white
@media (max-width: 600px)
margin 3vh 0
& h4
padding:10px
.big
width 50vw
@media (max-width: 600px)
width 100vw
section
display grid
grid-template-columns 1fr 1fr
@media (max-width: 600px)
grid-template-columns 1fr

View File

@@ -0,0 +1,69 @@
const HtmlWebpackPlugin = require("html-webpack-plugin");
const FileManagerPlugin = require("filemanager-webpack-plugin");
const path = require("path");
const fs = require("fs");
const pagesDir = path.join(__dirname, "src", "pages");
const pages = fs.readdirSync(pagesDir).filter(file => file.endsWith(".pug"));
module.exports = {
output: {
path: path.join(__dirname, "dist"),
filename: "index.[contenthash].js",
assetModuleFilename: path.join("images", "[name].[contenthash][ext]"),
},
entry: path.join(__dirname, "src", "index.js"),
module: {
rules: [
{
test: /\.pug$/,
loader: "pug-loader",
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: "asset/resource",
},
{
test: /\.svg$/,
type: "asset/resource",
generator: {
filename: path.join("icons", "[name].[contenthash][ext]"),
},
},
{
test: /\.styl$/,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
},
{
loader: "stylus-loader",
},
],
},
],
},
plugins: [
...pages.map(
(page) =>
new HtmlWebpackPlugin({
template: path.join(pagesDir, page),
filename: page.replace(".pug", ".html"),
})
),
new FileManagerPlugin({
events: {
onStart: {
delete: ["dist"],
},
},
}),
],
devServer: {
watchFiles: path.join(__dirname, "src"),
port: 9000,
},
};

View File

@@ -1,48 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
OpenCV Details
</title>
</head>
<body bgcolor="#F0F8FF">
<details>
<summary>Menu</summary>
<ul>
<li><a href="./index.html">Home</a></li>
<li><a href="./embeded_details.html"><h4>Embeded Details</h4></a></li>
<li><a href="./opencv_details.html">OpenCV Details</a></li>
<li><a href="./photography_details.html">Photography Details</a></li>
<li><a href="./table.html">Table with filters (not working yet)</a></li>
<li><a href="./images/institute.png">Institute</a></li>
</ul>
</details>
<h2 align="center">OpenCV Details</h2>
<hr width="800" align="center">
<p align="center">
<img src="./images/opencv.png" alt="OpenCV" height="150" align="top">
as mentioned before i love when programs are able to <i>see</i> things <br>
my experience with opencv started with simple hight level functions like detectCircle or findContours and
etc...<br>
Right now i'm crawling deeper into the library , and the idea of standartisation of parameters between different
cameras is appealig to me <br>
so i'm trying to understand how all that works from the math side<br>
Additionally, I'm exploring Re-Identification (ReId) techniques,
they are used for recognizing and tracking objects across different camera views or consecutive frames.
</p>
<hr width="500" align="center">
<p>
One of many projects I've worked on is <a href="https://github.com/OkunElya/ArucoNGP-MapCreator"
target="_blank">ArucoNGP-MapCreator</a>.<br>
The idea was to create a relative map of Aruco markers just from photos of pairs (or more) of them.<br>
It can also estimate the camera's position in the world relative to a specific marker, using only images
containing any marker.<br>
It was also my first deep dive into linear algebra.<br>
</p>
</body>
</html>

6692
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

30
package.json Normal file
View File

@@ -0,0 +1,30 @@
{
"name": "template_pug",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --mode production",
"serve": "webpack serve --open --mode development",
"dev": "webpack --mode development",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"chokidar": "^4.0.3",
"css-loader": "^6.8.1",
"filemanager-webpack-plugin": "^8.0.0",
"glob": "^11.0.3",
"html-webpack-plugin": "^5.5.3",
"pug": "^2.0.4",
"pug-loader": "^2.4.0",
"style-loader": "^3.3.3",
"stylus": "^0.61.0",
"stylus-loader": "^7.1.3",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
}
}

View File

@@ -1,42 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
Photography Details
</title>
</head>
<body bgcolor="#F0F8FF">
<details>
<summary>Menu</summary>
<ul>
<li><a href="./index.html">Home</a></li>
<li><a href="./embeded_details.html">Embeded Details</a></li>
<li><a href="./opencv_details.html">OpenCV Details</a></li>
<li><a href="./photography_details.html"><h4>Photography Details</h4></a></li>
<li><a href="./table.html">Table with filters (not working yet)</a></li>
<li><a href="./images/institute.png">Institute))</a></li>
</ul>
</details>
<h2 align="center">Photography Details</h2>
<hr width="800" align="center">
<p align="center">
Usually i capture landcape scenes with SLR camera, the main workhorse is Nikon D3100 with kit and 70-210mm
</p>
<p align="center">
<img src="images/photos/image0.png" alt="Photo 0" width="200">
<img src="images/photos/image1.png" alt="Photo 1" width="200">
<img src="images/photos/image2.png" alt="Photo 2" width="200">
</p>
<p align="center">
<img src="images/photos/image3.png" alt="Photo 3" width="200">
<img src="images/photos/image4.png" alt="Photo 4" width="200">
<img src="images/photos/image5.png" alt="Photo 5" width="200">
</p>
</body>
</html>

306
src/components/data.pug Normal file
View File

@@ -0,0 +1,306 @@
block variables
-
var navbarItems = {
Home: './index.html',
Embedded: './embeded_details.html',
OpenCV: './opencv_details.html',
Photography: './photography-details.html',
Table: './table.html',
Institute: './images/institute.png'
};
var smallCards = [
{
header: 'Заголовок',
text: '3D printers are versatile tools used for creating prototypes, custom parts, and artistic designs. They work by layering materials.',
image: require('../images/16x10/3d-printer.jpeg'),
imageAlt: '3D Printer',
link: '#',
},
{
header: 'BLHeli ESCs',
text: 'BLHeli ESCs are electronic speed controllers designed for drones, offering smooth and precise motor control.',
image: require('../images/16x10/blheli-esc.jpeg'),
imageAlt: 'BLHeli ESC',
link: '#',
},
{
header: 'Raspberry Pi Nano',
text: 'Raspberry Pi Nano is a compact computer ideal for learning, prototyping, and IoT projects. It is highly energy-efficient.',
image: require('../images/16x10/rpi-nano.jpeg'),
imageAlt: 'Raspberry Pi Nano',
link: '#',
},
{
header: 'Smart Thermostats',
text: 'Smart thermostats help regulate home temperatures efficiently, saving energy and enhancing comfort with automation.',
image: require('../images/16x10/thermostat.jpeg'),
imageAlt: 'Smart Thermostat',
link: '#',
}
];
var galleryImages= [
{ src: require('../images/sqarucos.png'), alt: 'ESP32'},
{ src: require('../images/sqstm32.png'), alt: 'Arduino'},
{ src: require('../images/sqesp32.png'), alt: 'STM32'}
];
var locationFilters = [
{ id: 'loc_kitchen', value: 'Kitchen', label: 'Kitchen' },
{ id: 'loc_living', value: 'Living Room', label: 'Living Room' },
{ id: 'loc_balcony', value: 'Balcony', label: 'Balcony' },
{ id: 'loc_bedroom', value: 'Bedroom', label: 'Bedroom' }
];
var sensorTypeFilters = [
{ id: 'type_xiaomi', value: 'Xiaomi', label: 'Xiaomi' },
{ id: 'type_bmp220', value: 'Bmp220', label: 'Bmp220' },
{ id: 'type_scd30', value: 'Scd30(Internal)', label: 'Scd30(Internal)' },
{ id: 'type_bmp280', value: 'Bmp280', label: 'Bmp280' }
];
var sortOptions = [
{ value: '', label: '-- None --' },
{ value: 'SensorID', label: 'SensorID' },
{ value: 'Timestamp', label: 'Time' },
{ value: 'BatteryLevel', label: 'BatteryLevel' },
{ value: 'Temperature', label: 'Temperature' },
{ value: 'Humidity', label: 'Humidity' }
];
var axisOptions = [
{ id: 'x_time', value: 'Time', label: 'Time', checked: true },
{ id: 'x_battery', value: 'BatteryLevel', label: 'BatteryLevel', checked: false },
{ id: 'x_temperature', value: 'Temperature', label: 'Temperature', checked: false },
{ id: 'x_humidity', value: 'Humidity', label: 'Humidity', checked: false }
];
var valueOptions = [
{ id: 'val_temperature', value: 'AverageTemperature', label: 'Average Temperature', checked: true },
{ id: 'val_humidity', value: 'Humidity', label: 'Average Humidity', checked: false },
{ id: 'val_battery', value: 'BatteryLevel', label: 'Average BatteryLevel', checked: false }
]
var sensorData = [
{
sensorId: 'TEMP-001',
location: 'Balcony',
timestamp: '2025-10-03T03:41:50Z',
temperature: 19.4,
tempDifference: -0.2,
sensorType: 'Bmp220',
batteryLevel: 95,
humidity: 38.1,
lastCalibrationDate: '2025-07-26'
},
{
sensorId: 'TEMP-003',
location: 'Bedroom',
timestamp: '2025-10-03T03:42:46Z',
temperature: 18.2,
tempDifference: -0.1,
sensorType: 'Xiaomi',
batteryLevel: 75,
humidity: 45.5,
lastCalibrationDate: '2025-07-21'
},
{
sensorId: 'TEMP-004',
location: 'Balcony',
timestamp: '2025-10-03T03:43:48Z',
temperature: 24.1,
tempDifference: 0.1,
sensorType: 'Xiaomi',
batteryLevel: 72,
humidity: 50.5,
lastCalibrationDate: '2025-08-30'
},
{
sensorId: 'TEMP-001',
location: 'Balcony',
timestamp: '2025-10-03T03:44:34Z',
temperature: 19.1,
tempDifference: -0.3,
sensorType: 'Bmp220',
batteryLevel: 95,
humidity: 56.5,
lastCalibrationDate: '2025-07-26'
},
{
sensorId: 'TEMP-006',
location: 'Kitchen',
timestamp: '2025-10-03T03:45:46Z',
temperature: 22.8,
tempDifference: 0.0,
sensorType: 'Scd30(Internal)',
batteryLevel: 80,
humidity: 41.4,
lastCalibrationDate: '2025-09-10'
},
{
sensorId: 'TEMP-010',
location: 'Balcony',
timestamp: '2025-10-03T03:46:18Z',
temperature: 21.7,
tempDifference: 0.5,
sensorType: 'Scd30(Internal)',
batteryLevel: 79,
humidity: 59.8,
lastCalibrationDate: '2025-08-07'
},
{
sensorId: 'TEMP-006',
location: 'Balcony',
timestamp: '2025-10-03T03:47:05Z',
temperature: 22.7,
tempDifference: -0.1,
sensorType: 'Scd30(Internal)',
batteryLevel: 80,
humidity: 36.1,
lastCalibrationDate: '2025-09-10'
},
{
sensorId: 'TEMP-006',
location: 'Bedroom',
timestamp: '2025-10-03T03:48:13Z',
temperature: 22.9,
tempDifference: 0.2,
sensorType: 'Scd30(Internal)',
batteryLevel: 80,
humidity: 56.1,
lastCalibrationDate: '2025-09-10'
},
{
sensorId: 'TEMP-005',
location: 'Living Room',
timestamp: '2025-10-03T03:49:03Z',
temperature: 24.4,
tempDifference: 0.4,
sensorType: 'Bmp180',
batteryLevel: 91,
humidity: 30.1,
lastCalibrationDate: '2025-08-07'
},
{
sensorId: 'TEMP-001',
location: 'Kitchen',
timestamp: '2025-10-03T03:50:24Z',
temperature: 19.1,
tempDifference: 0.0,
sensorType: 'Bmp220',
batteryLevel: 95,
humidity: 64.8,
lastCalibrationDate: '2025-07-26'
},
{
sensorId: 'TEMP-008',
location: 'Living Room',
timestamp: '2025-10-03T03:51:12Z',
temperature: 21.9,
tempDifference: -0.1,
sensorType: 'Scd30(Internal)',
batteryLevel: 92,
humidity: 36.0,
lastCalibrationDate: '2025-08-02'
},
{
sensorId: 'TEMP-009',
location: 'Balcony',
timestamp: '2025-10-03T03:51:46Z',
temperature: 22.3,
tempDifference: 0.0,
sensorType: 'Xiaomi',
batteryLevel: 76,
humidity: 74.0,
lastCalibrationDate: '2025-09-17'
},
{
sensorId: 'TEMP-003',
location: 'Kitchen',
timestamp: '2025-10-03T03:52:23Z',
temperature: 18.4,
tempDifference: 0.2,
sensorType: 'Xiaomi',
batteryLevel: 75,
humidity: 45.2,
lastCalibrationDate: '2025-07-21'
},
{
sensorId: 'TEMP-010',
location: 'Living Room',
timestamp: '2025-10-03T03:53:44Z',
temperature: 21.8,
tempDifference: 0.1,
sensorType: 'Scd30(Internal)',
batteryLevel: 79,
humidity: 36.3,
lastCalibrationDate: '2025-08-07'
},
{
sensorId: 'TEMP-001',
location: 'Kitchen',
timestamp: '2025-10-03T03:54:46Z',
temperature: 18.7,
tempDifference: -0.4,
sensorType: 'Bmp220',
batteryLevel: 95,
humidity: 44.3,
lastCalibrationDate: '2025-07-26'
},
{
sensorId: 'TEMP-006',
location: 'Bedroom',
timestamp: '2025-10-03T03:55:24Z',
temperature: 23.3,
tempDifference: 0.4,
sensorType: 'Scd30(Internal)',
batteryLevel: 80,
humidity: 55.9,
lastCalibrationDate: '2025-09-10'
},
{
sensorId: 'TEMP-002',
location: 'Kitchen',
timestamp: '2025-10-03T03:55:57Z',
temperature: 17.7,
tempDifference: -0.5,
sensorType: 'Scd30(Internal)',
batteryLevel: 93,
humidity: 70.2,
lastCalibrationDate: '2025-08-30'
},
{
sensorId: 'TEMP-002',
location: 'Balcony',
timestamp: '2025-10-03T03:57:05Z',
temperature: 17.4,
tempDifference: -0.3,
sensorType: 'Scd30(Internal)',
batteryLevel: 93,
humidity: 66.7,
lastCalibrationDate: '2025-08-30'
},
{
sensorId: 'TEMP-009',
location: 'Living Room',
timestamp: '2025-10-03T03:58:28Z',
temperature: 22.6,
tempDifference: 0.3,
sensorType: 'Xiaomi',
batteryLevel: 76,
humidity: 56.4,
lastCalibrationDate: '2025-09-17'
},
{
sensorId: 'TEMP-004',
location: 'Bedroom',
timestamp: '2025-10-03T03:59:51Z',
temperature: 24.3,
tempDifference: 0.2,
sensorType: 'Xiaomi',
batteryLevel: 72,
humidity: 47.3,
lastCalibrationDate: '2025-08-30'
}
];

View File

@@ -0,0 +1,24 @@
include mixins.pug
html
head
meta(charset="UTF-8")
block title
title Details Page
body
block navbar
+navbarMixin("")
.details
header.details__header
block header
h1 Default Header
.details__content
.details__text
block text
p Default text content
.details__gallery
block gallery
p No images available

158
src/components/mixins.pug Normal file
View File

@@ -0,0 +1,158 @@
include data.pug
mixin navbarMixin(selectedItem)
.navbar
each navbarUrl,navbarName in navbarItems
if navbarName == selectedItem
a.navbar__link-wrapper(href=navbarUrl)
.navbar__item.navbar__item_selected #{navbarName}
else
a.navbar__link-wrapper(href=navbarUrl)
.navbar__item #{navbarName}
mixin infoCardsMinxin()
each cardData in smallCards
.small-card
.small-card__content
h3.small-card__header #{cardData.header}
p.small-card__text #{cardData.text}
a.small-card__link(href=cardData.link) Подробнее»
.small-card__image
img(src=cardData.image alt=cardData.imageAlt)
mixin galleryMixin()
each img in galleryImages
img.gallery__image(src=img.src alt=img.alt)
mixin filtersMixin()
details.filters
summary.filters__summary Filters
form.filters__form
fieldset.filters__fieldset
.filter-group
i.filter-group__label
b Location
br
.filter-group__items
each filter in locationFilters
input.filter-group__checkbox(type="checkbox" id=filter.id name="location" value=filter.value)
span #{filter.label}
br
.filter-group
i.filter-group__label
b Sensor Type
br
.filter-group__items
each filter in sensorTypeFilters
input.filter-group__checkbox(type="checkbox" id=filter.id name="sensor_type" value=filter.value)
span #{filter.label}
br
.filter-group
i.filter-group__label
b Numeric Values
br
.filter-group__range
span Temperature from:
input.filter-group__input(type="number" name="temp_min" placeholder="20")
span to:
input.filter-group__input(type="number" name="temp_max" placeholder="30")
br
span Humidity from:
input.filter-group__input(type="number" name="humidity_min" placeholder="40")
span to:
input.filter-group__input(type="number" name="humidity_max" placeholder="60")
br
.filter-group
i.filter-group__label
b Device Specific Filters
br
.filter-group__items
span Sensor Name:
input.filter-group__input(type="text" name="sensor_name")
br
span Days Since Calibration (max):
input.filter-group__input(type="number" name="calibration_days" placeholder="30")
br
.filter-group
i.filter-group__label
b Measurement Period
br
.filter-group__dates
span From:
input.filter-group__input(type="date" name="date_from")
br
span To:
input.filter-group__input(type="date" name="date_to")
br
.filter-group__buttons
input.filter-group__button.filter-group__button--submit(type="submit" value="Apply Filters")
input.filter-group__button.filter-group__button--reset(type="reset" value="Reset Filters")
mixin sortLevel(level)
.sort-level
i.sort-level__label
b Sort Level #{level}
br
label.sort-level__field-label(for=`sort${level}`) Field:
select.sort-level__select(id=`sort${level}` name=`sort${level}`)
each option in sortOptions
option(value=option.value) #{option.label}
label.sort-level__reverse-label(for=`sort${level}_reverse`)
input.sort-level__checkbox(type="checkbox" id=`sort${level}_reverse` name=`sort${level}_reverse`)
span Reverse
br
if level === '3'
input.sort-level__submit(type="submit" value="Sort")
else
br
mixin sortingMixin()
- const sortLevels = ['1', '2', '3'];
details.sorting
summary.sorting__summary Sortings
form.sorting__form
fieldset.sorting__fieldset
each level in sortLevels
+sortLevel(level)
mixin graphXOption(option)
if option.checked
input.axis-group__radio(type="radio" id=option.id name="x_axis" value=option.value checked)
else
input.axis-group__radio(type="radio" id=option.id name="x_axis" value=option.value)
label.axis-group__option-label(for=option.id) #{option.label}
br
mixin graphYOption(option)
if option.checked
input.values-group__checkbox(type="checkbox" id=option.id name="values" value=option.value checked)
else
input.values-group__checkbox(type="checkbox" id=option.id name="values" value=option.value)
label.values-group__option-label(for=option.id) #{option.label}
br
mixin graphMixin()
details.graph
summary.graph__summary Graph
form.graph__form
fieldset.graph__fieldset
.axis-group
i.axis-group__label
b X axis
br
.axis-group__options
each option in axisOptions
+graphXOption(option)
.values-group
i.values-group__label
b Values
br
.values-group__options
each option in valueOptions
+graphYOption(option)
button.values-group__button(type="submit" id="build_graph" name="build_graph") Build

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

View File

Before

Width:  |  Height:  |  Size: 347 KiB

After

Width:  |  Height:  |  Size: 347 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

Before

Width:  |  Height:  |  Size: 5.2 MiB

After

Width:  |  Height:  |  Size: 5.2 MiB

View File

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 99 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 MiB

After

Width:  |  Height:  |  Size: 3.9 MiB

View File

Before

Width:  |  Height:  |  Size: 4.4 MiB

After

Width:  |  Height:  |  Size: 4.4 MiB

View File

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
src/images/remote.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

BIN
src/images/sqesp32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

View File

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View File

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 99 KiB

3
src/index.js Normal file
View File

@@ -0,0 +1,3 @@
import './styles/index.styl'
import './styles/details.styl'
import './styles/table.styl'

51
src/pages/index.pug Normal file
View File

@@ -0,0 +1,51 @@
include ../components/mixins.pug
-
const infoBlockA = {
header: "Embedded Systems",
text: "Had a serval projects with different MCUs and wrote firmware for them. My main stack consists of Platformio+EspIdf or Arduino, also tried STM32 asdadas",
description: "I love embeded development beceuse of autonomity of produced devices, the redices are not dependant on any other hardware and can work autunomously",
img: require('../images/AQ_monitor.png'),
imgAlt: "ESP32"
}
const infoBlockB = {
header: "Embedded Systems",
text: "Had a serval projects with different MCUs and wrote firmware for them. My main stack consists of Platformio+EspIdf or Arduino, also tried STM32",
description: "I love embeded development device because of autonomity of produced devices, the devices are not dependant on any other hardware and can work autunomously or off the grid",
img: require('../images/remote.jpeg'),
imgAlt: "ESP32"
}
html(lang="en")
head
meta(charset="UTF-8")
title Portfolio
body
+navbarMixin("Home")
.gallery
+galleryMixin()
.main-container
.main-container__content
article.info-block
h2.info-block__header #{infoBlockA.header}
.info-block__container.info-block__container_layout-a
p.info-block__text #{infoBlockA.text}
.info-block__details
p.info-block__description #{infoBlockA.description}
a.info-block__link(href="#") More info
img.info-block__image(src=infoBlockA.img alt=infoBlockA.imgAlt)
article.info-block
h2.info-block__header #{infoBlockB.header}
.info-block__container.info-block__container_layout-b
p.info-block__text #{infoBlockB.text}
img.info-block__image(src=infoBlockB.img alt=infoBlockB.imgAlt)
.info-block__details
p.info-block__description #{infoBlockB.description}
a.info-block__link(href="./photography-details.html") More info
.sidebar
+infoCardsMinxin()

View File

@@ -0,0 +1,22 @@
extends ../components/details-template.pug
block title
title Photography Portfolio - Details
block navbar
+navbarMixin("Photography")
block header
h1.details__title Photography
p.details__description I prefer landscape photography.
block text
p.details__text-content D3100 -> SLT A58.
block gallery
.details__gallery-item
img.details__gallery-image(src=require('../images/photos/image0.png') alt="Photography 1")
.details__gallery-item
img.details__gallery-image(src=require('../images/photos/image1.png') alt="Photography 2")
.details__gallery-item
img.details__gallery-image(src=require('../images/photos/image2.png') alt="Photography 3")

25
src/pages/table.pug Normal file
View File

@@ -0,0 +1,25 @@
include ../components/mixins.pug
include ../components/data.pug
head
title table
body
+navbarMixin("Table")
.table-controls
+filtersMixin()
+sortingMixin()
+graphMixin()
table.table
tbody.table-content
each dataItem,index in sensorData
if index == 0
tr.table-content__table-header
each value,header in dataItem
th #{header}
tr.table-content__table-row
each value,header in dataItem
td #{value}

58
src/styles/details.styl Normal file
View File

@@ -0,0 +1,58 @@
.details
margin 0 auto
padding 20px
.details__header
margin-bottom 20px
text-align center
.details__title
margin-bottom 5px
.details__description
margin auto
.details__content
display flex
gap 40px
align-items flex-start
.details__text
flex 1
text-align justify
.details__text-content
margin auto 30px
.details__gallery
display flex
flex-direction column
gap 20px
margin auto
.details__gallery-item
overflow hidden
border-radius 8px
box-shadow 0 4px 12px rgba(0, 0, 0, 0.1)
transition transform 0.3s ease, box-shadow 0.3s ease
&:hover
transform translateY(-5px)
box-shadow 0 8px 20px rgba(0, 0, 0, 0.15)
.details__gallery-image
width 100%
height 250px
object-fit cover
display block
@media screen and (max-width: 700px)
.details__content
flex-direction column
.details__gallery
order -1 // Move gallery above text
.details__gallery-image
height 300px

166
src/styles/index.styl Normal file
View File

@@ -0,0 +1,166 @@
item_h=3em;
double-border()
border-top double thick silver
border-bottom double thick silver
flex-center()
display flex
align-items center
justify-content center
text-center-bold()
text-align center
font-weight bold
display block
grid-responsive(columns)
display grid
grid-template-columns columns
grid-template-rows 1fr
.navbar
double-border()
font-size 0
grid-responsive(repeat(7, min-content))
justify-items start
&__link-wrapper
color black
text-decoration none
&__item
display inline-block
width max-content
height item_h
line-height item_h
text-align center
vertical-align middle
padding 0 10px
margin @padding
overflow hidden
text-overflow ellipsis
font-size medium
&_selected
color green
font-weight bold
border-left double thin silver
border-right double thin silver
.gallery
display flex
flex-direction row
width 90%
margin auto
&__image
margin auto
width 100%
border thin solid black
&:nth-child(2n+1)
margin-top 10px
.main-container
grid-responsive(3fr 1fr)
.info-block
border solid thin black
padding 2vw
margin 1vw 0
&__header
text-center-bold()
&__container
&_layout-a
grid-responsive(3fr 3fr 2fr)
&_layout-b
grid-responsive(4fr 7fr 4fr)
& > *
margin 2vw
&__text, &__description
text-align justify
&__image
margin auto
width 100%
&__link
color inherit
.sidebar
border-left thin solid black
margin 30px 0 0 50px
.small-card
margin 20px 10px 0
grid-responsive(1fr 1fr)
&__content
text-align justify
&__header
text-center-bold()
text-align right
&__link
display block
text-align right
color inherit
&__image
& img
width 100%
margin-left:10px
@media screen and (max-width: 1000px)
.small-card
display flex
flex-direction column
.sidebar
margin 0
width:100%
@media screen and (max-width: 800px)
.navbar
grid-responsive(1fr 1fr)
grid-template-rows 1fr 1fr 1fr
justify-items center
&__item
&_selected
border-bottom double thick silver
border-left none
border-right none
.gallery
display inline-flex
flex-direction column
width 100%
&__image
width 100%
height 100%
&:nth-child(2n+1)
margin-top 0px
.main-container
display flex
flex-direction column
.info-block
&__container
&_layout-a, &_layout-b
display flex
flex-direction column

6
src/styles/table.styl Normal file
View File

@@ -0,0 +1,6 @@
.table, .table-content *, .table-content
border: 1px solid black;
border-collapse: collapse;
.table-content__table-row:nth-child(2n)
background: #F0FFF0;

2360
table.html

File diff suppressed because it is too large Load Diff

69
webpack.config.js Normal file
View File

@@ -0,0 +1,69 @@
const HtmlWebpackPlugin = require("html-webpack-plugin");
const FileManagerPlugin = require("filemanager-webpack-plugin");
const path = require("path");
const fs = require("fs");
const pagesDir = path.join(__dirname, "src", "pages");
const pages = fs.readdirSync(pagesDir).filter(file => file.endsWith(".pug"));
module.exports = {
output: {
path: path.join(__dirname, "dist"),
filename: "index.[contenthash].js",
assetModuleFilename: path.join("images", "[name].[contenthash][ext]"),
},
entry: path.join(__dirname, "src", "index.js"),
module: {
rules: [
{
test: /\.pug$/,
loader: "pug-loader",
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: "asset/resource",
},
{
test: /\.svg$/,
type: "asset/resource",
generator: {
filename: path.join("icons", "[name].[contenthash][ext]"),
},
},
{
test: /\.styl$/,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
},
{
loader: "stylus-loader",
},
],
},
],
},
plugins: [
...pages.map(
(page) =>
new HtmlWebpackPlugin({
template: path.join(pagesDir, page),
filename: page.replace(".pug", ".html"),
})
),
new FileManagerPlugin({
events: {
onStart: {
delete: ["dist"],
},
},
}),
],
devServer: {
watchFiles: path.join(__dirname, "src"),
port: 9000,
},
};