Compare commits
50 Commits
b653d69e77
...
hw7
| Author | SHA1 | Date | |
|---|---|---|---|
| 011e19e531 | |||
| 5d7ecb1f13 | |||
| 9fef1e5b0d | |||
| c09b7b5769 | |||
| cf80fd251e | |||
| 46e3696d85 | |||
| 9e5950490a | |||
| 26bc727758 | |||
| 04db81b55a | |||
| 4ab5967abe | |||
| 63af3ed7b4 | |||
| b2c005e22c | |||
| 4cf2f56749 | |||
| b0c3660f16 | |||
| b47e479b95 | |||
| eb509fb846 | |||
| 9870335263 | |||
| 7cc781c0b9 | |||
| 8eaf1ed628 | |||
| 7b1c5b0a50 | |||
| 4316ac1636 | |||
| a4f511cb45 | |||
| dd9002a61b | |||
| e142436ed3 | |||
| 38e70189b8 | |||
| 39d023d50b | |||
| 05b624120d | |||
| 7a83c54165 | |||
| c495c26320 | |||
| 3982a97dce | |||
| 8f89dbe429 | |||
| 98b74ae77d | |||
| bdc5a9d55c | |||
| 8900cf3228 | |||
| 4cc6b7e9d8 | |||
| 73ea28eab6 | |||
| ea0b091c8a | |||
| c53abdb678 | |||
| 2b4a36c1ff | |||
| 03e7b28167 | |||
| a25b444c01 | |||
| d54afa7b2e | |||
| 01dfe8011d | |||
| 5f692a4708 | |||
| b98abb94cc | |||
| deeb9dbd5c | |||
| 2f44691a98 | |||
| 36fb1653d3 | |||
| 0bdaa800f6 | |||
| ebe6566b87 |
5
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
node_modules
|
**node_modules
|
||||||
to_reform
|
**to_reform
|
||||||
|
.vscode
|
||||||
6692
current_site/package-lock.json
generated
Normal file
306
current_site/src/components/data.pug
Normal 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'
|
||||||
|
}
|
||||||
|
];
|
||||||
24
current_site/src/components/details-template.pug
Normal 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
current_site/src/components/mixins.pug
Normal 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
|
||||||
|
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 198 KiB |
|
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 159 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 229 KiB After Width: | Height: | Size: 229 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 347 KiB After Width: | Height: | Size: 347 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 5.2 MiB After Width: | Height: | Size: 5.2 MiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 3.9 MiB After Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 4.4 MiB After Width: | Height: | Size: 4.4 MiB |
|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 1.9 MiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
3
current_site/src/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import './styles/index.styl'
|
||||||
|
import './styles/details.styl'
|
||||||
|
import './styles/table.styl'
|
||||||
51
current_site/src/pages/index.pug
Normal 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()
|
||||||
22
current_site/src/pages/photography-details.pug
Normal 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
current_site/src/pages/table.pug
Normal 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
current_site/src/styles/details.styl
Normal 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
current_site/src/styles/index.styl
Normal 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
current_site/src/styles/table.styl
Normal 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;
|
||||||
112
hw/hw6/hw6.js
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
let templates = [
|
||||||
|
[
|
||||||
|
"X--X----",
|
||||||
|
"-XXX-X--",
|
||||||
|
"----X---",
|
||||||
|
"----X---",
|
||||||
|
"------XX",
|
||||||
|
"----XX--",
|
||||||
|
"X-------",
|
||||||
|
"-XX--X--"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"---XX---",
|
||||||
|
"----X-X-",
|
||||||
|
"---XX---",
|
||||||
|
"---X----",
|
||||||
|
"-X------",
|
||||||
|
"X----X-X",
|
||||||
|
"--X--X--",
|
||||||
|
"-X----XX"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"-X-X----",
|
||||||
|
"---X-X--",
|
||||||
|
"X-XX--X-",
|
||||||
|
"--X-X---",
|
||||||
|
"------X",
|
||||||
|
"--------",
|
||||||
|
"X-----X-",
|
||||||
|
"-X-X---X"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"-XX-X---",
|
||||||
|
"-----X--",
|
||||||
|
"----X---",
|
||||||
|
"-----X-X",
|
||||||
|
"-X-X--X-",
|
||||||
|
"-XX----X",
|
||||||
|
"-X------",
|
||||||
|
"XX------"
|
||||||
|
], [
|
||||||
|
"----XX-X",
|
||||||
|
"X-------",
|
||||||
|
"--------",
|
||||||
|
"-----XX-",
|
||||||
|
"---X-X--",
|
||||||
|
"-X---XX-",
|
||||||
|
"-X-X----",
|
||||||
|
"----XXX-"
|
||||||
|
], [
|
||||||
|
"XX------",
|
||||||
|
"-----X--",
|
||||||
|
"-------X",
|
||||||
|
"-X-X----",
|
||||||
|
"X-X----X",
|
||||||
|
"-X-X-X-X",
|
||||||
|
"----X-X-",
|
||||||
|
"-X------"
|
||||||
|
],
|
||||||
|
];
|
||||||
|
const squareSize = templates[0].length;
|
||||||
|
|
||||||
|
//convert to arrays for mutability
|
||||||
|
let temp = []
|
||||||
|
for (let n = 0; n < templates.length; n++) {
|
||||||
|
temp.push([])
|
||||||
|
for (let i = 0; i < squareSize; i++) {
|
||||||
|
temp[n].push([]);
|
||||||
|
for (let j = 0; j < squareSize; j++) {
|
||||||
|
temp[n][i].push(templates[n][i][j] == "X" ? 1 : 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
templates = temp;
|
||||||
|
|
||||||
|
const encodedMsg = "Р_НАЙА_СЛЗДЕ_ЛОСЖСТОИКНОЛЬЛЬТКУЮО__КЗАЕ_ДВАОКАЧОЖЗ_УЧАСМОДУ_ТЮЖЕ";
|
||||||
|
|
||||||
|
|
||||||
|
function rotateTemplate(template) {
|
||||||
|
for (let i = 0; i < squareSize; i++) {
|
||||||
|
for (let j = 0; j < i; j++) {
|
||||||
|
let temp = template[i][j];
|
||||||
|
template[i][j] = template[j][i];
|
||||||
|
template[j][i] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0; i < squareSize; i++) {
|
||||||
|
for (let j = 0; j < squareSize / 2; j++) {
|
||||||
|
let temp = template[i][j];
|
||||||
|
template[i][j] = template[i][(squareSize - 1) - j];
|
||||||
|
template[i][(squareSize - 1) - j] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let n = 0; n < templates.length; n++) {
|
||||||
|
let out = ""
|
||||||
|
for (let rot = 0; rot < 4; rot++) {
|
||||||
|
for (let i = 0; i < squareSize; i++) {
|
||||||
|
for (let j = 0; j < squareSize; j++) {
|
||||||
|
if (templates[n][i][j]) {
|
||||||
|
out += encodedMsg[i * squareSize + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rotateTemplate(templates[n]);
|
||||||
|
}
|
||||||
|
console.log(out);
|
||||||
|
console.log("=======");
|
||||||
|
|
||||||
|
}
|
||||||
BIN
hw/hw7/favicon.ico
Normal file
|
After Width: | Height: | Size: 31 KiB |
108
hw/hw7/hw7.css
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
.desctription-heading{
|
||||||
|
font-size: medium;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scheme-image{
|
||||||
|
flex: 1;
|
||||||
|
max-width: 400px;
|
||||||
|
height: auto;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 300px;
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputs{
|
||||||
|
min-width: 300px;
|
||||||
|
}
|
||||||
|
.outputs{
|
||||||
|
min-width: 300px;
|
||||||
|
}
|
||||||
|
.radio-label{
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
p{
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
.max-w{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bad-input-tooltip {
|
||||||
|
display: block;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #721c24;
|
||||||
|
border: 1px solid #8f0c19;
|
||||||
|
padding: 4px 8px;
|
||||||
|
max-width: 220px;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bad-input-highlight {
|
||||||
|
outline: 2px solid #990917;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
body{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even) {
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
.main-container {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scheme-image {
|
||||||
|
max-width: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls-container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputs, .outputs {
|
||||||
|
min-width: unset;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
71
hw/hw7/hw7.html
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>калькулятор равнобедренного треугольника</title>
|
||||||
|
<link rel="stylesheet" href="./hw7.css">
|
||||||
|
<link rel="icon" href="favicon.ico">
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/xp.css/dist/98.css"
|
||||||
|
>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h3 class="desctription-heading">калькулятор равнобедренного треугольника</h3>
|
||||||
|
|
||||||
|
<div class="main-container">
|
||||||
|
<div class="image-container">
|
||||||
|
<img src="./imgs/type1.png" class="scheme-image" id="schemeImageA">
|
||||||
|
<img src="./imgs/type2.png" class="scheme-image hidden" id="schemeImageB">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="controls-container">
|
||||||
|
<div class="inputs" id="inputsForm">
|
||||||
|
<p>Выберете варинат входных данных:</p>
|
||||||
|
<input type="radio" name="input-type" id="radioButtonA" checked>
|
||||||
|
<label class="radio-label" for="radioButtonA">
|
||||||
|
<span>боковая сторона и угол при основании</span>
|
||||||
|
</label><br>
|
||||||
|
<input type="radio" name="input-type" id="radioButtonB">
|
||||||
|
<label class="radio-label" for="radioButtonB">
|
||||||
|
<span>основание и прилежащий к нему угол</span>
|
||||||
|
</label>
|
||||||
|
<form>
|
||||||
|
<fieldset id="inputTypeFieldsetA">
|
||||||
|
<legend>входные данные</legend>
|
||||||
|
<label for="equalSideLength">Длина боковой стороны B:<span class="bad-input-tooltip hidden" id="equalSideLengthErr"></span></label><br>
|
||||||
|
<input class="max-w" type="number" min="0" id="equalSideLength">
|
||||||
|
<br>
|
||||||
|
<label for="baseAngle">Угол при основании α (в градусах):<span class="bad-input-tooltip hidden" id="baseAngleErr"></span></label><br>
|
||||||
|
<input class="max-w" type="number" min="0" max="180" id="baseAngle">
|
||||||
|
</fieldset>
|
||||||
|
<fieldset id="inputTypeFieldsetB" class="hidden">
|
||||||
|
<legend>входные данные</legend>
|
||||||
|
<label for="baseSideLength">Длина основания A:<span class="bad-input-tooltip hidden" id="baseSideLengthErr"></span></label><br>
|
||||||
|
<input class="max-w" type="number" min="0" id="baseSideLength">
|
||||||
|
<br>
|
||||||
|
<label for="baseAdjacentAngle">Угол прилежащий основанию β:<span class="bad-input-tooltip hidden" id="baseAdjacentAngleErr"></span></label><br>
|
||||||
|
<input class="max-w" type="number" min="0" max="180" id="baseAdjacentAngle">
|
||||||
|
</fieldset>
|
||||||
|
<fieldset id="outputsFieldset">
|
||||||
|
<legend>что вычислить</legend>
|
||||||
|
<span class="bad-input-tooltip hidden" id="outputValuesErr"><br></span>
|
||||||
|
<input type="checkbox" name="output-valuesR" id="outputValuesR" checked>
|
||||||
|
<label for="outputValuesR">радиус вписанной окружности</label><br>
|
||||||
|
<input type="checkbox" name="output-valuesH" id="outputValuesH" checked>
|
||||||
|
<label for="outputValuesH">высоты треугольника</label><br>
|
||||||
|
<input type="checkbox" name="output-valuesL" id="outputValuesL" checked>
|
||||||
|
<label for="outputValuesL">длины сторон треугольника</label><br>
|
||||||
|
</fieldset>
|
||||||
|
<button id="calculateButton" disabled>Вычислить</button>
|
||||||
|
<button id="clearButton">Отчислить</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<table class="outputs hidden" id="outputsTable">
|
||||||
|
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script src="./hw7.js">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</html>
|
||||||
357
hw/hw7/hw7.js
Normal file
@@ -0,0 +1,357 @@
|
|||||||
|
let elements = {
|
||||||
|
radioA: document.getElementById('radioButtonA'),
|
||||||
|
radioB: document.getElementById('radioButtonB'),
|
||||||
|
fieldsetA: document.getElementById('inputTypeFieldsetA'),
|
||||||
|
fieldsetB: document.getElementById('inputTypeFieldsetB'),
|
||||||
|
imageA: document.getElementById('schemeImageA'),
|
||||||
|
imageB: document.getElementById('schemeImageB'),
|
||||||
|
|
||||||
|
inputsForm: document.getElementById('inputsForm'),
|
||||||
|
|
||||||
|
equalSideLength: document.getElementById('equalSideLength'),
|
||||||
|
equalSideLengthErr: document.getElementById('equalSideLengthErr'),
|
||||||
|
baseAngle: document.getElementById('baseAngle'),
|
||||||
|
baseAngleErr: document.getElementById('baseAngleErr'),
|
||||||
|
baseSideLength: document.getElementById('baseSideLength'),
|
||||||
|
baseSideLengthErr: document.getElementById('baseSideLengthErr'),
|
||||||
|
baseAdjacentAngle: document.getElementById('baseAdjacentAngle'),
|
||||||
|
baseAdjacentAngleErr: document.getElementById('baseAdjacentAngleErr'),
|
||||||
|
|
||||||
|
outputsFieldset: document.getElementById('outputsFieldset'),
|
||||||
|
outputValuesErr: document.getElementById('outputValuesErr'),
|
||||||
|
outputR: document.getElementById('outputValuesR'),
|
||||||
|
outputH: document.getElementById('outputValuesH'),
|
||||||
|
outputL: document.getElementById('outputValuesL'),
|
||||||
|
calculateButton: document.getElementById('calculateButton'),
|
||||||
|
clearButton: document.getElementById('clearButton'),
|
||||||
|
outputsTable: document.getElementById('outputsTable')
|
||||||
|
}
|
||||||
|
console.log("loaded js!");
|
||||||
|
|
||||||
|
let currentModeIsA = true;
|
||||||
|
let outputFields = {};
|
||||||
|
|
||||||
|
let inputsA = {
|
||||||
|
l: null,
|
||||||
|
angle: null
|
||||||
|
};
|
||||||
|
|
||||||
|
let inputsB = {
|
||||||
|
l: null,
|
||||||
|
angle: null
|
||||||
|
};
|
||||||
|
|
||||||
|
function highlightErrorElement(errorFieldIndex, add = true) {
|
||||||
|
let fields = [
|
||||||
|
elements.equalSideLength,
|
||||||
|
elements.baseAngle,
|
||||||
|
elements.baseSideLength,
|
||||||
|
elements.baseAdjacentAngle,
|
||||||
|
outputsFieldset
|
||||||
|
];
|
||||||
|
if (fields[errorFieldIndex]) {
|
||||||
|
if (add) {
|
||||||
|
fields[errorFieldIndex].classList.add("bad-input-highlight");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fields[errorFieldIndex].classList.remove("bad-input-highlight");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function setErrTooltip(errorFieldIndex, tooltip) {
|
||||||
|
let errElem = [
|
||||||
|
elements.equalSideLengthErr,
|
||||||
|
elements.baseAngleErr,
|
||||||
|
elements.baseSideLengthErr,
|
||||||
|
elements.baseAdjacentAngleErr,
|
||||||
|
elements.outputValuesErr
|
||||||
|
][errorFieldIndex];
|
||||||
|
if (errElem) {
|
||||||
|
highlightErrorElement(errorFieldIndex, tooltip !== "");
|
||||||
|
|
||||||
|
if (tooltip !== "") {
|
||||||
|
errElem.classList.remove("hidden");;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errElem.classList.add("hidden");;
|
||||||
|
}
|
||||||
|
if (errorFieldIndex == 4) {
|
||||||
|
tooltip += "<br>"
|
||||||
|
}
|
||||||
|
errElem.innerHTML = tooltip;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function deg2rad(degrees) {
|
||||||
|
return degrees * (Math.PI / 180);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCalculations() {
|
||||||
|
let heights = [];//base related, side realted
|
||||||
|
let lengths = [];// base side
|
||||||
|
let radius = 0;
|
||||||
|
let baseAngle = 0;
|
||||||
|
let sideAngle = 0;
|
||||||
|
if (currentModeIsA) {
|
||||||
|
lengths[0] = 2 * Math.sin(deg2rad(inputsA.angle) / 2) * inputsA.l;
|
||||||
|
lengths[1] = inputsA.l;
|
||||||
|
baseAngle = inputsA.angle;
|
||||||
|
sideAngle = (180 - baseAngle) / 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lengths[0] = inputsB.l;
|
||||||
|
lengths[1] = inputsB.l / (2 * Math.cos(deg2rad(inputsB.angle)));
|
||||||
|
sideAngle = inputsB.angle;
|
||||||
|
baseAngle = 180 - 2 * sideAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let a = lengths[0];
|
||||||
|
let b = lengths[1];
|
||||||
|
let p = (a + b + b) / 2;
|
||||||
|
radius = Math.sqrt((p - a) * (p - b) * (p - b) / p);
|
||||||
|
|
||||||
|
heights[0] = lengths[1] * Math.sin(deg2rad(sideAngle));
|
||||||
|
heights[1] = lengths[0] * Math.sin(deg2rad(baseAngle));
|
||||||
|
return {
|
||||||
|
radius: radius,
|
||||||
|
heights: heights,
|
||||||
|
lengths: lengths
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCheckboxes() {
|
||||||
|
outputFields["radius"] = elements.outputR.checked;
|
||||||
|
outputFields["heights"] = elements.outputH.checked;
|
||||||
|
outputFields["lengths"] = elements.outputL.checked;
|
||||||
|
let ret = !outputFields.radius && !outputFields.heights && !outputFields.lengths;
|
||||||
|
if (ret) {
|
||||||
|
setErrTooltip(4, "Выберите хотя бы один параметр для вывода.");
|
||||||
|
} else {
|
||||||
|
setErrTooltip(4, "");
|
||||||
|
}
|
||||||
|
updateCalculateButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCalculateButton() {
|
||||||
|
let ret = false;
|
||||||
|
if (currentModeIsA) {
|
||||||
|
ret = inputsA["l"] !== null && inputsA["angle"] !== null
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = inputsB["l"] !== null && inputsB["angle"] !== null
|
||||||
|
}
|
||||||
|
ret &= elements.outputR.checked || elements.outputH.checked || elements.outputL.checked;
|
||||||
|
|
||||||
|
elements.calculateButton.disabled = !ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchInputs(selectA) {
|
||||||
|
if (selectA) {
|
||||||
|
elements.imageA.classList.remove("hidden");
|
||||||
|
elements.imageB.classList.add("hidden");
|
||||||
|
elements.fieldsetA.classList.remove("hidden");
|
||||||
|
elements.fieldsetB.classList.add("hidden");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
elements.imageA.classList.add("hidden");
|
||||||
|
elements.imageB.classList.remove("hidden");
|
||||||
|
elements.fieldsetA.classList.add("hidden");
|
||||||
|
elements.fieldsetB.classList.remove("hidden");
|
||||||
|
}
|
||||||
|
updateCalculateButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayTable(calcResults) {
|
||||||
|
let table = elements.outputsTable;
|
||||||
|
table.innerHTML = ""; // Clear previous content
|
||||||
|
|
||||||
|
let header = "<tr><th>Параметр</th><th>Значение</th></tr>";
|
||||||
|
let rows = "";
|
||||||
|
|
||||||
|
if (outputFields.radius) {
|
||||||
|
rows += `<tr><td>R</td><td>${calcResults.radius.toFixed(3)}</td></tr>`;
|
||||||
|
}
|
||||||
|
if (outputFields.heights) {
|
||||||
|
rows += `<tr><td>h1</td><td>${calcResults.heights[0].toFixed(3)}</td></tr>`;
|
||||||
|
rows += `<tr><td>h2</td><td>${calcResults.heights[1].toFixed(3)}</td></tr>`;
|
||||||
|
}
|
||||||
|
if (outputFields.lengths) {
|
||||||
|
rows += `<tr><td>A</td><td>${calcResults.lengths[0].toFixed(3)}</td></tr>`;
|
||||||
|
rows += `<tr><td>B</td><td>${calcResults.lengths[1].toFixed(3)}</td></tr>`;
|
||||||
|
}
|
||||||
|
table.innerHTML = header + rows;
|
||||||
|
|
||||||
|
if (rows === "") {
|
||||||
|
table.innerHTML = `<h3>Выберите параметры для вычислений, сейчас таблица пустая</h3>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.classList.remove("hidden");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearCurrentInputs() {
|
||||||
|
if (currentModeIsA) {
|
||||||
|
elements.equalSideLength.value = null;
|
||||||
|
elements.baseAngle.value = null;
|
||||||
|
setErrTooltip(0, "");
|
||||||
|
setErrTooltip(1, "");
|
||||||
|
inputsA = {
|
||||||
|
l: null,
|
||||||
|
angle: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
inputsB = {
|
||||||
|
l: null,
|
||||||
|
angle: null
|
||||||
|
};
|
||||||
|
setErrTooltip(2, "");
|
||||||
|
setErrTooltip(3, "");
|
||||||
|
elements.baseSideLength.value = null;
|
||||||
|
elements.baseAdjacentAngle.value = null;
|
||||||
|
}
|
||||||
|
elements.outputsTable.classList.add("hidden");
|
||||||
|
updateCalculateButton()
|
||||||
|
}
|
||||||
|
|
||||||
|
function check180Angle(angleString) {
|
||||||
|
let angle = parseFloat(angleString);
|
||||||
|
if (isNaN(angle)) {
|
||||||
|
return "Введите корректное число";
|
||||||
|
}
|
||||||
|
if (angle <= 0) {
|
||||||
|
return "Угол должен быть больше 0";
|
||||||
|
}
|
||||||
|
if (angle >= 180) {
|
||||||
|
return "Угол должен быть меньше 180";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function check90Angle(angleString) {
|
||||||
|
let angle = parseFloat(angleString);
|
||||||
|
if (isNaN(angle)) {
|
||||||
|
return "Введите корректное число";
|
||||||
|
}
|
||||||
|
if (angle <= 0) {
|
||||||
|
return "Угол должен быть больше 0";
|
||||||
|
}
|
||||||
|
if (angle >= 90) {
|
||||||
|
return "Угол должен быть меньше 90";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkLength(lengthString) {
|
||||||
|
let length = parseFloat(lengthString);
|
||||||
|
if (!isFinite(length)) {
|
||||||
|
return "Введите корректное число";
|
||||||
|
}
|
||||||
|
if (length <= 0) {
|
||||||
|
return "Длина должна быть больше 0";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSwitchInputs(event) {
|
||||||
|
if (event.target.id[event.target.id.length - 1].toLowerCase() == "a") {
|
||||||
|
currentModeIsA = true;
|
||||||
|
switchInputs(true);
|
||||||
|
console.log("Switching inputs to A");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
currentModeIsA = false;
|
||||||
|
switchInputs(false);
|
||||||
|
console.log("Switching inputs to B");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleInputsUpdate(event) {
|
||||||
|
switch (event.target.id) {
|
||||||
|
case "equalSideLength":
|
||||||
|
{
|
||||||
|
const err = checkLength(event.target.value);
|
||||||
|
setErrTooltip(0, err);
|
||||||
|
if (err === "") {
|
||||||
|
inputsA.l = parseFloat(event.target.value);
|
||||||
|
} else {
|
||||||
|
inputsA.l = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "baseAngle":
|
||||||
|
{
|
||||||
|
const err = check180Angle(event.target.value);
|
||||||
|
setErrTooltip(1, err);
|
||||||
|
if (err === "") {
|
||||||
|
inputsA.angle = parseFloat(event.target.value);
|
||||||
|
} else {
|
||||||
|
inputsA.angle = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "baseSideLength":
|
||||||
|
{
|
||||||
|
const err = checkLength(event.target.value);
|
||||||
|
setErrTooltip(2, err);
|
||||||
|
if (err === "") {
|
||||||
|
inputsB.l = parseFloat(event.target.value);
|
||||||
|
} else {
|
||||||
|
inputsB.l = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "baseAdjacentAngle":
|
||||||
|
{
|
||||||
|
const err = check90Angle(event.target.value);
|
||||||
|
setErrTooltip(3, err);
|
||||||
|
if (err === "") {
|
||||||
|
inputsB.angle = parseFloat(event.target.value);
|
||||||
|
} else {
|
||||||
|
inputsB.angle = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log(event.target.id)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
updateCalculateButton();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFieldsetEvent(event) {
|
||||||
|
if (event.target.type === 'radio') {
|
||||||
|
handleSwitchInputs(event);
|
||||||
|
} else if (event.target.type === 'number') {
|
||||||
|
handleInputsUpdate(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elements.inputsForm.addEventListener('change', handleFieldsetEvent);
|
||||||
|
elements.inputsForm.addEventListener('input', handleFieldsetEvent);
|
||||||
|
|
||||||
|
elements.outputsFieldset.addEventListener('change', (event) => {
|
||||||
|
if (event.target.type === 'checkbox') {
|
||||||
|
updateCheckboxes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
elements.clearButton.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
clearCurrentInputs()
|
||||||
|
});
|
||||||
|
|
||||||
|
elements.calculateButton.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
displayTable(getCalculations());
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// чтобы не сконфузило
|
||||||
|
updateCheckboxes();
|
||||||
|
switchInputs(elements.radioA.checked);
|
||||||
BIN
hw/hw7/imgs/type1.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
BIN
hw/hw7/imgs/type2.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
1
labs/fake-lab5/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
node_modules
|
||||||
30
labs/fake-lab5/package.json
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
19
labs/fake-lab5/src/pages/index.pug
Normal 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="#") …
|
||||||
86
labs/fake-lab5/src/styles/main.styl
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
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)
|
||||||
|
overflow hidden
|
||||||
|
|
||||||
|
& img
|
||||||
|
width: 100%
|
||||||
|
@media (max-width: 600px)
|
||||||
|
grid-template-rows repeat(5, 1fr)
|
||||||
|
grid-template-columns 1fr
|
||||||
|
justify-items center
|
||||||
|
|
||||||
|
article
|
||||||
|
width 80%
|
||||||
|
margin auto
|
||||||
|
display grid
|
||||||
|
grid-template-columns repeat(3, 1fr)
|
||||||
|
grid-gap 4%
|
||||||
|
overflow hidden
|
||||||
|
|
||||||
|
@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
|
||||||
69
labs/fake-lab5/webpack.config.js
Normal 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,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 37 KiB |
@@ -1,2 +0,0 @@
|
|||||||
h2= 'Hello World!'
|
|
||||||
img(src= require("../images/img1.jpg"))
|
|
||||||
@@ -1,19 +1,5 @@
|
|||||||
extends template
|
head
|
||||||
|
title Lab 5
|
||||||
block nav
|
body
|
||||||
nav
|
p.first-green-letter Текст Текст
|
||||||
+createMenu(dictMenu, 'Главная')
|
p.first-green-letter Второй параграф
|
||||||
|
|
||||||
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="#") …
|
|
||||||
@@ -1,84 +1,7 @@
|
|||||||
colorText = #6f6d6d
|
text(size, color)
|
||||||
|
&:first-letter
|
||||||
|
font-size size
|
||||||
|
color color
|
||||||
|
|
||||||
back(size)
|
.first-green-letter
|
||||||
background-color #f1f1f1
|
text(2em,green)
|
||||||
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
|
|
||||||
19
labs/lab6/lab6.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
function areNumbersEqual(num1,num2,percision){
|
||||||
|
return Math.abs(num1 - num2) < percision;
|
||||||
|
}
|
||||||
|
|
||||||
|
func=(...args) => {
|
||||||
|
const percision=0.1E-2;
|
||||||
|
args.sort();
|
||||||
|
let out = "";
|
||||||
|
let lastElem = null;
|
||||||
|
for (let i = 0; i < args.length-1; i++){
|
||||||
|
if (areNumbersEqual(args[i],args[i+1],percision) && (!areNumbersEqual(args[i],lastElem,percision) || lastElem === null)){
|
||||||
|
lastElem = args[i];
|
||||||
|
out += lastElem+" ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(func(-0.0009111,0,-0.0009111,-0.009111,-0,1.1,1.101,2.0001,2))
|
||||||
20
labs/lab7/lab7.html
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<body>
|
||||||
|
<h3>Языки программирования</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href ="">Python</a></li>
|
||||||
|
<li><a href ="">C</a></li>
|
||||||
|
<li><a id="test" href ="">Java</a></li>
|
||||||
|
<li><a href ="">JavaScript</a></li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
let elem = document.getElementById("test");
|
||||||
|
elem = elem.parentNode;
|
||||||
|
|
||||||
|
while(elem.parentElement!==null){
|
||||||
|
let newElem =document.createElement(elem.children[0].tagName);
|
||||||
|
newElem.innerHTML= "Новый Элемент";
|
||||||
|
elem.appendChild(newElem);
|
||||||
|
elem=elem.parentNode;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
69
lectures/lecture3.txt
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
ol#list(type="I")
|
||||||
|
li Препроцессоры HTML
|
||||||
|
ul(type="disc")
|
||||||
|
li.first
|
||||||
|
a(href="#") Haml
|
||||||
|
li Pug
|
||||||
|
li Препроцессоры CSS
|
||||||
|
ul(type="circle")
|
||||||
|
li.first SAAS
|
||||||
|
li Stylus
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- var tag = 'h'
|
||||||
|
- var i = 1
|
||||||
|
|
||||||
|
#{tag+i} Уровень #{i}
|
||||||
|
- i++
|
||||||
|
#{tag+i} Уровень #{i}
|
||||||
|
- i++
|
||||||
|
#{tag+i} Уровень #{i}
|
||||||
|
- i++
|
||||||
|
#{tag+i} Уровень #{i}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- var products ={"Товар":"Цена","ручка":30.5, "карандаш":50, "альбом":156, "тетрадь":21.5, "ластик":10.2}
|
||||||
|
table
|
||||||
|
each name,price in products
|
||||||
|
tr
|
||||||
|
td #{name}
|
||||||
|
td #{price}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
table
|
||||||
|
- for(var i=0;i<10;i++)
|
||||||
|
tr
|
||||||
|
- for(var j=0;j<10;j++)
|
||||||
|
- if((i + j) % 2 == 0)
|
||||||
|
td.white
|
||||||
|
- else
|
||||||
|
td.black
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mixin createList(listType, items, tag)
|
||||||
|
- var dispListType = "ul"
|
||||||
|
- if (listType == "ol")
|
||||||
|
- dispListType = "ol"
|
||||||
|
|
||||||
|
#{dispListType}.list
|
||||||
|
each item in items
|
||||||
|
li
|
||||||
|
#{tag} #{item}
|
||||||
|
|
||||||
|
// Вызов миксина
|
||||||
|
+createList('ul', ['Python', 'JavaScript', 'Java'], 'strong')
|
||||||
|
|
||||||
|
|
||||||
|
size=1%
|
||||||
|
section
|
||||||
|
box-shadow: size size (2*size) rgba(0,0,0,0.5)
|
||||||
|
padding:size*2
|
||||||
|
margin:size*4
|
||||||
17
lectures/temp.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
function updateDict(dict, update) {
|
||||||
|
let key, value = update.entries()[0];
|
||||||
|
dict[key] = value + (key in dict) ? dict[key] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
aboba={"asd":123}
|
||||||
|
upd={"asd":123}
|
||||||
|
upd1={"asd":123}
|
||||||
|
|
||||||
|
updateDict(aboba,upd1)
|
||||||
|
console.log(aboba)
|
||||||
|
updateDict(aboba,upd1)
|
||||||
|
console.log(aboba)
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
-
|
|
||||||
const pages = {
|
|
||||||
embedded: {
|
|
||||||
title: 'Embedded Details',
|
|
||||||
slug: 'embedded',
|
|
||||||
menuTitle: 'Embeded Details',
|
|
||||||
images: [
|
|
||||||
{ src: './images/esp32.png', alt: 'ESP32', height: 150 },
|
|
||||||
{ src: './images/arduino.png', alt: 'Arduino', height: 150 },
|
|
||||||
{ src: './images/stm32.png', alt: 'STM32', height: 150 }
|
|
||||||
],
|
|
||||||
paragraphs: [
|
|
||||||
"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",
|
|
||||||
"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>"
|
|
||||||
],
|
|
||||||
table: {
|
|
||||||
title: 'Microcontroller Comparison Table',
|
|
||||||
headers: ['Board/MCU', 'UART Count', 'Dynamic UART Assignment', 'ADC Channels', 'Debug Support', 'Flash Size', 'Wireless Connectivity'],
|
|
||||||
rows: [
|
|
||||||
['ESP32', '3', 'Yes (via IO MUX)', '18', 'JTAG, Serial', '4MB (typical)', 'Wi-Fi, Bluetooth'],
|
|
||||||
['ESP32-S3', '3', 'Yes (via IO MUX)', '20', 'JTAG, Serial', '8MB (typical)', 'Wi-Fi, Bluetooth LE'],
|
|
||||||
['ESP-01', '1', 'No', '1', 'Serial only', '512KB/1MB', 'Wi-Fi'],
|
|
||||||
['Arduino Uno (ATmega328P)', '1', 'No', '6', 'Serial, DebugWire', '32KB', 'None'],
|
|
||||||
['Blue Pill (STM32F103C8T6)', '3', 'Yes (remappable)', '10', 'SWD, Serial', '64KB/128KB', 'None']
|
|
||||||
]
|
|
||||||
},
|
|
||||||
footer: "no rpi pico here , the build system has won over my temper"
|
|
||||||
},
|
|
||||||
|
|
||||||
opencv: {
|
|
||||||
title: 'OpenCV Details',
|
|
||||||
slug: 'opencv',
|
|
||||||
menuTitle: 'OpenCV Details',
|
|
||||||
images: [
|
|
||||||
{ src: './images/opencv.png', alt: 'OpenCV', height: 150 }
|
|
||||||
],
|
|
||||||
paragraphs: [
|
|
||||||
"as mentioned before i love when programs are able to <i>see</i> things",
|
|
||||||
"my experience with opencv started with simple hight level functions like detectCircle or findContours and etc...",
|
|
||||||
"Right now i'm crawling deeper into the library , and the idea of standartisation of parameters between different cameras is appealig to me",
|
|
||||||
"so i'm trying to understand how all that works from the math side",
|
|
||||||
"Additionally, I'm exploring Re-Identification (ReId) techniques, they are used for recognizing and tracking objects across different camera views or consecutive frames."
|
|
||||||
],
|
|
||||||
content: {
|
|
||||||
type: 'text',
|
|
||||||
text: "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."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
photography: {
|
|
||||||
title: 'Photography Details',
|
|
||||||
slug: 'photography',
|
|
||||||
menuTitle: 'Photography Details',
|
|
||||||
images: [],
|
|
||||||
paragraphs: [
|
|
||||||
"Usually i capture landcape scenes with SLR camera, the main workhorse is Nikon D3100 with kit and 70-210mm"
|
|
||||||
],
|
|
||||||
gallery: [
|
|
||||||
[
|
|
||||||
{ src: 'images/photos/image0.png', alt: 'Photo 0', width: 200 },
|
|
||||||
{ src: 'images/photos/image1.png', alt: 'Photo 1', width: 200 },
|
|
||||||
{ src: 'images/photos/image2.png', alt: 'Photo 2', width: 200 }
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{ src: 'images/photos/image3.png', alt: 'Photo 3', width: 200 },
|
|
||||||
{ src: 'images/photos/image4.png', alt: 'Photo 4', width: 200 },
|
|
||||||
{ src: 'images/photos/image5.png', alt: 'Photo 5', width: 200 }
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
-
|
|
||||||
const menu = [
|
|
||||||
{ href: './index.html', title: 'Home' },
|
|
||||||
{ href: './embeded_details.html', title: 'Embeded Details' },
|
|
||||||
{ href: './opencv_details.html', title: 'OpenCV Details' },
|
|
||||||
{ href: './photography_details.html', title: 'Photography Details' },
|
|
||||||
{ href: './table.html', title: 'Table with filters (not working yet)' },
|
|
||||||
{ href: './images/institute.png', title: 'Institute' }
|
|
||||||
];
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
include data.pug
|
|
||||||
|
|
||||||
mixin detailsPage(pageData)
|
|
||||||
doctype html
|
|
||||||
html(lang="en")
|
|
||||||
head
|
|
||||||
meta(charset="UTF-8")
|
|
||||||
title= pageData.title
|
|
||||||
|
|
||||||
body(bgcolor="#F0F8FF")
|
|
||||||
//- Menu
|
|
||||||
details
|
|
||||||
summary Menu
|
|
||||||
ul
|
|
||||||
each item in menu
|
|
||||||
li
|
|
||||||
if item.title === pageData.menuTitle
|
|
||||||
a(href=item.href)
|
|
||||||
h4= item.title
|
|
||||||
else
|
|
||||||
a(href=item.href)= item.title
|
|
||||||
|
|
||||||
//- Page Title
|
|
||||||
h2(align="center")= pageData.title
|
|
||||||
hr(width="800" align="center")
|
|
||||||
|
|
||||||
//- Header Images
|
|
||||||
if pageData.images && pageData.images.length > 0
|
|
||||||
p(align="center")
|
|
||||||
each img in pageData.images
|
|
||||||
if img.height
|
|
||||||
img(src=img.src alt=img.alt height=img.height)
|
|
||||||
else if img.width
|
|
||||||
img(src=img.src alt=img.alt width=img.width)
|
|
||||||
else
|
|
||||||
img(src=img.src alt=img.alt)
|
|
||||||
|
|
||||||
//- Paragraphs
|
|
||||||
if pageData.paragraphs
|
|
||||||
each para in pageData.paragraphs
|
|
||||||
p(align="justify")!= para
|
|
||||||
|
|
||||||
//- Table (for embedded page)
|
|
||||||
if pageData.table
|
|
||||||
h3(align="center")= pageData.table.title
|
|
||||||
table(border="1" align="center" cellpadding="6" cellspacing="0")
|
|
||||||
tr
|
|
||||||
each header in pageData.table.headers
|
|
||||||
th= header
|
|
||||||
each row in pageData.table.rows
|
|
||||||
tr
|
|
||||||
each cell in row
|
|
||||||
td= cell
|
|
||||||
|
|
||||||
//- Content (for opencv page)
|
|
||||||
if pageData.content
|
|
||||||
hr(width="500" align="center")
|
|
||||||
p!= pageData.content.text
|
|
||||||
|
|
||||||
//- Gallery (for photography page)
|
|
||||||
if pageData.gallery
|
|
||||||
each row in pageData.gallery
|
|
||||||
p(align="center")
|
|
||||||
each img in row
|
|
||||||
img(src=img.src alt=img.alt width=img.width)
|
|
||||||
|
|
||||||
//- Footer
|
|
||||||
if pageData.footer
|
|
||||||
p(align="right")= pageData.footer
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
-
|
|
||||||
const menuItems = [
|
|
||||||
{ href: './index.html', title: 'Home', isActive: true },
|
|
||||||
{ href: './embeded_details.html', title: 'Embedded' },
|
|
||||||
{ href: './opencv_details.html', title: 'OpenCV' },
|
|
||||||
{ href: './photography_details.html', title: 'Photography' },
|
|
||||||
{ href: './table.html', title: 'Table' },
|
|
||||||
{ href: './images/institute.png', title: 'Institute' }
|
|
||||||
];
|
|
||||||
|
|
||||||
const galleryImages = [
|
|
||||||
{ src: './images/sqarucos.png', alt: 'Arduino' },
|
|
||||||
{ src: './images/sqstm32.png', alt: 'STM32' },
|
|
||||||
{ src: './images/sqesp32.png', alt: 'ESP32' }
|
|
||||||
];
|
|
||||||
|
|
||||||
const contentBlocks = [
|
|
||||||
{
|
|
||||||
title: 'Embedded Systems',
|
|
||||||
image: './images/AQ_monitor.png',
|
|
||||||
imageAlt: 'ESP32',
|
|
||||||
columns: [
|
|
||||||
{ text: 'Had several projects with different MCUs and wrote firmware for them. My main stack consists of Platformio+EspIdf or Arduino, also tried STM32' },
|
|
||||||
{ text: 'I love embedded development because of autonomy of produced devices, the devices are not dependent on any other hardware and can work autonomously', hasLink: true }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Embedded Systems',
|
|
||||||
image: './images/remote.jpeg',
|
|
||||||
imageAlt: 'Remote',
|
|
||||||
imageCenter: true,
|
|
||||||
columns: [
|
|
||||||
{ text: 'Had several projects with different MCUs and wrote firmware for them. My main stack consists of Platformio+EspIdf or Arduino, also tried STM32' },
|
|
||||||
{ text: 'I love embedded development because of autonomy of produced devices, the devices are not dependent on any other hardware and can work autonomously or off the grid', hasLink: true }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const sidebarBlocks = [
|
|
||||||
{
|
|
||||||
title: '3D Printer',
|
|
||||||
text: '3D printers are versatile tools used for creating prototypes, custom parts, and artistic designs. They work by layering materials.',
|
|
||||||
image: 'images/16x10/3d-printer.jpeg',
|
|
||||||
alt: '3D Printer'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'BLHeli ESCs',
|
|
||||||
text: 'BLHeli ESCs are electronic speed controllers designed for drones, offering smooth and precise motor control.',
|
|
||||||
image: 'images/16x10/blheli-esc.jpeg',
|
|
||||||
alt: 'BLHeli ESC'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Raspberry Pi Nano',
|
|
||||||
text: 'Raspberry Pi Nano is a compact computer ideal for learning, prototyping, and IoT projects. It is highly energy-efficient.',
|
|
||||||
image: 'images/16x10/rpi-nano.jpeg',
|
|
||||||
alt: 'Raspberry Pi Nano'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Smart Thermostats',
|
|
||||||
text: 'Smart thermostats help regulate home temperatures efficiently, saving energy and enhancing comfort with automation.',
|
|
||||||
image: 'images/16x10/thermostat.jpeg',
|
|
||||||
alt: 'Smart Thermostat'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
mixin nav-menu(items)
|
|
||||||
nav.nav
|
|
||||||
ul.nav__list
|
|
||||||
each item in items
|
|
||||||
li.nav__item
|
|
||||||
a.nav__link(href=item.href class=item.isActive ? 'nav__link--active' : '')= item.title
|
|
||||||
|
|
||||||
mixin gallery(images)
|
|
||||||
.gallery
|
|
||||||
each img in images
|
|
||||||
.gallery__item
|
|
||||||
img.gallery__image(src=img.src alt=img.alt)
|
|
||||||
|
|
||||||
mixin content-block(block, index)
|
|
||||||
.content-block
|
|
||||||
.content-block__header
|
|
||||||
h5.content-block__title= block.title
|
|
||||||
.content-block__body(class=`content-block__body--layout-${index % 2 === 0 ? 'a' : 'b'}`)
|
|
||||||
if index % 2 === 0
|
|
||||||
each col in block.columns
|
|
||||||
.content-block__column
|
|
||||||
p.content-block__text= col.text
|
|
||||||
if col.hasLink
|
|
||||||
a.content-block__link(href="#") More info»
|
|
||||||
.content-block__column.content-block__column--image
|
|
||||||
img.content-block__image(src=block.image alt=block.imageAlt)
|
|
||||||
else
|
|
||||||
.content-block__column
|
|
||||||
p.content-block__text= block.columns[0].text
|
|
||||||
.content-block__column.content-block__column--image-center
|
|
||||||
img.content-block__image(src=block.image alt=block.imageAlt)
|
|
||||||
.content-block__column
|
|
||||||
p.content-block__text= block.columns[1].text
|
|
||||||
if block.columns[1].hasLink
|
|
||||||
a.content-block__link(href="#") More info»
|
|
||||||
|
|
||||||
mixin sidebar-card(card)
|
|
||||||
.sidebar-card
|
|
||||||
.sidebar-card__content
|
|
||||||
h6.sidebar-card__title= card.title
|
|
||||||
p.sidebar-card__text= card.text
|
|
||||||
a.sidebar-card__link(href="#") More Info»
|
|
||||||
.sidebar-card__image-wrapper
|
|
||||||
img.sidebar-card__image(src=card.image alt=card.alt)
|
|
||||||
|
|
||||||
doctype html
|
|
||||||
html(lang="en")
|
|
||||||
head
|
|
||||||
meta(charset="UTF-8")
|
|
||||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
|
||||||
link(rel="stylesheet" href="styles/index.css")
|
|
||||||
title Portfolio
|
|
||||||
|
|
||||||
body.page
|
|
||||||
//- Navigation
|
|
||||||
+nav-menu(menuItems)
|
|
||||||
|
|
||||||
//- Image Gallery
|
|
||||||
+gallery(galleryImages)
|
|
||||||
|
|
||||||
//- Main Content
|
|
||||||
.main
|
|
||||||
.main__content
|
|
||||||
each block, index in contentBlocks
|
|
||||||
+content-block(block, index)
|
|
||||||
|
|
||||||
//- Sidebar
|
|
||||||
.main__sidebar
|
|
||||||
each card in sidebarBlocks
|
|
||||||
+sidebar-card(card)
|
|
||||||
|
|
||||||
//- Footer
|
|
||||||
footer.footer
|
|
||||||
span.footer__text Kulesh A.
|
|
||||||
span.footer__text Б9123-09.03.04
|
|
||||||
@@ -1,259 +0,0 @@
|
|||||||
// Variables
|
|
||||||
$color-bg = #F0F8FF
|
|
||||||
$color-text = black
|
|
||||||
$color-primary = green
|
|
||||||
$color-border = silver
|
|
||||||
$color-footer-bg = #f8f9fa
|
|
||||||
|
|
||||||
$border-thin = 1px solid black
|
|
||||||
$border-double = double 4px silver
|
|
||||||
$border-double-thick = double thick silver
|
|
||||||
|
|
||||||
$spacing-sm = 10px
|
|
||||||
$spacing-md = 20px
|
|
||||||
$spacing-lg = 30px
|
|
||||||
$spacing-xl = 50px
|
|
||||||
|
|
||||||
$breakpoint-mobile = 800px
|
|
||||||
$breakpoint-tablet = 1000px
|
|
||||||
|
|
||||||
// Mixins
|
|
||||||
flex-center()
|
|
||||||
display flex
|
|
||||||
align-items center
|
|
||||||
justify-content center
|
|
||||||
|
|
||||||
text-justify()
|
|
||||||
text-align justify
|
|
||||||
|
|
||||||
border-block()
|
|
||||||
border $border-thin
|
|
||||||
padding 2vw
|
|
||||||
margin 1vw 0
|
|
||||||
|
|
||||||
// Base
|
|
||||||
*
|
|
||||||
box-sizing border-box
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
|
|
||||||
.page
|
|
||||||
font-family Arial, sans-serif
|
|
||||||
background-color $color-bg
|
|
||||||
color $color-text
|
|
||||||
|
|
||||||
// Navigation (БЭМ)
|
|
||||||
.nav
|
|
||||||
border-top $border-double-thick
|
|
||||||
border-bottom $border-double-thick
|
|
||||||
|
|
||||||
&__list
|
|
||||||
display grid
|
|
||||||
grid-template-columns repeat(7, min-content)
|
|
||||||
grid-template-rows 1fr
|
|
||||||
justify-items start
|
|
||||||
list-style none
|
|
||||||
font-size 0
|
|
||||||
|
|
||||||
@media screen and (max-width: $breakpoint-mobile)
|
|
||||||
grid-template-columns 1fr 1fr
|
|
||||||
grid-template-rows 1fr 1fr 1fr
|
|
||||||
justify-items center
|
|
||||||
|
|
||||||
&__item
|
|
||||||
display inline-block
|
|
||||||
|
|
||||||
&__link
|
|
||||||
display block
|
|
||||||
width max-content
|
|
||||||
height 3em
|
|
||||||
line-height 3em
|
|
||||||
text-align center
|
|
||||||
padding 0 $spacing-sm
|
|
||||||
margin 0 $spacing-sm
|
|
||||||
color $color-text
|
|
||||||
text-decoration none
|
|
||||||
font-size medium
|
|
||||||
overflow hidden
|
|
||||||
text-overflow ellipsis
|
|
||||||
|
|
||||||
&--active
|
|
||||||
color $color-primary
|
|
||||||
font-weight bold
|
|
||||||
border-left $border-double
|
|
||||||
border-right $border-double
|
|
||||||
|
|
||||||
@media screen and (max-width: $breakpoint-mobile)
|
|
||||||
border-left none
|
|
||||||
border-right none
|
|
||||||
border-bottom $border-double-thick
|
|
||||||
|
|
||||||
// Gallery (БЭМ)
|
|
||||||
.gallery
|
|
||||||
display flex
|
|
||||||
flex-direction row
|
|
||||||
width 90%
|
|
||||||
margin auto
|
|
||||||
gap 0
|
|
||||||
|
|
||||||
@media screen and (max-width: $breakpoint-mobile)
|
|
||||||
flex-direction column
|
|
||||||
width 100%
|
|
||||||
|
|
||||||
&__item
|
|
||||||
flex 1
|
|
||||||
margin auto
|
|
||||||
|
|
||||||
&__image
|
|
||||||
width 100%
|
|
||||||
height auto
|
|
||||||
border $border-thin
|
|
||||||
|
|
||||||
&:nth-child(odd)
|
|
||||||
margin-top $spacing-sm
|
|
||||||
|
|
||||||
@media screen and (max-width: $breakpoint-mobile)
|
|
||||||
margin-top 0
|
|
||||||
|
|
||||||
// Main Layout (БЭМ)
|
|
||||||
.main
|
|
||||||
display grid
|
|
||||||
grid-template-columns 3fr 1fr
|
|
||||||
grid-template-rows 1fr
|
|
||||||
gap 0
|
|
||||||
|
|
||||||
@media screen and (max-width: $breakpoint-mobile)
|
|
||||||
display flex
|
|
||||||
flex-direction column
|
|
||||||
|
|
||||||
&__content
|
|
||||||
padding-right 0
|
|
||||||
|
|
||||||
&__sidebar
|
|
||||||
border-left $border-thin
|
|
||||||
margin $spacing-lg 0 0 $spacing-xl
|
|
||||||
padding-left $spacing-md
|
|
||||||
|
|
||||||
@media screen and (max-width: $breakpoint-mobile)
|
|
||||||
border-left none
|
|
||||||
margin $spacing-lg 0 0 0
|
|
||||||
padding-left 0
|
|
||||||
|
|
||||||
// Content Block (БЭМ)
|
|
||||||
.content-block
|
|
||||||
border-block()
|
|
||||||
|
|
||||||
&__header
|
|
||||||
text-align center
|
|
||||||
margin-bottom 1vw
|
|
||||||
|
|
||||||
&__title
|
|
||||||
font-weight bold
|
|
||||||
font-size 1.2em
|
|
||||||
|
|
||||||
&__body
|
|
||||||
&--layout-a
|
|
||||||
display grid
|
|
||||||
grid-template-columns 3fr 3fr 2fr
|
|
||||||
grid-template-rows 1fr
|
|
||||||
|
|
||||||
@media screen and (max-width: $breakpoint-mobile)
|
|
||||||
display flex
|
|
||||||
flex-direction column
|
|
||||||
|
|
||||||
&--layout-b
|
|
||||||
display grid
|
|
||||||
grid-template-columns 4fr 7fr 4fr
|
|
||||||
grid-template-rows 1fr
|
|
||||||
|
|
||||||
@media screen and (max-width: $breakpoint-mobile)
|
|
||||||
display flex
|
|
||||||
flex-direction column
|
|
||||||
|
|
||||||
&__column
|
|
||||||
margin 2vw
|
|
||||||
|
|
||||||
&--image
|
|
||||||
flex-center()
|
|
||||||
|
|
||||||
&--image-center
|
|
||||||
flex-center()
|
|
||||||
grid-column 2
|
|
||||||
|
|
||||||
&__text
|
|
||||||
text-justify()
|
|
||||||
|
|
||||||
&__image
|
|
||||||
width 100%
|
|
||||||
height auto
|
|
||||||
|
|
||||||
&__link
|
|
||||||
display block
|
|
||||||
text-align right
|
|
||||||
margin-top $spacing-sm
|
|
||||||
color $color-text
|
|
||||||
text-decoration none
|
|
||||||
font-size 0.9em
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
// Sidebar Card (БЭМ)
|
|
||||||
.sidebar-card
|
|
||||||
display grid
|
|
||||||
grid-template-columns 1fr 1fr
|
|
||||||
grid-template-rows auto
|
|
||||||
margin $spacing-md $spacing-sm 0
|
|
||||||
gap $spacing-sm
|
|
||||||
|
|
||||||
@media screen and (max-width: $breakpoint-tablet)
|
|
||||||
display flex
|
|
||||||
flex-direction column
|
|
||||||
|
|
||||||
&__content
|
|
||||||
display flex
|
|
||||||
flex-direction column
|
|
||||||
justify-content space-between
|
|
||||||
|
|
||||||
&__title
|
|
||||||
font-weight bold
|
|
||||||
text-align right
|
|
||||||
margin-bottom $spacing-sm
|
|
||||||
|
|
||||||
&__text
|
|
||||||
text-justify()
|
|
||||||
font-size 0.9em
|
|
||||||
margin-bottom $spacing-sm
|
|
||||||
|
|
||||||
&__link
|
|
||||||
display block
|
|
||||||
text-align right
|
|
||||||
color $color-text
|
|
||||||
text-decoration none
|
|
||||||
font-size 0.85em
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
&__image-wrapper
|
|
||||||
overflow hidden
|
|
||||||
|
|
||||||
&__image
|
|
||||||
width 100%
|
|
||||||
height auto
|
|
||||||
display block
|
|
||||||
transition transform 0.3s ease
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
transform scale(1.05)
|
|
||||||
|
|
||||||
// Footer (БЭМ)
|
|
||||||
.footer
|
|
||||||
background-color $color-footer-bg
|
|
||||||
padding 1em 2em
|
|
||||||
margin-top $spacing-lg
|
|
||||||
display flex
|
|
||||||
gap 2em
|
|
||||||
|
|
||||||
&__text
|
|
||||||
font-size 1.1em
|
|
||||||