Отзывы и предложения к софту от AleXStam
Поговорим о...
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: Arial, sans-serif;
background-color: #fff;
padding: 10px;
font-size: 11px;
}

.container {
max-width: 1200px;
margin: 0 auto;
}

h1 {
text-align: center;
color: #333;
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.search-container {
margin: 15px 0;
text-align: center;
}

.icon-search-input {
width: 300px;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}

.icon-search-input:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.controls-row {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: #f0f0f0;
border-radius: 4px;
border: 1px solid #ddd;
}

.stats {
font-size: 12px;
}

.group-select {
padding: 6px 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 12px;
background: white;
}

.show-groups-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
}

.toggle-checkbox {
width: 16px;
height: 16px;
}

.comparison-container {
display: flex;
flex-wrap: wrap;
gap: 15px;
align-items: flex-start;
justify-content: center;
}

.group-section {
break-inside: avoid;
}

.group-header {
background: #f8f9fa;
padding: 6px 10px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: #495057;
font-size: 13px;
}

.icon-column {
border: 1px solid #e0e0e0;
border-radius: 5px;
padding: 8px;
background: #fafafa;
width: 420px; /* Увеличили ширину с 380px до 420px */
flex-shrink: 0;
}

.column-header {
display: grid;
grid-template-columns: 32px 20px 32px 1fr;
gap: 8px;
align-items: center;
padding: 5px 3px;
margin-bottom: 5px;
border-bottom: 1px solid #ddd;
font-weight: bold;
text-align: center;
}

.header-label {
font-size: 11px;
color: #333;
white-space: nowrap;
}

.icon-row {
display: grid;
grid-template-columns: 32px 20px 32px 1fr;
gap: 8px;
align-items: center;
padding: 6px 3px;
border-bottom: 1px solid #f0f0f0;
min-height: 40px;
}

.icon-row:last-child {
border-bottom: none;
}

.icon-image {
width: 32px;
height: 32px;
object-fit: contain;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
}

.bmp-processed {
filter: none;
}

.arrow {
text-align: center;
color: #999;
font-size: 14px;
font-weight: bold;
white-space: nowrap;
}

.icon-info {
padding-left: 8px;
padding-right: 5px;
min-width: 0;
width: 100%;
}

.icon-name {
color: #333;
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px; /* Увеличили шрифт с 11px до 12px */
max-width: 240px; /* Увеличили максимальную ширину */
}

.loading {
text-align: center;
padding: 20px;
color: #666;
width: 100%;
}

.no-results {
text-align: center;
padding: 40px;
color: #666;
width: 100%;
font-size: 14px;
}

.columns-container {
display: flex;
flex-wrap: wrap;
gap: 15px;
width: 100%;
justify-content: center;
}

.masonry-column {
display: flex;
flex-direction: column;
gap: 15px;
}

/* Адаптивность для мобильных устройств */
@media (max-width: 768px) {
.container {
max-width: 100%;
padding: 0 10px;
}

.icon-column {
width: 100%;
max-width: 420px; /* Обновили максимальную ширину */
}

.icon-search-input {
width: 100%;
max-width: 300px;
}

.controls-row {
flex-wrap: wrap;
gap: 10px;
}

.column-header {
gap: 4px;
padding: 5px 2px;
}

.header-label {
font-size: 10px;
}

.icon-name {
font-size: 11px; /* Чуть меньше на мобильных, но больше чем было */
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.icon-column {
width: 100%;
max-width: 100%;
}

.column-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 3px;
}

.header-label {
font-size: 9px;
}

.arrow {
font-size: 12px;
}

.icon-name {
font-size: 11px;
max-width: 200px;
}
}
</style>
</head>
<body>
<div class="container">
<h1>Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="search-container">
<input type="text"
id="iconSearchInput"
class="icon-search-input"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="controls-row">
<div class="stats">
Всего иконок для сравнения: <span id="totalCount">0</span> |
Отображено: <span id="shownCount">0</span>
</div>
<select id="groupSelect" class="group-select" style="display: none;">
<option value="">Все группы</option>
</select>
<div class="show-groups-toggle">
<input type="checkbox" id="showGroupsToggle" class="toggle-checkbox" checked>
<label for="showGroupsToggle">Показывать группы</label>
</div>
</div>

<div class="comparison-container" id="iconsContainer">
<div class="loading">Загрузка иконок...</div>
</div>
</div>

<script>
let allIcons = [];
let filteredIcons = [];
let availableGroups = [];
let showGroups = true;

// Функция для разбивки больших групп на части
function splitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для расчета примерной высоты группы
function calculateGroupHeight(iconsCount) {
const headerHeight = 40;
const rowHeight = 32;
const padding = 16;
return headerHeight + (iconsCount * rowHeight) + padding;
}

// Функция для создания адаптивной masonry компоновки
function createAdaptiveMasonryLayout(groupsChunks) {
const container = document.getElementById('iconsContainer');
const containerWidth = container.clientWidth;
const columnWidth = 420 + 15; // Обновили ширину колонки с учетом gap

const maxColumns = Math.floor(1200 / columnWidth);
const availableColumns = Math.min(maxColumns, Math.max(1, Math.floor(containerWidth / columnWidth)));

// Создаем колонки
const columns = Array.from({ length: availableColumns }, () => {
const col = document.createElement('div');
col.className = 'masonry-column';
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(availableColumns).fill(0);

// Распределяем группы по колонкам (алгоритм "наименьшая высота")
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = createGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

columnHeights[columnIndex] += group.height;
});

return columns;
}

// Функция для отображения иконок с группировкой (masonry компоновка)
function renderIconsWithGroups() {
const container = document.getElementById('iconsContainer');
container.innerHTML = '';

if (filteredIcons.length === 0) {
container.innerHTML = '<div class="no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
updateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = groupIcons(filteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = splitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: calculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы
if (noGroup.length > 0) {
const noGroupChunks = splitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: calculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте (от высоких к низким для лучшего заполнения)
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем адаптивную masonry компоновку
const columns = createAdaptiveMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'columns-container';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
updateStats();
}

// Функция для создания секции группы
function createGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'group-section';

const header = document.createElement('div');
header.className = 'group-header';
header.textContent = groupName;
section.appendChild(header);

const column = createIconColumn(icons);
section.appendChild(column);

return section;
}

// Функция для создания колонки с иконками
function createIconColumn(icons) {
const column = document.createElement('div');
column.className = 'icon-column';

const header = document.createElement('div');
header.className = 'column-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'header-label';
beforeLabel.textContent = 'ДО';
beforeLabel.style.whiteSpace = 'nowrap';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'arrow';
arrowSpace.textContent = '→';
arrowSpace.style.whiteSpace = 'nowrap';

const afterLabel = document.createElement('div');
afterLabel.className = 'header-label';
afterLabel.textContent = 'ПОСЛЕ';
afterLabel.style.whiteSpace = 'nowrap';

const nameLabel = document.createElement('div');
nameLabel.className = 'header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';
nameLabel.style.whiteSpace = 'nowrap';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(createIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function setupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (showGroups && filteredIcons.length > 0) {
renderIconsWithGroups();
}
}, 250);
});
}

// Остальные функции без изменений
function processBMPWithPinkBackground(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
console.warn('Ошибка обработки BMP:', error);
resolve({
element: img,
processed: false
});
}
});
}

function loadImageWithBMPProcessing(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await processBMPWithPinkBackground(img);
result.element.alt = alt;
resolve(result);
} else {
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
console.warn('Ошибка обработки изображения:', error, src);
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
console.warn('Ошибка загрузки изображения:', src);
const placeholder = new Image();
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function groupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function createIconRow(icon) {
const row = document.createElement('div');
row.className = 'icon-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
loadImageWithBMPProcessing(icon.before, `${icon.name} (до)`),
loadImageWithBMPProcessing(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'icon-image' + (beforeResult.processed ? ' bmp-processed' : '');
afterImg.className = 'icon-image' + (afterResult.processed ? ' bmp-processed' : '');

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'icon-info';

const name = document.createElement('div');
name.className = 'icon-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function renderIconsWithoutGroups() {
const container = document.getElementById('iconsContainer');
container.innerHTML = '';

if (filteredIcons.length === 0) {
container.innerHTML = '<div class="no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
updateStats();
return;
}

const sortedIcons = [...filteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = createIconColumn(columnIcons);
container.appendChild(column);
}

updateStats();
}

function filterIcons(searchTerm, selectedGroup = '') {
let filtered = [...allIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}

filteredIcons = filtered;
renderFilteredIcons();
}

function renderFilteredIcons() {
if (showGroups) {
renderIconsWithGroups();
} else {
renderIconsWithoutGroups();
}
}

function updateStats() {
document.getElementById('totalCount').textContent = allIcons.length;
document.getElementById('shownCount').textContent = filteredIcons.length;
}

function initGroupSelect(groups) {
const groupSelect = document.getElementById('groupSelect');
groupSelect.innerHTML = '<option value="">Все группы</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = groups.length > 0 ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('iconSearchInput').value;
filterIcons(searchTerm, this.value);
});
}

function renderIcons(images, groups) {
allIcons = images;
filteredIcons = [...allIcons];
availableGroups = groups;

initGroupSelect(groups);
renderFilteredIcons();
}

async function loadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

renderIcons(processedImages, data.availableGroups || []);
} else {
document.getElementById('iconsContainer').innerHTML = '<div class="loading">Ошибка загрузки данных</div>';
}
} catch (error) {
document.getElementById('iconsContainer').innerHTML = '<div class="loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
document.getElementById('iconsContainer').innerHTML = '<div class="loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
document.getElementById('iconsContainer').innerHTML = '<div class="loading">Ошибка загрузки иконок</div>';
}
}

function setupSearch() {
const searchInput = document.getElementById('iconSearchInput');
let searchTimeout;

searchInput.addEventListener('input', function(e) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('groupSelect').value;
filterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('groupSelect').value;
filterIcons('', selectedGroup);
}
});

searchInput.addEventListener('keypress', function(e) {
e.stopPropagation();
});

searchInput.addEventListener('keydown', function(e) {
e.stopPropagation();
});
}

function setupGroupsToggle() {
const toggle = document.getElementById('showGroupsToggle');

toggle.addEventListener('change', function() {
showGroups = this.checked;
renderFilteredIcons();
});
}

window.addEventListener('DOMContentLoaded', function() {
loadIcons();
setupSearch();
setupGroupsToggle();
setupResizeHandler();
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: Arial, sans-serif;
background-color: #fff;
padding: 10px;
font-size: 11px;
}

.container {
max-width: 1200px;
margin: 0 auto;
}

h1 {
text-align: center;
color: #333;
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.search-container {
margin: 15px 0;
text-align: center;
}

.icon-search-input {
width: 300px;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}

.icon-search-input:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.controls-row {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: #f0f0f0;
border-radius: 4px;
border: 1px solid #ddd;
}

.stats {
font-size: 12px;
}

.group-select {
padding: 6px 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 12px;
background: white;
}

.show-groups-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
}

.toggle-checkbox {
width: 16px;
height: 16px;
}

.comparison-container {
display: flex;
flex-wrap: wrap;
gap: 12px; /* Уменьшили gap с 15px до 12px */
align-items: flex-start;
justify-content: center;
}

.group-section {
break-inside: avoid;
}

.group-header {
background: #f8f9fa;
padding: 6px 10px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: #495057;
font-size: 13px;
}

.icon-column {
border: 1px solid #e0e0e0;
border-radius: 5px;
padding: 6px; /* Уменьшили padding с 8px до 6px */
background: #fafafa;
width: 400px; /* Уменьшили ширину с 420px до 400px */
flex-shrink: 0;
}

.column-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr; /* Уменьшили gap в заголовке */
gap: 6px; /* Уменьшили gap с 8px до 6px */
align-items: center;
padding: 4px 2px; /* Уменьшили padding */
margin-bottom: 4px; /* Уменьшили отступ */
border-bottom: 1px solid #ddd;
font-weight: bold;
text-align: center;
}

.header-label {
font-size: 11px;
color: #333;
white-space: nowrap;
}

.icon-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr; /* Уменьшили gap */
gap: 6px; /* Уменьшили gap с 8px до 6px */
align-items: center;
padding: 4px 2px; /* Уменьшили padding */
border-bottom: 1px solid #f0f0f0;
min-height: 36px; /* Уменьшили минимальную высоту */
}

.icon-row:last-child {
border-bottom: none;
}

.icon-image {
width: 32px;
height: 32px;
object-fit: contain;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
}

.bmp-processed {
filter: none;
}

.arrow {
text-align: center;
color: #999;
font-size: 13px; /* Уменьшили шрифт стрелки */
font-weight: bold;
white-space: nowrap;
}

.icon-info {
padding-left: 6px; /* Уменьшили padding */
padding-right: 3px; /* Уменьшили padding */
min-width: 0;
width: 100%;
}

.icon-name {
color: #333;
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 220px; /* Немного уменьшили максимальную ширину */
}

.loading {
text-align: center;
padding: 20px;
color: #666;
width: 100%;
}

.no-results {
text-align: center;
padding: 40px;
color: #666;
width: 100%;
font-size: 14px;
}

.columns-container {
display: flex;
flex-wrap: wrap;
gap: 12px; /* Уменьшили gap с 15px до 12px */
width: 100%;
justify-content: center;
}

.masonry-column {
display: flex;
flex-direction: column;
gap: 12px; /* Уменьшили gap с 15px до 12px */
}

/* Адаптивность для мобильных устройств */
@media (max-width: 768px) {
.container {
max-width: 100%;
padding: 0 10px;
}

.icon-column {
width: 100%;
max-width: 400px;
}

.icon-search-input {
width: 100%;
max-width: 300px;
}

.controls-row {
flex-wrap: wrap;
gap: 10px;
}

.column-header {
gap: 4px;
padding: 4px 2px;
}

.header-label {
font-size: 10px;
}

.icon-name {
font-size: 11px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.icon-column {
width: 100%;
max-width: 100%;
}

.column-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 3px;
}

.header-label {
font-size: 9px;
}

.arrow {
font-size: 12px;
}

.icon-name {
font-size: 11px;
max-width: 200px;
}
}
</style>
</head>
<body>
<div class="container">
<h1>Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="search-container">
<input type="text"
id="iconSearchInput"
class="icon-search-input"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="controls-row">
<div class="stats">
Всего иконок для сравнения: <span id="totalCount">0</span> |
Отображено: <span id="shownCount">0</span>
</div>
<select id="groupSelect" class="group-select" style="display: none;">
<option value="">Все группы</option>
</select>
<div class="show-groups-toggle">
<input type="checkbox" id="showGroupsToggle" class="toggle-checkbox" checked>
<label for="showGroupsToggle">Показывать группы</label>
</div>
</div>

<div class="comparison-container" id="iconsContainer">
<div class="loading">Загрузка иконок...</div>
</div>
</div>

<script>
let allIcons = [];
let filteredIcons = [];
let availableGroups = [];
let showGroups = true;

// Функция для разбивки больших групп на части
function splitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для расчета примерной высоты группы
function calculateGroupHeight(iconsCount) {
const headerHeight = 36; // Уменьшили высоту заголовка
const rowHeight = 30; // Уменьшили высоту строки
const padding = 12; // Уменьшили padding
return headerHeight + (iconsCount * rowHeight) + padding;
}

// Функция для создания адаптивной masonry компоновки
function createAdaptiveMasonryLayout(groupsChunks) {
const container = document.getElementById('iconsContainer');
const containerWidth = container.clientWidth;
const columnWidth = 400 + 12; // Обновили ширину колонки с учетом уменьшенного gap

const maxColumns = Math.floor(1200 / columnWidth);
const availableColumns = Math.min(maxColumns, Math.max(1, Math.floor(containerWidth / columnWidth)));

console.log(`Container width: ${containerWidth}, Column width: ${columnWidth}, Columns: ${availableColumns}`);

// Создаем колонки
const columns = Array.from({ length: availableColumns }, () => {
const col = document.createElement('div');
col.className = 'masonry-column';
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(availableColumns).fill(0);

// Распределяем группы по колонкам (алгоритм "наименьшая высота")
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = createGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

columnHeights[columnIndex] += group.height;
});

return columns;
}

// Функция для отображения иконок с группировкой (masonry компоновка)
function renderIconsWithGroups() {
const container = document.getElementById('iconsContainer');
container.innerHTML = '';

if (filteredIcons.length === 0) {
container.innerHTML = '<div class="no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
updateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = groupIcons(filteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = splitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: calculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы
if (noGroup.length > 0) {
const noGroupChunks = splitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: calculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте (от высоких к низким для лучшего заполнения)
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем адаптивную masonry компоновку
const columns = createAdaptiveMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'columns-container';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
updateStats();
}

// Функция для создания секции группы
function createGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'group-section';

const header = document.createElement('div');
header.className = 'group-header';
header.textContent = groupName;
section.appendChild(header);

const column = createIconColumn(icons);
section.appendChild(column);

return section;
}

// Функция для создания колонки с иконками
function createIconColumn(icons) {
const column = document.createElement('div');
column.className = 'icon-column';

const header = document.createElement('div');
header.className = 'column-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'header-label';
beforeLabel.textContent = 'ДО';
beforeLabel.style.whiteSpace = 'nowrap';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'arrow';
arrowSpace.textContent = '→';
arrowSpace.style.whiteSpace = 'nowrap';

const afterLabel = document.createElement('div');
afterLabel.className = 'header-label';
afterLabel.textContent = 'ПОСЛЕ';
afterLabel.style.whiteSpace = 'nowrap';

const nameLabel = document.createElement('div');
nameLabel.className = 'header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';
nameLabel.style.whiteSpace = 'nowrap';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(createIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function setupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (showGroups && filteredIcons.length > 0) {
renderIconsWithGroups();
}
}, 250);
});
}

// Остальные функции без изменений
function processBMPWithPinkBackground(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
console.warn('Ошибка обработки BMP:', error);
resolve({
element: img,
processed: false
});
}
});
}

function loadImageWithBMPProcessing(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await processBMPWithPinkBackground(img);
result.element.alt = alt;
resolve(result);
} else {
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
console.warn('Ошибка обработки изображения:', error, src);
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
console.warn('Ошибка загрузки изображения:', src);
const placeholder = new Image();
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDI1LjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function groupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function createIconRow(icon) {
const row = document.createElement('div');
row.className = 'icon-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
loadImageWithBMPProcessing(icon.before, `${icon.name} (до)`),
loadImageWithBMPProcessing(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'icon-image' + (beforeResult.processed ? ' bmp-processed' : '');
afterImg.className = 'icon-image' + (afterResult.processed ? ' bmp-processed' : '');

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'icon-info';

const name = document.createElement('div');
name.className = 'icon-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function renderIconsWithoutGroups() {
const container = document.getElementById('iconsContainer');
container.innerHTML = '';

if (filteredIcons.length === 0) {
container.innerHTML = '<div class="no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
updateStats();
return;
}

const sortedIcons = [...filteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = createIconColumn(columnIcons);
container.appendChild(column);
}

updateStats();
}

function filterIcons(searchTerm, selectedGroup = '') {
let filtered = [...allIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}

filteredIcons = filtered;
renderFilteredIcons();
}

function renderFilteredIcons() {
if (showGroups) {
renderIconsWithGroups();
} else {
renderIconsWithoutGroups();
}
}

function updateStats() {
document.getElementById('totalCount').textContent = allIcons.length;
document.getElementById('shownCount').textContent = filteredIcons.length;
}

function initGroupSelect(groups) {
const groupSelect = document.getElementById('groupSelect');
groupSelect.innerHTML = '<option value="">Все группы</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = groups.length > 0 ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('iconSearchInput').value;
filterIcons(searchTerm, this.value);
});
}

function renderIcons(images, groups) {
allIcons = images;
filteredIcons = [...allIcons];
availableGroups = groups;

initGroupSelect(groups);
renderFilteredIcons();
}

async function loadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

renderIcons(processedImages, data.availableGroups || []);
} else {
document.getElementById('iconsContainer').innerHTML = '<div class="loading">Ошибка загрузки данных</div>';
}
} catch (error) {
document.getElementById('iconsContainer').innerHTML = '<div class="loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
document.getElementById('iconsContainer').innerHTML = '<div class="loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
document.getElementById('iconsContainer').innerHTML = '<div class="loading">Ошибка загрузки иконок</div>';
}
}

function setupSearch() {
const searchInput = document.getElementById('iconSearchInput');
let searchTimeout;

searchInput.addEventListener('input', function(e) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('groupSelect').value;
filterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('groupSelect').value;
filterIcons('', selectedGroup);
}
});

searchInput.addEventListener('keypress', function(e) {
e.stopPropagation();
});

searchInput.addEventListener('keydown', function(e) {
e.stopPropagation();
});
}

function setupGroupsToggle() {
const toggle = document.getElementById('showGroupsToggle');

toggle.addEventListener('change', function() {
showGroups = this.checked;
renderFilteredIcons();
});
}

window.addEventListener('DOMContentLoaded', function() {
loadIcons();
setupSearch();
setupGroupsToggle();
setupResizeHandler();
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
.icon-comparison-container {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.icon-comparison-body {
font-family: Arial, sans-serif;
background-color: #fff;
padding: 10px;
font-size: 11px;
}

.icon-comparison-wrapper {
max-width: 1200px;
margin: 0 auto;
}

.icon-comparison-title {
text-align: center;
color: #333;
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.icon-comparison-search-area {
margin: 15px 0;
text-align: center;
}

.icon-comparison-search {
width: 300px;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}

.icon-comparison-search:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.icon-comparison-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: #f0f0f0;
border-radius: 4px;
border: 1px solid #ddd;
}

.icon-comparison-stats {
font-size: 12px;
}

.icon-comparison-group-select {
padding: 6px 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 12px;
background: white;
}

.icon-comparison-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
}

.icon-comparison-checkbox {
width: 16px;
height: 16px;
}

.icon-comparison-grid {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: flex-start;
justify-content: center;
}

.icon-comparison-group {
break-inside: avoid;
}

.icon-comparison-group-title {
background: #f8f9fa;
padding: 6px 10px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: #495057;
font-size: 13px;
}

.icon-comparison-panel {
border: 1px solid #e0e0e0;
border-radius: 5px;
padding: 6px;
background: #fafafa;
width: 400px;
flex-shrink: 0;
}

.icon-comparison-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid #ddd;
font-weight: bold;
text-align: center;
}

.icon-comparison-header-label {
font-size: 11px;
color: #333;
white-space: nowrap;
}

.icon-comparison-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid #f0f0f0;
min-height: 36px;
}

.icon-comparison-row:last-child {
border-bottom: none;
}

.icon-comparison-image {
width: 32px;
height: 32px;
object-fit: contain;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
}

.icon-comparison-bmp-processed {
filter: none;
}

.icon-comparison-arrow {
text-align: center;
color: #999;
font-size: 13px;
font-weight: bold;
white-space: nowrap;
}

.icon-comparison-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
width: 100%;
}

.icon-comparison-name {
color: #333;
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 220px;
}

.icon-comparison-loading {
text-align: center;
padding: 20px;
color: #666;
width: 100%;
}

.icon-comparison-no-results {
text-align: center;
padding: 40px;
color: #666;
width: 100%;
font-size: 14px;
}

.icon-comparison-columns {
display: flex;
flex-wrap: wrap;
gap: 12px;
width: 100%;
justify-content: center;
}

.icon-comparison-masonry-column {
display: flex;
flex-direction: column;
gap: 12px;
}

/* Адаптивность для мобильных устройств */
@media (max-width: 768px) {
.icon-comparison-wrapper {
max-width: 100%;
padding: 0 10px;
}

.icon-comparison-panel {
width: 100%;
max-width: 400px;
}

.icon-comparison-search {
width: 100%;
max-width: 300px;
}

.icon-comparison-controls {
flex-wrap: wrap;
gap: 10px;
}

.icon-comparison-panel-header {
gap: 4px;
padding: 4px 2px;
}

.icon-comparison-header-label {
font-size: 10px;
}

.icon-comparison-name {
font-size: 11px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.icon-comparison-panel {
width: 100%;
max-width: 100%;
}

.icon-comparison-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 3px;
}

.icon-comparison-header-label {
font-size: 9px;
}

.icon-comparison-arrow {
font-size: 12px;
}

.icon-comparison-name {
font-size: 11px;
max-width: 200px;
}
}

/* Для широких экранов - больше колонок */
@media (min-width: 1400px) {
.icon-comparison-wrapper {
max-width: 1400px;
}
}

@media (min-width: 1600px) {
.icon-comparison-wrapper {
max-width: 1600px;
}
}
</style>
</head>
<body class="icon-comparison-body">
<div class="icon-comparison-wrapper">
<h1 class="icon-comparison-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="icon-comparison-search-area">
<input type="text"
id="iconComparisonSearch"
class="icon-comparison-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="icon-comparison-controls">
<div class="icon-comparison-stats">
Всего иконок для сравнения: <span id="iconComparisonTotalCount">0</span> |
Отображено: <span id="iconComparisonShownCount">0</span>
</div>
<select id="iconComparisonGroupSelect" class="icon-comparison-group-select" style="display: none;">
<option value="">Все группы</option>
</select>
<div class="icon-comparison-toggle">
<input type="checkbox" id="iconComparisonShowGroups" class="icon-comparison-checkbox" checked>
<label for="iconComparisonShowGroups">Показывать группы</label>
</div>
</div>

<div class="icon-comparison-grid" id="iconComparisonContainer">
<div class="icon-comparison-loading">Загрузка иконок...</div>
</div>
</div>

<script>
let iconComparisonAllIcons = [];
let iconComparisonFilteredIcons = [];
let iconComparisonAvailableGroups = [];
let iconComparisonShowGroups = true;

// Функция для разбивки больших групп на части
function iconComparisonSplitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для расчета примерной высоты группы
function iconComparisonCalculateGroupHeight(iconsCount) {
const headerHeight = 36;
const rowHeight = 30;
const padding = 12;
return headerHeight + (iconsCount * rowHeight) + padding;
}

// Функция для создания адаптивной masonry компоновки
function iconComparisonCreateMasonryLayout(groupsChunks) {
const container = document.getElementById('iconComparisonContainer');
const containerWidth = container.clientWidth;
const columnWidth = 400 + 12;

const maxColumns = Math.floor(1600 / columnWidth); // Увеличили максимальное количество колонок
const availableColumns = Math.min(maxColumns, Math.max(1, Math.floor(containerWidth / columnWidth)));

console.log(`Container width: ${containerWidth}, Column width: ${columnWidth}, Columns: ${availableColumns}`);

// Создаем колонки
const columns = Array.from({ length: availableColumns }, () => {
const col = document.createElement('div');
col.className = 'icon-comparison-masonry-column';
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(availableColumns).fill(0);

// Распределяем группы по колонкам (алгоритм "наименьшая высота")
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = iconComparisonCreateGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

columnHeights[columnIndex] += group.height;
});

return columns;
}

// Функция для отображения иконок с группировкой (masonry компоновка)
function iconComparisonRenderWithGroups() {
const container = document.getElementById('iconComparisonContainer');
container.innerHTML = '';

if (iconComparisonFilteredIcons.length === 0) {
container.innerHTML = '<div class="icon-comparison-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
iconComparisonUpdateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = iconComparisonGroupIcons(iconComparisonFilteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = iconComparisonSplitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: iconComparisonCalculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы
if (noGroup.length > 0) {
const noGroupChunks = iconComparisonSplitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: iconComparisonCalculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте (от высоких к низким для лучшего заполнения)
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем адаптивную masonry компоновку
const columns = iconComparisonCreateMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'icon-comparison-columns';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
iconComparisonUpdateStats();
}

// Функция для создания секции группы
function iconComparisonCreateGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'icon-comparison-group';

const header = document.createElement('div');
header.className = 'icon-comparison-group-title';
header.textContent = groupName;
section.appendChild(header);

const column = iconComparisonCreateIconColumn(icons);
section.appendChild(column);

return section;
}

// Функция для создания колонки с иконками
function iconComparisonCreateIconColumn(icons) {
const column = document.createElement('div');
column.className = 'icon-comparison-panel';

const header = document.createElement('div');
header.className = 'icon-comparison-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'icon-comparison-header-label';
beforeLabel.textContent = 'ДО';
beforeLabel.style.whiteSpace = 'nowrap';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'icon-comparison-arrow';
arrowSpace.textContent = '→';
arrowSpace.style.whiteSpace = 'nowrap';

const afterLabel = document.createElement('div');
afterLabel.className = 'icon-comparison-header-label';
afterLabel.textContent = 'ПОСЛЕ';
afterLabel.style.whiteSpace = 'nowrap';

const nameLabel = document.createElement('div');
nameLabel.className = 'icon-comparison-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';
nameLabel.style.whiteSpace = 'nowrap';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(iconComparisonCreateIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function iconComparisonSetupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (iconComparisonShowGroups && iconComparisonFilteredIcons.length > 0) {
iconComparisonRenderWithGroups();
}
}, 250);
});
}

// Остальные функции с переименованными названиями
function iconComparisonProcessBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
console.warn('Ошибка обработки BMP:', error);
resolve({
element: img,
processed: false
});
}
});
}

function iconComparisonLoadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await iconComparisonProcessBMP(img);
result.element.alt = alt;
resolve(result);
} else {
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
console.warn('Ошибка обработки изображения:', error, src);
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
console.warn('Ошибка загрузки изображения:', src);
const placeholder = new Image();
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function iconComparisonGroupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function iconComparisonCreateIconRow(icon) {
const row = document.createElement('div');
row.className = 'icon-comparison-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
iconComparisonLoadImage(icon.before, `${icon.name} (до)`),
iconComparisonLoadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'icon-comparison-image' + (beforeResult.processed ? ' icon-comparison-bmp-processed' : '');
afterImg.className = 'icon-comparison-image' + (afterResult.processed ? ' icon-comparison-bmp-processed' : '');

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'icon-comparison-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'icon-comparison-info';

const name = document.createElement('div');
name.className = 'icon-comparison-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function iconComparisonRenderWithoutGroups() {
const container = document.getElementById('iconComparisonContainer');
container.innerHTML = '';

if (iconComparisonFilteredIcons.length === 0) {
container.innerHTML = '<div class="icon-comparison-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
iconComparisonUpdateStats();
return;
}

const sortedIcons = [...iconComparisonFilteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = iconComparisonCreateIconColumn(columnIcons);
container.appendChild(column);
}

iconComparisonUpdateStats();
}

function iconComparisonFilterIcons(searchTerm, selectedGroup = '') {
let filtered = [...iconComparisonAllIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}

iconComparisonFilteredIcons = filtered;
iconComparisonRenderFilteredIcons();
}

function iconComparisonRenderFilteredIcons() {
if (iconComparisonShowGroups) {
iconComparisonRenderWithGroups();
} else {
iconComparisonRenderWithoutGroups();
}
}

function iconComparisonUpdateStats() {
document.getElementById('iconComparisonTotalCount').textContent = iconComparisonAllIcons.length;
document.getElementById('iconComparisonShownCount').textContent = iconComparisonFilteredIcons.length;
}

function iconComparisonInitGroupSelect(groups) {
const groupSelect = document.getElementById('iconComparisonGroupSelect');
groupSelect.innerHTML = '<option value="">Все группы</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = groups.length > 0 ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('iconComparisonSearch').value;
iconComparisonFilterIcons(searchTerm, this.value);
});
}

function iconComparisonRenderIcons(images, groups) {
iconComparisonAllIcons = images;
iconComparisonFilteredIcons = [...iconComparisonAllIcons];
iconComparisonAvailableGroups = groups;

iconComparisonInitGroupSelect(groups);
iconComparisonRenderFilteredIcons();
}

async function iconComparisonLoadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

iconComparisonRenderIcons(processedImages, data.availableGroups || []);
} else {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки иконок</div>';
}
}

function iconComparisonSetupSearch() {
const searchInput = document.getElementById('iconComparisonSearch');
let searchTimeout;

searchInput.addEventListener('input', function(e) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('iconComparisonGroupSelect').value;
iconComparisonFilterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('iconComparisonGroupSelect').value;
iconComparisonFilterIcons('', selectedGroup);
}
});

searchInput.addEventListener('keypress', function(e) {
e.stopPropagation();
});

searchInput.addEventListener('keydown', function(e) {
e.stopPropagation();
});
}

function iconComparisonSetupToggle() {
const toggle = document.getElementById('iconComparisonShowGroups');

toggle.addEventListener('change', function() {
iconComparisonShowGroups = this.checked;
iconComparisonRenderFilteredIcons();
});
}

window.addEventListener('DOMContentLoaded', function() {
iconComparisonLoadIcons();
iconComparisonSetupSearch();
iconComparisonSetupToggle();
iconComparisonSetupResizeHandler();
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
.icon-comparison-container {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.icon-comparison-body {
font-family: Arial, sans-serif;
background-color: #fff;
padding: 10px;
font-size: 11px;
transition: background-color 0.3s ease, color 0.3s ease;
}

/* Темная тема */
.icon-comparison-body.dark-theme {
background-color: #1a1a1a;
color: #e0e0e0;
}

.icon-comparison-wrapper {
max-width: 1200px;
margin: 0 auto;
}

.icon-comparison-title {
text-align: center;
color: #333;
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
transition: color 0.3s ease;
}

.dark-theme .icon-comparison-title {
color: #e0e0e0;
}

.icon-comparison-search-area {
margin: 15px 0;
text-align: center;
}

.icon-comparison-search {
width: 300px;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
background-color: white;
color: #333;
transition: all 0.3s ease;
}

.dark-theme .icon-comparison-search {
background-color: #2d2d2d;
border-color: #555;
color: #e0e0e0;
}

.icon-comparison-search:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.dark-theme .icon-comparison-search:focus {
border-color: #4dabf7;
box-shadow: 0 0 0 2px rgba(77, 171, 247, 0.25);
}

.icon-comparison-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: #f0f0f0;
border-radius: 4px;
border: 1px solid #ddd;
transition: all 0.3s ease;
}

.dark-theme .icon-comparison-controls {
background: #2d2d2d;
border-color: #444;
}

.icon-comparison-stats {
font-size: 12px;
transition: color 0.3s ease;
}

.dark-theme .icon-comparison-stats {
color: #e0e0e0;
}

.icon-comparison-group-select {
padding: 6px 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 12px;
background: white;
color: #333;
transition: all 0.3s ease;
}

.dark-theme .icon-comparison-group-select {
background: #2d2d2d;
border-color: #555;
color: #e0e0e0;
}

.icon-comparison-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
transition: color 0.3s ease;
}

.dark-theme .icon-comparison-toggle {
color: #e0e0e0;
}

.icon-comparison-checkbox {
width: 16px;
height: 16px;
}

.icon-comparison-grid {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: flex-start;
justify-content: center;
}

.icon-comparison-group {
break-inside: avoid;
}

.icon-comparison-group-title {
background: #f8f9fa;
padding: 6px 10px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: #495057;
font-size: 13px;
transition: all 0.3s ease;
}

.dark-theme .icon-comparison-group-title {
background: #2d2d2d;
color: #e0e0e0;
}

.icon-comparison-panel {
border: 1px solid #e0e0e0;
border-radius: 5px;
padding: 6px;
background: #fafafa;
width: 400px;
flex-shrink: 0;
transition: all 0.3s ease;
}

.dark-theme .icon-comparison-panel {
background: #2d2d2d;
border-color: #444;
}

.icon-comparison-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid #ddd;
font-weight: bold;
text-align: center;
transition: all 0.3s ease;
}

.dark-theme .icon-comparison-panel-header {
border-bottom-color: #555;
}

.icon-comparison-header-label {
font-size: 11px;
color: #333;
white-space: nowrap;
transition: color 0.3s ease;
}

.dark-theme .icon-comparison-header-label {
color: #e0e0e0;
}

.icon-comparison-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid #f0f0f0;
min-height: 36px;
transition: all 0.3s ease;
}

.dark-theme .icon-comparison-row {
border-bottom-color: #444;
}

.icon-comparison-row:last-child {
border-bottom: none;
}

.icon-comparison-image {
width: 32px;
height: 32px;
object-fit: contain;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
background-color: transparent;
/* Для темных иконок на светлом фоне и наоборот */
mix-blend-mode: multiply;
}

.dark-theme .icon-comparison-image {
/* Инвертируем только темные иконки, светлые остаются как есть */
filter: brightness(1.2);
mix-blend-mode: screen;
}

/* Специальная обработка для обработанных BMP */
.icon-comparison-bmp-processed {
filter: none;
}

.dark-theme .icon-comparison-bmp-processed {
/* Для обработанных BMP сохраняем оригинальный вид */
filter: none;
mix-blend-mode: normal;
}

.icon-comparison-arrow {
text-align: center;
color: #999;
font-size: 13px;
font-weight: bold;
white-space: nowrap;
transition: color 0.3s ease;
}

.dark-theme .icon-comparison-arrow {
color: #777;
}

.icon-comparison-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
width: 100%;
}

.icon-comparison-name {
color: #333;
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 220px;
transition: color 0.3s ease;
}

.dark-theme .icon-comparison-name {
color: #e0e0e0;
}

.icon-comparison-loading {
text-align: center;
padding: 20px;
color: #666;
width: 100%;
transition: color 0.3s ease;
}

.dark-theme .icon-comparison-loading {
color: #999;
}

.icon-comparison-no-results {
text-align: center;
padding: 40px;
color: #666;
width: 100%;
font-size: 14px;
transition: color 0.3s ease;
}

.dark-theme .icon-comparison-no-results {
color: #999;
}

.icon-comparison-columns {
display: flex;
flex-wrap: wrap;
gap: 12px;
width: 100%;
justify-content: center;
}

.icon-comparison-masonry-column {
display: flex;
flex-direction: column;
gap: 12px;
}

/* Индикатор темы (для отладки) */
.icon-comparison-theme-indicator {
position: fixed;
bottom: 10px;
right: 10px;
padding: 5px 10px;
background: #007bff;
color: white;
border-radius: 3px;
font-size: 10px;
z-index: 1000;
opacity: 0.7;
}

/* Адаптивность для мобильных устройств */
@media (max-width: 768px) {
.icon-comparison-wrapper {
max-width: 100%;
padding: 0 10px;
}

.icon-comparison-panel {
width: 100%;
max-width: 400px;
}

.icon-comparison-search {
width: 100%;
max-width: 300px;
}

.icon-comparison-controls {
flex-wrap: wrap;
gap: 10px;
}

.icon-comparison-panel-header {
gap: 4px;
padding: 4px 2px;
}

.icon-comparison-header-label {
font-size: 10px;
}

.icon-comparison-name {
font-size: 11px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.icon-comparison-panel {
width: 100%;
max-width: 100%;
}

.icon-comparison-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 3px;
}

.icon-comparison-header-label {
font-size: 9px;
}

.icon-comparison-arrow {
font-size: 12px;
}

.icon-comparison-name {
font-size: 11px;
max-width: 200px;
}
}

/* Для широких экранов - больше колонок */
@media (min-width: 1400px) {
.icon-comparison-wrapper {
max-width: 1400px;
}
}

@media (min-width: 1600px) {
.icon-comparison-wrapper {
max-width: 1600px;
}
}
</style>
</head>
<body class="icon-comparison-body">
<div class="icon-comparison-wrapper">
<h1 class="icon-comparison-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="icon-comparison-search-area">
<input type="text"
id="iconComparisonSearch"
class="icon-comparison-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="icon-comparison-controls">
<div class="icon-comparison-stats">
Всего иконок для сравнения: <span id="iconComparisonTotalCount">0</span> |
Отображено: <span id="iconComparisonShownCount">0</span>
</div>
<select id="iconComparisonGroupSelect" class="icon-comparison-group-select" style="display: none;">
<option value="">Все группы</option>
</select>
<div class="icon-comparison-toggle">
<input type="checkbox" id="iconComparisonShowGroups" class="icon-comparison-checkbox" checked>
<label for="iconComparisonShowGroups">Показывать группы</label>
</div>
</div>

<div class="icon-comparison-grid" id="iconComparisonContainer">
<div class="icon-comparison-loading">Загрузка иконок...</div>
</div>
</div>

<!-- Индикатор темы (можно удалить в продакшене) -->
<div id="iconComparisonThemeIndicator" class="icon-comparison-theme-indicator" style="display: none;">
Тема: <span id="iconComparisonThemeStatus">светлая</span>
</div>

<script>
let iconComparisonAllIcons = [];
let iconComparisonFilteredIcons = [];
let iconComparisonAvailableGroups = [];
let iconComparisonShowGroups = true;
let iconComparisonIsDarkTheme = false;

// Функция для проверки и применения темы Hugo
function iconComparisonDetectAndApplyTheme() {
const body = document.querySelector('.icon-comparison-body');
const indicator = document.getElementById('iconComparisonThemeIndicator');

// Проверяем наличие класса dark-theme на корневом элементе Hugo
const htmlElement = document.documentElement;
const hugoBody = document.body;

// Различные способы определения темной темы в Hugo
const isDarkByClass = htmlElement.classList.contains('dark') ||
hugoBody.classList.contains('dark') ||
htmlElement.classList.contains('dark-mode') ||
hugoBody.classList.contains('dark-mode') ||
htmlElement.classList.contains('theme-dark') ||
hugoBody.classList.contains('theme-dark');

// Проверяем атрибуты data-theme
const isDarkByAttr = htmlElement.getAttribute('data-theme') === 'dark' ||
hugoBody.getAttribute('data-theme') === 'dark';

// Проверяем CSS переменные
const computedStyle = window.getComputedStyle(htmlElement);
const bgColor = computedStyle.backgroundColor;
const rgb = bgColor.match(/\d+/g);
if (rgb) {
const brightness = (parseInt(rgb[0]) * 299 + parseInt(rgb[1]) * 587 + parseInt(rgb[2]) * 114) / 1000;
const isDarkByColor = brightness < 128;

if (isDarkByColor) {
iconComparisonIsDarkTheme = true;
}
}

// Применяем тему если нашли признаки темной темы
if (isDarkByClass || isDarkByAttr || iconComparisonIsDarkTheme) {
body.classList.add('dark-theme');
iconComparisonIsDarkTheme = true;

// Обновляем индикатор
if (indicator) {
indicator.querySelector('#iconComparisonThemeStatus').textContent = 'тёмная';
indicator.style.display = 'block';
}
} else {
body.classList.remove('dark-theme');
iconComparisonIsDarkTheme = false;

// Обновляем индикатор
if (indicator) {
indicator.querySelector('#iconComparisonThemeStatus').textContent = 'светлая';
indicator.style.display = 'block';
}
}
}

// Наблюдатель за изменениями темы
function iconComparisonSetupThemeObserver() {
// Создаем наблюдатель за изменениями атрибутов
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes' &&
(mutation.attributeName === 'class' || mutation.attributeName === 'data-theme')) {
iconComparisonDetectAndApplyTheme();
}
});
});

// Начинаем наблюдение за корневым элементом и body
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'data-theme']
});

observer.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'data-theme']
});

// Также слушаем изменения CSS переменных
window.addEventListener('storage', iconComparisonDetectAndApplyTheme);

// Проверяем тему при загрузке
setTimeout(iconComparisonDetectAndApplyTheme, 100);

// И периодически проверяем (на случай динамического переключения)
setInterval(iconComparisonDetectAndApplyTheme, 1000);
}

// Функция для разбивки больших групп на части
function iconComparisonSplitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для расчета примерной высоты группы
function iconComparisonCalculateGroupHeight(iconsCount) {
const headerHeight = 36;
const rowHeight = 30;
const padding = 12;
return headerHeight + (iconsCount * rowHeight) + padding;
}

// Функция для создания адаптивной masonry компоновки
function iconComparisonCreateMasonryLayout(groupsChunks) {
const container = document.getElementById('iconComparisonContainer');
const containerWidth = container.clientWidth;
const columnWidth = 400 + 12;

const maxColumns = Math.floor(1600 / columnWidth);
const availableColumns = Math.min(maxColumns, Math.max(1, Math.floor(containerWidth / columnWidth)));

// Создаем колонки
const columns = Array.from({ length: availableColumns }, () => {
const col = document.createElement('div');
col.className = 'icon-comparison-masonry-column';
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(availableColumns).fill(0);

// Распределяем группы по колонкам (алгоритм "наименьшая высота")
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = iconComparisonCreateGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

columnHeights[columnIndex] += group.height;
});

return columns;
}

// Функция для отображения иконок с группировкой (masonry компоновка)
function iconComparisonRenderWithGroups() {
const container = document.getElementById('iconComparisonContainer');
container.innerHTML = '';

if (iconComparisonFilteredIcons.length === 0) {
container.innerHTML = '<div class="icon-comparison-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
iconComparisonUpdateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = iconComparisonGroupIcons(iconComparisonFilteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = iconComparisonSplitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: iconComparisonCalculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы
if (noGroup.length > 0) {
const noGroupChunks = iconComparisonSplitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: iconComparisonCalculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте (от высоких к низким для лучшего заполнения)
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем адаптивную masonry компоновку
const columns = iconComparisonCreateMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'icon-comparison-columns';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
iconComparisonUpdateStats();
}

// Функция для создания секции группы
function iconComparisonCreateGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'icon-comparison-group';

const header = document.createElement('div');
header.className = 'icon-comparison-group-title';
header.textContent = groupName;
section.appendChild(header);

const column = iconComparisonCreateIconColumn(icons);
section.appendChild(column);

return section;
}

// Функция для создания колонки с иконками
function iconComparisonCreateIconColumn(icons) {
const column = document.createElement('div');
column.className = 'icon-comparison-panel';

const header = document.createElement('div');
header.className = 'icon-comparison-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'icon-comparison-header-label';
beforeLabel.textContent = 'ДО';
beforeLabel.style.whiteSpace = 'nowrap';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'icon-comparison-arrow';
arrowSpace.textContent = '→';
arrowSpace.style.whiteSpace = 'nowrap';

const afterLabel = document.createElement('div');
afterLabel.className = 'icon-comparison-header-label';
afterLabel.textContent = 'ПОСЛЕ';
afterLabel.style.whiteSpace = 'nowrap';

const nameLabel = document.createElement('div');
nameLabel.className = 'icon-comparison-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';
nameLabel.style.whiteSpace = 'nowrap';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(iconComparisonCreateIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function iconComparisonSetupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (iconComparisonShowGroups && iconComparisonFilteredIcons.length > 0) {
iconComparisonRenderWithGroups();
}
}, 250);
});
}

// Остальные функции
function iconComparisonProcessBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
console.warn('Ошибка обработки BMP:', error);
resolve({
element: img,
processed: false
});
}
});
}

function iconComparisonLoadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await iconComparisonProcessBMP(img);
result.element.alt = alt;
resolve(result);
} else {
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
console.warn('Ошибка обработки изображения:', error, src);
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
console.warn('Ошибка загрузки изображения:', src);
const placeholder = new Image();
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function iconComparisonGroupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function iconComparisonCreateIconRow(icon) {
const row = document.createElement('div');
row.className = 'icon-comparison-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
iconComparisonLoadImage(icon.before, `${icon.name} (до)`),
iconComparisonLoadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'icon-comparison-image' + (beforeResult.processed ? ' icon-comparison-bmp-processed' : '');
afterImg.className = 'icon-comparison-image' + (afterResult.processed ? ' icon-comparison-bmp-processed' : '');

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'icon-comparison-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'icon-comparison-info';

const name = document.createElement('div');
name.className = 'icon-comparison-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function iconComparisonRenderWithoutGroups() {
const container = document.getElementById('iconComparisonContainer');
container.innerHTML = '';

if (iconComparisonFilteredIcons.length === 0) {
container.innerHTML = '<div class="icon-comparison-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
iconComparisonUpdateStats();
return;
}

const sortedIcons = [...iconComparisonFilteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = iconComparisonCreateIconColumn(columnIcons);
container.appendChild(column);
}

iconComparisonUpdateStats();
}

function iconComparisonFilterIcons(searchTerm, selectedGroup = '') {
let filtered = [...iconComparisonAllIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}

iconComparisonFilteredIcons = filtered;
iconComparisonRenderFilteredIcons();
}

function iconComparisonRenderFilteredIcons() {
if (iconComparisonShowGroups) {
iconComparisonRenderWithGroups();
} else {
iconComparisonRenderWithoutGroups();
}
}

function iconComparisonUpdateStats() {
document.getElementById('iconComparisonTotalCount').textContent = iconComparisonAllIcons.length;
document.getElementById('iconComparisonShownCount').textContent = iconComparisonFilteredIcons.length;
}

function iconComparisonInitGroupSelect(groups) {
const groupSelect = document.getElementById('iconComparisonGroupSelect');
groupSelect.innerHTML = '<option value="">Все группы</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = groups.length > 0 ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('iconComparisonSearch').value;
iconComparisonFilterIcons(searchTerm, this.value);
});
}

function iconComparisonRenderIcons(images, groups) {
iconComparisonAllIcons = images;
iconComparisonFilteredIcons = [...iconComparisonAllIcons];
iconComparisonAvailableGroups = groups;

iconComparisonInitGroupSelect(groups);
iconComparisonRenderFilteredIcons();
}

async function iconComparisonLoadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

iconComparisonRenderIcons(processedImages, data.availableGroups || []);
} else {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки иконок</div>';
}
}

function iconComparisonSetupSearch() {
const searchInput = document.getElementById('iconComparisonSearch');
let searchTimeout;

searchInput.addEventListener('input', function(e) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('iconComparisonGroupSelect').value;
iconComparisonFilterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('iconComparisonGroupSelect').value;
iconComparisonFilterIcons('', selectedGroup);
}
});

searchInput.addEventListener('keypress', function(e) {
e.stopPropagation();
});

searchInput.addEventListener('keydown', function(e) {
e.stopPropagation();
});
}

function iconComparisonSetupToggle() {
const toggle = document.getElementById('iconComparisonShowGroups');

toggle.addEventListener('change', function() {
iconComparisonShowGroups = this.checked;
iconComparisonRenderFilteredIcons();
});
}

window.addEventListener('DOMContentLoaded', function() {
// Сначала настраиваем определение темы
iconComparisonSetupThemeObserver();

// Затем загружаем остальное
iconComparisonLoadIcons();
iconComparisonSetupSearch();
iconComparisonSetupToggle();
iconComparisonSetupResizeHandler();
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
.icon-comparison-container {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.icon-comparison-body {
font-family: Arial, sans-serif;
background-color: #fff;
padding: 10px;
font-size: 11px;
}

/* Темная тема - упрощенная версия */
.icon-comparison-body.dark-mode {
background-color: #1a1a1a;
color: #e0e0e0;
}

.dark-mode .icon-comparison-title {
color: #e0e0e0;
}

.dark-mode .icon-comparison-controls {
background: #2d2d2d;
border-color: #444;
}

.dark-mode .icon-comparison-stats {
color: #e0e0e0;
}

.dark-mode .icon-comparison-search {
background-color: #2d2d2d;
border-color: #555;
color: #e0e0e0;
}

.dark-mode .icon-comparison-group-select {
background: #2d2d2d;
border-color: #555;
color: #e0e0e0;
}

.dark-mode .icon-comparison-toggle {
color: #e0e0e0;
}

.dark-mode .icon-comparison-group-title {
background: #2d2d2d;
color: #e0e0e0;
}

.dark-mode .icon-comparison-panel {
background: #2d2d2d;
border-color: #444;
}

.dark-mode .icon-comparison-panel-header {
border-bottom-color: #555;
}

.dark-mode .icon-comparison-header-label {
color: #e0e0e0;
}

.dark-mode .icon-comparison-row {
border-bottom-color: #444;
}

.dark-mode .icon-comparison-arrow {
color: #777;
}

.dark-mode .icon-comparison-name {
color: #e0e0e0;
}

.dark-mode .icon-comparison-loading {
color: #999;
}

.dark-mode .icon-comparison-no-results {
color: #999;
}

/* Основные стили */
.icon-comparison-wrapper {
max-width: 1200px;
margin: 0 auto;
}

.icon-comparison-title {
text-align: center;
color: #333;
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.icon-comparison-search-area {
margin: 15px 0;
text-align: center;
}

.icon-comparison-search {
width: 300px;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
background-color: white;
color: #333;
}

.icon-comparison-search:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.icon-comparison-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: #f0f0f0;
border-radius: 4px;
border: 1px solid #ddd;
}

.icon-comparison-stats {
font-size: 12px;
}

.icon-comparison-group-select {
padding: 6px 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 12px;
background: white;
color: #333;
}

.icon-comparison-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
}

.icon-comparison-checkbox {
width: 16px;
height: 16px;
}

.icon-comparison-grid {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: flex-start;
justify-content: center;
}

.icon-comparison-group {
break-inside: avoid;
}

.icon-comparison-group-title {
background: #f8f9fa;
padding: 6px 10px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: #495057;
font-size: 13px;
}

.icon-comparison-panel {
border: 1px solid #e0e0e0;
border-radius: 5px;
padding: 6px;
background: #fafafa;
width: 400px;
flex-shrink: 0;
}

.icon-comparison-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid #ddd;
font-weight: bold;
text-align: center;
}

.icon-comparison-header-label {
font-size: 11px;
color: #333;
white-space: nowrap;
}

.icon-comparison-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid #f0f0f0;
min-height: 36px;
}

.icon-comparison-row:last-child {
border-bottom: none;
}

.icon-comparison-image {
width: 32px;
height: 32px;
object-fit: contain;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
}

.icon-comparison-bmp-processed {
filter: none;
}

.icon-comparison-arrow {
text-align: center;
color: #999;
font-size: 13px;
font-weight: bold;
white-space: nowrap;
}

.icon-comparison-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
width: 100%;
}

.icon-comparison-name {
color: #333;
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 220px;
}

.icon-comparison-loading {
text-align: center;
padding: 20px;
color: #666;
width: 100%;
}

.icon-comparison-no-results {
text-align: center;
padding: 40px;
color: #666;
width: 100%;
font-size: 14px;
}

.icon-comparison-columns {
display: flex;
flex-wrap: wrap;
gap: 12px;
width: 100%;
justify-content: center;
}

.icon-comparison-masonry-column {
display: flex;
flex-direction: column;
gap: 12px;
}

/* Адаптивность */
@media (max-width: 768px) {
.icon-comparison-wrapper {
max-width: 100%;
padding: 0 10px;
}

.icon-comparison-panel {
width: 100%;
max-width: 400px;
}

.icon-comparison-search {
width: 100%;
max-width: 300px;
}

.icon-comparison-controls {
flex-wrap: wrap;
gap: 10px;
}

.icon-comparison-panel-header {
gap: 4px;
padding: 4px 2px;
}

.icon-comparison-header-label {
font-size: 10px;
}

.icon-comparison-name {
font-size: 11px;
}
}

@media (max-width: 480px) {
.icon-comparison-panel {
width: 100%;
max-width: 100%;
}

.icon-comparison-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 3px;
}

.icon-comparison-header-label {
font-size: 9px;
}

.icon-comparison-arrow {
font-size: 12px;
}

.icon-comparison-name {
font-size: 11px;
max-width: 200px;
}
}
</style>
</head>
<body class="icon-comparison-body">
<div class="icon-comparison-wrapper">
<h1 class="icon-comparison-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="icon-comparison-search-area">
<input type="text"
id="iconComparisonSearch"
class="icon-comparison-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="icon-comparison-controls">
<div class="icon-comparison-stats">
Всего иконок для сравнения: <span id="iconComparisonTotalCount">0</span> |
Отображено: <span id="iconComparisonShownCount">0</span>
</div>
<select id="iconComparisonGroupSelect" class="icon-comparison-group-select" style="display: none;">
<option value="">Все группы</option>
</select>
<div class="icon-comparison-toggle">
<input type="checkbox" id="iconComparisonShowGroups" class="icon-comparison-checkbox" checked>
<label for="iconComparisonShowGroups">Показывать группы</label>
</div>
</div>

<div class="icon-comparison-grid" id="iconComparisonContainer">
<div class="icon-comparison-loading">Загрузка иконок...</div>
</div>
</div>

<script>
let iconComparisonAllIcons = [];
let iconComparisonFilteredIcons = [];
let iconComparisonAvailableGroups = [];
let iconComparisonShowGroups = true;

// Простая функция для проверки темной темы
function iconComparisonCheckDarkTheme() {
const body = document.querySelector('.icon-comparison-body');

// Проверяем несколько способов определения темной темы
if (document.documentElement.classList.contains('dark') ||
document.body.classList.contains('dark') ||
document.documentElement.classList.contains('dark-mode') ||
document.body.classList.contains('dark-mode') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.getAttribute('data-theme') === 'dark') {

body.classList.add('dark-mode');
return true;
}

// Проверяем по цвету фона
const computedStyle = window.getComputedStyle(document.documentElement);
const bgColor = computedStyle.backgroundColor;
if (bgColor) {
const rgb = bgColor.match(/\d+/g);
if (rgb) {
const brightness = (parseInt(rgb[0]) * 299 + parseInt(rgb[1]) * 587 + parseInt(rgb[2]) * 114) / 1000;
if (brightness < 128) {
body.classList.add('dark-mode');
return true;
}
}
}

// Если не темная тема - убираем класс
body.classList.remove('dark-mode');
return false;
}

// Функция для разбивки больших групп на части
function iconComparisonSplitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для расчета примерной высоты группы
function iconComparisonCalculateGroupHeight(iconsCount) {
const headerHeight = 36;
const rowHeight = 30;
const padding = 12;
return headerHeight + (iconsCount * rowHeight) + padding;
}

// Функция для создания адаптивной masonry компоновки
function iconComparisonCreateMasonryLayout(groupsChunks) {
const container = document.getElementById('iconComparisonContainer');
const containerWidth = container.clientWidth;
const columnWidth = 400 + 12;

const maxColumns = Math.floor(1600 / columnWidth);
const availableColumns = Math.min(maxColumns, Math.max(1, Math.floor(containerWidth / columnWidth)));

// Создаем колонки
const columns = Array.from({ length: availableColumns }, () => {
const col = document.createElement('div');
col.className = 'icon-comparison-masonry-column';
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(availableColumns).fill(0);

// Распределяем группы по колонкам
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = iconComparisonCreateGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

columnHeights[columnIndex] += group.height;
});

return columns;
}

// Функция для отображения иконок с группировкой
function iconComparisonRenderWithGroups() {
const container = document.getElementById('iconComparisonContainer');
container.innerHTML = '';

if (iconComparisonFilteredIcons.length === 0) {
container.innerHTML = '<div class="icon-comparison-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
iconComparisonUpdateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = iconComparisonGroupIcons(iconComparisonFilteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = iconComparisonSplitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: iconComparisonCalculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы
if (noGroup.length > 0) {
const noGroupChunks = iconComparisonSplitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: iconComparisonCalculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем masonry компоновку
const columns = iconComparisonCreateMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'icon-comparison-columns';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
iconComparisonUpdateStats();
}

// Функция для создания секции группы
function iconComparisonCreateGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'icon-comparison-group';

const header = document.createElement('div');
header.className = 'icon-comparison-group-title';
header.textContent = groupName;
section.appendChild(header);

const column = iconComparisonCreateIconColumn(icons);
section.appendChild(column);

return section;
}

// Функция для создания колонки с иконками
function iconComparisonCreateIconColumn(icons) {
const column = document.createElement('div');
column.className = 'icon-comparison-panel';

const header = document.createElement('div');
header.className = 'icon-comparison-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'icon-comparison-header-label';
beforeLabel.textContent = 'ДО';
beforeLabel.style.whiteSpace = 'nowrap';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'icon-comparison-arrow';
arrowSpace.textContent = '→';
arrowSpace.style.whiteSpace = 'nowrap';

const afterLabel = document.createElement('div');
afterLabel.className = 'icon-comparison-header-label';
afterLabel.textContent = 'ПОСЛЕ';
afterLabel.style.whiteSpace = 'nowrap';

const nameLabel = document.createElement('div');
nameLabel.className = 'icon-comparison-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';
nameLabel.style.whiteSpace = 'nowrap';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(iconComparisonCreateIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function iconComparisonSetupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (iconComparisonShowGroups && iconComparisonFilteredIcons.length > 0) {
iconComparisonRenderWithGroups();
}
}, 250);
});
}

// Обработка BMP
function iconComparisonProcessBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
console.warn('Ошибка обработки BMP:', error);
resolve({
element: img,
processed: false
});
}
});
}

function iconComparisonLoadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await iconComparisonProcessBMP(img);
result.element.alt = alt;
resolve(result);
} else {
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
console.warn('Ошибка обработки изображения:', error, src);
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
console.warn('Ошибка загрузки изображения:', src);
const placeholder = new Image();
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function iconComparisonGroupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function iconComparisonCreateIconRow(icon) {
const row = document.createElement('div');
row.className = 'icon-comparison-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
iconComparisonLoadImage(icon.before, `${icon.name} (до)`),
iconComparisonLoadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'icon-comparison-image' + (beforeResult.processed ? ' icon-comparison-bmp-processed' : '');
afterImg.className = 'icon-comparison-image' + (afterResult.processed ? ' icon-comparison-bmp-processed' : '');

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'icon-comparison-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'icon-comparison-info';

const name = document.createElement('div');
name.className = 'icon-comparison-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function iconComparisonRenderWithoutGroups() {
const container = document.getElementById('iconComparisonContainer');
container.innerHTML = '';

if (iconComparisonFilteredIcons.length === 0) {
container.innerHTML = '<div class="icon-comparison-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
iconComparisonUpdateStats();
return;
}

const sortedIcons = [...iconComparisonFilteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = iconComparisonCreateIconColumn(columnIcons);
container.appendChild(column);
}

iconComparisonUpdateStats();
}

function iconComparisonFilterIcons(searchTerm, selectedGroup = '') {
let filtered = [...iconComparisonAllIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}

iconComparisonFilteredIcons = filtered;
iconComparisonRenderFilteredIcons();
}

function iconComparisonRenderFilteredIcons() {
if (iconComparisonShowGroups) {
iconComparisonRenderWithGroups();
} else {
iconComparisonRenderWithoutGroups();
}
}

function iconComparisonUpdateStats() {
document.getElementById('iconComparisonTotalCount').textContent = iconComparisonAllIcons.length;
document.getElementById('iconComparisonShownCount').textContent = iconComparisonFilteredIcons.length;
}

function iconComparisonInitGroupSelect(groups) {
const groupSelect = document.getElementById('iconComparisonGroupSelect');
groupSelect.innerHTML = '<option value="">Все группы</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = groups.length > 0 ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('iconComparisonSearch').value;
iconComparisonFilterIcons(searchTerm, this.value);
});
}

function iconComparisonRenderIcons(images, groups) {
iconComparisonAllIcons = images;
iconComparisonFilteredIcons = [...iconComparisonAllIcons];
iconComparisonAvailableGroups = groups;

iconComparisonInitGroupSelect(groups);
iconComparisonRenderFilteredIcons();
}

async function iconComparisonLoadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

iconComparisonRenderIcons(processedImages, data.availableGroups || []);
} else {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки иконок</div>';
}
}

function iconComparisonSetupSearch() {
const searchInput = document.getElementById('iconComparisonSearch');
let searchTimeout;

searchInput.addEventListener('input', function(e) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('iconComparisonGroupSelect').value;
iconComparisonFilterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('iconComparisonGroupSelect').value;
iconComparisonFilterIcons('', selectedGroup);
}
});

searchInput.addEventListener('keypress', function(e) {
e.stopPropagation();
});

searchInput.addEventListener('keydown', function(e) {
e.stopPropagation();
});
}

function iconComparisonSetupToggle() {
const toggle = document.getElementById('iconComparisonShowGroups');

toggle.addEventListener('change', function() {
iconComparisonShowGroups = this.checked;
iconComparisonRenderFilteredIcons();
});
}

window.addEventListener('DOMContentLoaded', function() {
// Простая проверка темы при загрузке
setTimeout(iconComparisonCheckDarkTheme, 100);

// Загружаем основной функционал
iconComparisonLoadIcons();
iconComparisonSetupSearch();
iconComparisonSetupToggle();
iconComparisonSetupResizeHandler();
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
/* Наши стили полностью изолированы */
.icon-comparison-page {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, sans-serif;
background-color: #fff;
padding: 10px;
font-size: 11px;
color: #333;
/* Изолируем наши стили от Hugo */
all: initial;
font-family: Arial, sans-serif !important;
}

.icon-comparison-page * {
box-sizing: border-box;
}

/* Светлая тема по умолчанию */
.icon-comparison-page[data-theme="light"] {
background-color: #fff;
color: #333;
}

/* Темная тема */
.icon-comparison-page[data-theme="dark"] {
background-color: #1a1a1a;
color: #e0e0e0;
}

.icon-comparison-wrapper {
max-width: 1200px;
margin: 0 auto;
}

.icon-comparison-title {
text-align: center;
color: #333;
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-title {
color: #e0e0e0;
}

.icon-comparison-search-area {
margin: 15px 0;
text-align: center;
}

.icon-comparison-search {
width: 300px;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
background-color: white;
color: #333;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-search {
background-color: #2d2d2d;
border-color: #555;
color: #e0e0e0;
}

.icon-comparison-search:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-search:focus {
border-color: #4dabf7;
box-shadow: 0 0 0 2px rgba(77, 171, 247, 0.25);
}

.icon-comparison-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: #f0f0f0;
border-radius: 4px;
border: 1px solid #ddd;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-controls {
background: #2d2d2d;
border-color: #444;
}

.icon-comparison-stats {
font-size: 12px;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-stats {
color: #e0e0e0;
}

.icon-comparison-group-select {
padding: 6px 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 12px;
background: white;
color: #333;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-group-select {
background: #2d2d2d;
border-color: #555;
color: #e0e0e0;
}

.icon-comparison-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-toggle {
color: #e0e0e0;
}

.icon-comparison-checkbox {
width: 16px;
height: 16px;
}

.icon-comparison-grid {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: flex-start;
justify-content: center;
}

.icon-comparison-group {
break-inside: avoid;
}

.icon-comparison-group-title {
background: #f8f9fa;
padding: 6px 10px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: #495057;
font-size: 13px;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-group-title {
background: #2d2d2d;
color: #e0e0e0;
}

.icon-comparison-panel {
border: 1px solid #e0e0e0;
border-radius: 5px;
padding: 6px;
background: #fafafa;
width: 400px;
flex-shrink: 0;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-panel {
background: #2d2d2d;
border-color: #444;
}

.icon-comparison-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid #ddd;
font-weight: bold;
text-align: center;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-panel-header {
border-bottom-color: #555;
}

.icon-comparison-header-label {
font-size: 11px;
color: #333;
white-space: nowrap;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-header-label {
color: #e0e0e0;
}

.icon-comparison-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid #f0f0f0;
min-height: 36px;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-row {
border-bottom-color: #444;
}

.icon-comparison-row:last-child {
border-bottom: none;
}

.icon-comparison-image {
width: 32px;
height: 32px;
object-fit: contain;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
/* Для темных иконок на светлом фоне */
background-color: transparent;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-image {
/* Небольшая коррекция для темной темы */
filter: brightness(1.1);
}

.icon-comparison-bmp-processed {
filter: none;
}

.icon-comparison-arrow {
text-align: center;
color: #999;
font-size: 13px;
font-weight: bold;
white-space: nowrap;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-arrow {
color: #777;
}

.icon-comparison-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
width: 100%;
}

.icon-comparison-name {
color: #333;
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 220px;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-name {
color: #e0e0e0;
}

.icon-comparison-loading {
text-align: center;
padding: 20px;
color: #666;
width: 100%;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-loading {
color: #999;
}

.icon-comparison-no-results {
text-align: center;
padding: 40px;
color: #666;
width: 100%;
font-size: 14px;
}

.icon-comparison-page[data-theme="dark"] .icon-comparison-no-results {
color: #999;
}

.icon-comparison-columns {
display: flex;
flex-wrap: wrap;
gap: 12px;
width: 100%;
justify-content: center;
}

.icon-comparison-masonry-column {
display: flex;
flex-direction: column;
gap: 12px;
}

/* Адаптивность для мобильных устройств */
@media (max-width: 768px) {
.icon-comparison-wrapper {
max-width: 100%;
padding: 0 10px;
}

.icon-comparison-panel {
width: 100%;
max-width: 400px;
}

.icon-comparison-search {
width: 100%;
max-width: 300px;
}

.icon-comparison-controls {
flex-wrap: wrap;
gap: 10px;
}

.icon-comparison-panel-header {
gap: 4px;
padding: 4px 2px;
}

.icon-comparison-header-label {
font-size: 10px;
}

.icon-comparison-name {
font-size: 11px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.icon-comparison-panel {
width: 100%;
max-width: 100%;
}

.icon-comparison-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 3px;
}

.icon-comparison-header-label {
font-size: 9px;
}

.icon-comparison-arrow {
font-size: 12px;
}

.icon-comparison-name {
font-size: 11px;
max-width: 200px;
}
}

/* Для широких экранов - больше колонок */
@media (min-width: 1400px) {
.icon-comparison-wrapper {
max-width: 1400px;
}
}

@media (min-width: 1600px) {
.icon-comparison-wrapper {
max-width: 1600px;
}
}
</style>
</head>
<body class="icon-comparison-page" data-theme="light">
<div class="icon-comparison-wrapper">
<h1 class="icon-comparison-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="icon-comparison-search-area">
<input type="text"
id="iconComparisonSearch"
class="icon-comparison-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="icon-comparison-controls">
<div class="icon-comparison-stats">
Всего иконок для сравнения: <span id="iconComparisonTotalCount">0</span> |
Отображено: <span id="iconComparisonShownCount">0</span>
</div>
<select id="iconComparisonGroupSelect" class="icon-comparison-group-select" style="display: none;">
<option value="">Все группы</option>
</select>
<div class="icon-comparison-toggle">
<input type="checkbox" id="iconComparisonShowGroups" class="icon-comparison-checkbox" checked>
<label for="iconComparisonShowGroups">Показывать группы</label>
</div>
</div>

<div class="icon-comparison-grid" id="iconComparisonContainer">
<div class="icon-comparison-loading">Загрузка иконок...</div>
</div>
</div>

<script>
// Глобальные переменные (изолированные)
window.iconComparisonData = {
allIcons: [],
filteredIcons: [],
availableGroups: [],
showGroups: true,
isDarkTheme: false
};

// Простая функция определения темы
function detectTheme() {
const pageElement = document.querySelector('.icon-comparison-page');

// Если страница открыта отдельно - всегда светлая тема
if (!window.parent || window.parent === window) {
pageElement.setAttribute('data-theme', 'light');
return;
}

try {
// Пробуем определить тему из родительского окна (Hugo)
const parentHtml = window.parent.document.documentElement;
const parentBody = window.parent.document.body;

// Проверяем различные признаки темной темы
const isDark =
parentHtml.classList.contains('dark') ||
parentHtml.classList.contains('dark-mode') ||
parentHtml.classList.contains('theme-dark') ||
parentBody.classList.contains('dark') ||
parentBody.classList.contains('dark-mode') ||
parentBody.classList.contains('theme-dark') ||
parentHtml.getAttribute('data-theme') === 'dark' ||
parentBody.getAttribute('data-theme') === 'dark' ||
window.parent.localStorage.getItem('theme') === 'dark' ||
window.parent.localStorage.getItem('color-scheme') === 'dark';

if (isDark) {
pageElement.setAttribute('data-theme', 'dark');
window.iconComparisonData.isDarkTheme = true;
} else {
pageElement.setAttribute('data-theme', 'light');
window.iconComparisonData.isDarkTheme = false;
}
} catch (error) {
// Если нет доступа к родительскому окну (CORS) или ошибка
pageElement.setAttribute('data-theme', 'light');
window.iconComparisonData.isDarkTheme = false;
}
}

// Функция для разбивки больших групп на части
function splitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для расчета примерной высоты группы
function calculateGroupHeight(iconsCount) {
const headerHeight = 36;
const rowHeight = 30;
const padding = 12;
return headerHeight + (iconsCount * rowHeight) + padding;
}

// Функция для создания адаптивной masonry компоновки
function createMasonryLayout(groupsChunks) {
const container = document.getElementById('iconComparisonContainer');
const containerWidth = container.clientWidth;
const columnWidth = 400 + 12;

const maxColumns = Math.floor(1600 / columnWidth);
const availableColumns = Math.min(maxColumns, Math.max(1, Math.floor(containerWidth / columnWidth)));

// Создаем колонки
const columns = Array.from({ length: availableColumns }, () => {
const col = document.createElement('div');
col.className = 'icon-comparison-masonry-column';
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(availableColumns).fill(0);

// Распределяем группы по колонкам (алгоритм "наименьшая высота")
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = createGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

columnHeights[columnIndex] += group.height;
});

return columns;
}

// Функция для отображения иконок с группировкой (masonry компоновка)
function renderWithGroups() {
const container = document.getElementById('iconComparisonContainer');
container.innerHTML = '';

if (window.iconComparisonData.filteredIcons.length === 0) {
container.innerHTML = '<div class="icon-comparison-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
updateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = groupIcons(window.iconComparisonData.filteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = splitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: calculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы
if (noGroup.length > 0) {
const noGroupChunks = splitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: calculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте (от высоких к низким для лучшего заполнения)
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем адаптивную masonry компоновку
const columns = createMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'icon-comparison-columns';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
updateStats();
}

// Функция для создания секции группы
function createGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'icon-comparison-group';

const header = document.createElement('div');
header.className = 'icon-comparison-group-title';
header.textContent = groupName;
section.appendChild(header);

const column = createIconColumn(icons);
section.appendChild(column);

return section;
}

// Функция для создания колонки с иконками
function createIconColumn(icons) {
const column = document.createElement('div');
column.className = 'icon-comparison-panel';

const header = document.createElement('div');
header.className = 'icon-comparison-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'icon-comparison-header-label';
beforeLabel.textContent = 'ДО';
beforeLabel.style.whiteSpace = 'nowrap';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'icon-comparison-arrow';
arrowSpace.textContent = '→';
arrowSpace.style.whiteSpace = 'nowrap';

const afterLabel = document.createElement('div');
afterLabel.className = 'icon-comparison-header-label';
afterLabel.textContent = 'ПОСЛЕ';
afterLabel.style.whiteSpace = 'nowrap';

const nameLabel = document.createElement('div');
nameLabel.className = 'icon-comparison-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';
nameLabel.style.whiteSpace = 'nowrap';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(createIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function setupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (window.iconComparisonData.showGroups && window.iconComparisonData.filteredIcons.length > 0) {
renderWithGroups();
}
}, 250);
});
}

// Остальные функции
function processBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
console.warn('Ошибка обработки BMP:', error);
resolve({
element: img,
processed: false
});
}
});
}

function loadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await processBMP(img);
result.element.alt = alt;
resolve(result);
} else {
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
console.warn('Ошибка обработки изображения:', error, src);
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
console.warn('Ошибка загрузки изображения:', src);
const placeholder = new Image();
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function groupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function createIconRow(icon) {
const row = document.createElement('div');
row.className = 'icon-comparison-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
loadImage(icon.before, `${icon.name} (до)`),
loadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'icon-comparison-image' + (beforeResult.processed ? ' icon-comparison-bmp-processed' : '');
afterImg.className = 'icon-comparison-image' + (afterResult.processed ? ' icon-comparison-bmp-processed' : '');

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'icon-comparison-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'icon-comparison-info';

const name = document.createElement('div');
name.className = 'icon-comparison-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function renderWithoutGroups() {
const container = document.getElementById('iconComparisonContainer');
container.innerHTML = '';

if (window.iconComparisonData.filteredIcons.length === 0) {
container.innerHTML = '<div class="icon-comparison-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
updateStats();
return;
}

const sortedIcons = [...window.iconComparisonData.filteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = createIconColumn(columnIcons);
container.appendChild(column);
}

updateStats();
}

function filterIcons(searchTerm, selectedGroup = '') {
let filtered = [...window.iconComparisonData.allIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}

window.iconComparisonData.filteredIcons = filtered;
renderFilteredIcons();
}

function renderFilteredIcons() {
if (window.iconComparisonData.showGroups) {
renderWithGroups();
} else {
renderWithoutGroups();
}
}

function updateStats() {
document.getElementById('iconComparisonTotalCount').textContent = window.iconComparisonData.allIcons.length;
document.getElementById('iconComparisonShownCount').textContent = window.iconComparisonData.filteredIcons.length;
}

function initGroupSelect(groups) {
const groupSelect = document.getElementById('iconComparisonGroupSelect');
groupSelect.innerHTML = '<option value="">Все группы</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = groups.length > 0 ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('iconComparisonSearch').value;
filterIcons(searchTerm, this.value);
});
}

function renderIcons(images, groups) {
window.iconComparisonData.allIcons = images;
window.iconComparisonData.filteredIcons = [...window.iconComparisonData.allIcons];
window.iconComparisonData.availableGroups = groups;

initGroupSelect(groups);
renderFilteredIcons();
}

async function loadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

renderIcons(processedImages, data.availableGroups || []);
} else {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки иконок</div>';
}
}

function setupSearch() {
const searchInput = document.getElementById('iconComparisonSearch');
let searchTimeout;

searchInput.addEventListener('input', function(e) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('iconComparisonGroupSelect').value;
filterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('iconComparisonGroupSelect').value;
filterIcons('', selectedGroup);
}
});

searchInput.addEventListener('keypress', function(e) {
e.stopPropagation();
});

searchInput.addEventListener('keydown', function(e) {
e.stopPropagation();
});
}

function setupToggle() {
const toggle = document.getElementById('iconComparisonShowGroups');

toggle.addEventListener('change', function() {
window.iconComparisonData.showGroups = this.checked;
renderFilteredIcons();
});
}

// Инициализация
document.addEventListener('DOMContentLoaded', function() {
// 1. Определяем тему (простая проверка)
detectTheme();

// 2. Загружаем иконки
loadIcons();

// 3. Настраиваем остальное
setupSearch();
setupToggle();
setupResizeHandler();

// 4. Простая проверка темы при загрузке (без сложных наблюдателей)
setTimeout(detectTheme, 100);
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
:root {
/* Светлая тема (по умолчанию) */
--ic-bg-color: #ffffff;
--ic-text-color: #333333;
--ic-panel-bg: #fafafa;
--ic-border-color: #e0e0e0;
--ic-header-bg: #f8f9fa;
--ic-header-text: #495057;
--ic-controls-bg: #f0f0f0;
--ic-search-border: #ddd;
--ic-search-focus: #007bff;
--ic-arrow-color: #999;
--ic-loading-color: #666;
--ic-row-border: #f0f0f0;
--ic-icon-bg: #f5f5f5;
}

/* Тёмная тема - активируется, когда Hugo устанавливает темную тему */
:root[data-theme="dark"],
html.dark-mode,
body.dark,
.dark-theme {
/* Переопределяем переменные для темной темы */
--ic-bg-color: #1a1a1a;
--ic-text-color: #e0e0e0;
--ic-panel-bg: #2d2d2d;
--ic-border-color: #404040;
--ic-header-bg: #3d3d3d;
--ic-header-text: #cccccc;
--ic-controls-bg: #333333;
--ic-search-border: #555;
--ic-search-focus: #4dabf7;
--ic-arrow-color: #888;
--ic-loading-color: #999;
--ic-row-border: #3a3a3a;
--ic-icon-bg: #2a2a2a; /* Светло-серый фон для иконок */
}

/* Дополнительные проверки для различных способов Hugo включения темной темы */
[data-mode="dark"],
[data-theme="dark"],
body[class*="dark"] {
--ic-bg-color: #1a1a1a;
--ic-text-color: #e0e0e0;
--ic-panel-bg: #2d2d2d;
--ic-border-color: #404040;
--ic-header-bg: #3d3d3d;
--ic-header-text: #cccccc;
--ic-controls-bg: #333333;
--ic-search-border: #555;
--ic-search-focus: #4dabf7;
--ic-arrow-color: #888;
--ic-loading-color: #999;
--ic-row-border: #3a3a3a;
--ic-icon-bg: #2a2a2a;
}

.icon-comparison-container {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.icon-comparison-body {
font-family: Arial, sans-serif;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
padding: 10px;
font-size: 11px;
transition: background-color 0.3s ease, color 0.3s ease;
}

.icon-comparison-wrapper {
max-width: 1200px;
margin: 0 auto;
}

.icon-comparison-title {
text-align: center;
color: var(--ic-text-color);
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.icon-comparison-search-area {
margin: 15px 0;
text-align: center;
}

.icon-comparison-search {
width: 300px;
padding: 8px 12px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 14px;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.icon-comparison-search:focus {
outline: none;
border-color: var(--ic-search-focus);
box-shadow: 0 0 0 2px rgba(77, 171, 247, 0.25);
}

.icon-comparison-search::placeholder {
color: var(--ic-arrow-color);
}

.icon-comparison-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: var(--ic-controls-bg);
border-radius: 4px;
border: 1px solid var(--ic-border-color);
transition: all 0.3s ease;
}

.icon-comparison-stats {
font-size: 12px;
color: var(--ic-text-color);
}

.icon-comparison-group-select {
padding: 6px 10px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 12px;
background: var(--ic-bg-color);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.icon-comparison-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
color: var(--ic-text-color);
}

.icon-comparison-checkbox {
width: 16px;
height: 16px;
accent-color: var(--ic-search-focus);
}

.icon-comparison-grid {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: flex-start;
justify-content: center;
}

.icon-comparison-group {
break-inside: avoid;
}

.icon-comparison-group-title {
background: var(--ic-header-bg);
padding: 6px 10px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: var(--ic-header-text);
font-size: 13px;
transition: all 0.3s ease;
}

.icon-comparison-panel {
border: 1px solid var(--ic-border-color);
border-radius: 5px;
padding: 6px;
background: var(--ic-panel-bg);
width: 400px;
flex-shrink: 0;
transition: all 0.3s ease;
}

.icon-comparison-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid var(--ic-border-color);
font-weight: bold;
text-align: center;
color: var(--ic-text-color);
}

.icon-comparison-header-label {
font-size: 11px;
color: var(--ic-text-color);
white-space: nowrap;
}

.icon-comparison-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid var(--ic-row-border);
min-height: 36px;
transition: border-color 0.3s ease;
}

.icon-comparison-row:last-child {
border-bottom: none;
}

.icon-comparison-image {
width: 32px;
height: 32px;
object-fit: contain;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
background-color: var(--ic-icon-bg);
border-radius: 3px;
padding: 2px;
box-sizing: border-box;
}

.icon-comparison-bmp-processed {
filter: none;
}

.icon-comparison-arrow {
text-align: center;
color: var(--ic-arrow-color);
font-size: 13px;
font-weight: bold;
white-space: nowrap;
}

.icon-comparison-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
width: 100%;
}

.icon-comparison-name {
color: var(--ic-text-color);
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 220px;
}

.icon-comparison-loading {
text-align: center;
padding: 20px;
color: var(--ic-loading-color);
width: 100%;
}

.icon-comparison-no-results {
text-align: center;
padding: 40px;
color: var(--ic-loading-color);
width: 100%;
font-size: 14px;
}

.icon-comparison-columns {
display: flex;
flex-wrap: wrap;
gap: 12px;
width: 100%;
justify-content: center;
}

.icon-comparison-masonry-column {
display: flex;
flex-direction: column;
gap: 12px;
}

/* Адаптивность для мобильных устройств */
@media (max-width: 768px) {
.icon-comparison-wrapper {
max-width: 100%;
padding: 0 10px;
}

.icon-comparison-panel {
width: 100%;
max-width: 400px;
}

.icon-comparison-search {
width: 100%;
max-width: 300px;
}

.icon-comparison-controls {
flex-wrap: wrap;
gap: 10px;
}

.icon-comparison-panel-header {
gap: 4px;
padding: 4px 2px;
}

.icon-comparison-header-label {
font-size: 10px;
}

.icon-comparison-name {
font-size: 11px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.icon-comparison-panel {
width: 100%;
max-width: 100%;
}

.icon-comparison-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 3px;
}

.icon-comparison-header-label {
font-size: 9px;
}

.icon-comparison-arrow {
font-size: 12px;
}

.icon-comparison-name {
font-size: 11px;
max-width: 200px;
}
}

/* Для широких экранов - больше колонок */
@media (min-width: 1400px) {
.icon-comparison-wrapper {
max-width: 1400px;
}
}

@media (min-width: 1600px) {
.icon-comparison-wrapper {
max-width: 1600px;
}
}

/* Стили для placeholder в темной теме */
:root[data-theme="dark"] .icon-comparison-image,
html.dark-mode .icon-comparison-image,
body.dark .icon-comparison-image {
background-color: var(--ic-icon-bg);
}
</style>
</head>
<body class="icon-comparison-body">
<div class="icon-comparison-wrapper">
<h1 class="icon-comparison-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="icon-comparison-search-area">
<input type="text"
id="iconComparisonSearch"
class="icon-comparison-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="icon-comparison-controls">
<div class="icon-comparison-stats">
Всего иконок для сравнения: <span id="iconComparisonTotalCount">0</span> |
Отображено: <span id="iconComparisonShownCount">0</span>
</div>
<select id="iconComparisonGroupSelect" class="icon-comparison-group-select" style="display: none;">
<option value="">Все группы</option>
</select>
<div class="icon-comparison-toggle">
<input type="checkbox" id="iconComparisonShowGroups" class="icon-comparison-checkbox" checked>
<label for="iconComparisonShowGroups">Показывать группы</label>
</div>
</div>

<div class="icon-comparison-grid" id="iconComparisonContainer">
<div class="icon-comparison-loading">Загрузка иконок...</div>
</div>
</div>

<script>
let iconComparisonAllIcons = [];
let iconComparisonFilteredIcons = [];
let iconComparisonAvailableGroups = [];
let iconComparisonShowGroups = true;

// Функция для определения текущей темы Hugo
function iconComparisonDetectHugoTheme() {
// Проверяем различные способы, которыми Hugo может указывать тему
const htmlElement = document.documentElement;
const bodyElement = document.body;

// Проверяем data-атрибуты
if (htmlElement.hasAttribute('data-theme') && htmlElement.getAttribute('data-theme') === 'dark') {
return 'dark';
}

if (htmlElement.hasAttribute('data-mode') && htmlElement.getAttribute('data-mode') === 'dark') {
return 'dark';
}

// Проверяем классы на html
if (htmlElement.classList.contains('dark')) {
return 'dark';
}

if (htmlElement.classList.contains('dark-mode')) {
return 'dark';
}

// Проверяем классы на body
if (bodyElement.classList.contains('dark')) {
return 'dark';
}

if (bodyElement.classList.contains('dark-theme')) {
return 'dark';
}

if (bodyElement.classList.contains('dark-mode')) {
return 'dark';
}

// Проверяем наличие класса dark в любом родительском элементе
if (document.querySelector('html.dark, body.dark, .dark, [data-theme="dark"], [data-mode="dark"]')) {
return 'dark';
}

// По умолчанию светлая тема
return 'light';
}

// Функция для применения темы к странице
function iconComparisonApplyTheme() {
const theme = iconComparisonDetectHugoTheme();
const body = document.querySelector('.icon-comparison-body');
const html = document.documentElement;

if (theme === 'dark') {
// Устанавливаем data-атрибут для CSS-переменных
html.setAttribute('data-theme', 'dark');
// Также добавляем класс для дополнительной специфичности
body.classList.add('dark-theme');
} else {
html.removeAttribute('data-theme');
body.classList.remove('dark-theme');
}

console.log('Тема Hugo определена как:', theme);
}

// Наблюдатель за изменениями атрибутов (если Hugo динамически меняет тему)
function iconComparisonSetupThemeObserver() {
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'attributes' &&
(mutation.attributeName === 'class' ||
mutation.attributeName === 'data-theme' ||
mutation.attributeName === 'data-mode')) {
iconComparisonApplyTheme();
}
});
});

// Наблюдаем за изменениями в html и body
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'data-theme', 'data-mode']
});

observer.observe(document.body, {
attributes: true,
attributeFilter: ['class']
});
}

// Функция для разбивки больших групп на части
function iconComparisonSplitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для расчета примерной высоты группы
function iconComparisonCalculateGroupHeight(iconsCount) {
const headerHeight = 36;
const rowHeight = 30;
const padding = 12;
return headerHeight + (iconsCount * rowHeight) + padding;
}

// Функция для создания адаптивной masonry компоновки
function iconComparisonCreateMasonryLayout(groupsChunks) {
const container = document.getElementById('iconComparisonContainer');
const containerWidth = container.clientWidth;
const columnWidth = 400 + 12;

const maxColumns = Math.floor(1600 / columnWidth); // Увеличили максимальное количество колонок
const availableColumns = Math.min(maxColumns, Math.max(1, Math.floor(containerWidth / columnWidth)));

console.log(`Container width: ${containerWidth}, Column width: ${columnWidth}, Columns: ${availableColumns}`);

// Создаем колонки
const columns = Array.from({ length: availableColumns }, () => {
const col = document.createElement('div');
col.className = 'icon-comparison-masonry-column';
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(availableColumns).fill(0);

// Распределяем группы по колонкам (алгоритм "наименьшая высота")
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = iconComparisonCreateGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

columnHeights[columnIndex] += group.height;
});

return columns;
}

// Функция для отображения иконок с группировкой (masonry компоновка)
function iconComparisonRenderWithGroups() {
const container = document.getElementById('iconComparisonContainer');
container.innerHTML = '';

if (iconComparisonFilteredIcons.length === 0) {
container.innerHTML = '<div class="icon-comparison-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
iconComparisonUpdateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = iconComparisonGroupIcons(iconComparisonFilteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = iconComparisonSplitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: iconComparisonCalculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы
if (noGroup.length > 0) {
const noGroupChunks = iconComparisonSplitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: iconComparisonCalculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте (от высоких к низким для лучшего заполнения)
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем адаптивную masonry компоновку
const columns = iconComparisonCreateMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'icon-comparison-columns';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
iconComparisonUpdateStats();
}

// Функция для создания секции группы
function iconComparisonCreateGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'icon-comparison-group';

const header = document.createElement('div');
header.className = 'icon-comparison-group-title';
header.textContent = groupName;
section.appendChild(header);

const column = iconComparisonCreateIconColumn(icons);
section.appendChild(column);

return section;
}

// Функция для создания колонки с иконками
function iconComparisonCreateIconColumn(icons) {
const column = document.createElement('div');
column.className = 'icon-comparison-panel';

const header = document.createElement('div');
header.className = 'icon-comparison-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'icon-comparison-header-label';
beforeLabel.textContent = 'ДО';
beforeLabel.style.whiteSpace = 'nowrap';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'icon-comparison-arrow';
arrowSpace.textContent = '→';
arrowSpace.style.whiteSpace = 'nowrap';

const afterLabel = document.createElement('div');
afterLabel.className = 'icon-comparison-header-label';
afterLabel.textContent = 'ПОСЛЕ';
afterLabel.style.whiteSpace = 'nowrap';

const nameLabel = document.createElement('div');
nameLabel.className = 'icon-comparison-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';
nameLabel.style.whiteSpace = 'nowrap';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(iconComparisonCreateIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function iconComparisonSetupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (iconComparisonShowGroups && iconComparisonFilteredIcons.length > 0) {
iconComparisonRenderWithGroups();
}
}, 250);
});
}

// Остальные функции с переименованными названиями
function iconComparisonProcessBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
console.warn('Ошибка обработки BMP:', error);
resolve({
element: img,
processed: false
});
}
});
}

function iconComparisonLoadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await iconComparisonProcessBMP(img);
result.element.alt = alt;
resolve(result);
} else {
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
console.warn('Ошибка обработки изображения:', error, src);
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
console.warn('Ошибка загрузки изображения:', src);
const placeholder = new Image();
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSJ2YXIoLS1pYy1pY29uLWJnKSIvPgo8cGF0aCBkPSJNMTYgMThDMTYuNTUyMyAxOCAxNyAxNy41NTIzIDE3IDE3VjExQzE3IDEwLjQ0NzcgMTYuNTUyMyAxMCAxNiAxMEMxNS40NDc3IDEwIDE1IDEwLjQ0NzcgMTUgMTFWMTdDMTUgMTcuNTUyMyAxNS40NDc3IDE4IDE2IDE4WiIgZmlsbD0idmFyKC0taWMtYXJyb3ctY29sb3IpIi8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSJ2YXIoLS1pYy1hcnJvdy1jb2xvcikiLz4KPC9zdmc+Cg==';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function iconComparisonGroupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function iconComparisonCreateIconRow(icon) {
const row = document.createElement('div');
row.className = 'icon-comparison-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
iconComparisonLoadImage(icon.before, `${icon.name} (до)`),
iconComparisonLoadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'icon-comparison-image' + (beforeResult.processed ? ' icon-comparison-bmp-processed' : '');
afterImg.className = 'icon-comparison-image' + (afterResult.processed ? ' icon-comparison-bmp-processed' : '');

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'icon-comparison-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'icon-comparison-info';

const name = document.createElement('div');
name.className = 'icon-comparison-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function iconComparisonRenderWithoutGroups() {
const container = document.getElementById('iconComparisonContainer');
container.innerHTML = '';

if (iconComparisonFilteredIcons.length === 0) {
container.innerHTML = '<div class="icon-comparison-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
iconComparisonUpdateStats();
return;
}

const sortedIcons = [...iconComparisonFilteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = iconComparisonCreateIconColumn(columnIcons);
container.appendChild(column);
}

iconComparisonUpdateStats();
}

function iconComparisonFilterIcons(searchTerm, selectedGroup = '') {
let filtered = [...iconComparisonAllIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}

iconComparisonFilteredIcons = filtered;
iconComparisonRenderFilteredIcons();
}

function iconComparisonRenderFilteredIcons() {
if (iconComparisonShowGroups) {
iconComparisonRenderWithGroups();
} else {
iconComparisonRenderWithoutGroups();
}
}

function iconComparisonUpdateStats() {
document.getElementById('iconComparisonTotalCount').textContent = iconComparisonAllIcons.length;
document.getElementById('iconComparisonShownCount').textContent = iconComparisonFilteredIcons.length;
}

function iconComparisonInitGroupSelect(groups) {
const groupSelect = document.getElementById('iconComparisonGroupSelect');
groupSelect.innerHTML = '<option value="">Все группы</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = groups.length > 0 ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('iconComparisonSearch').value;
iconComparisonFilterIcons(searchTerm, this.value);
});
}

function iconComparisonRenderIcons(images, groups) {
iconComparisonAllIcons = images;
iconComparisonFilteredIcons = [...iconComparisonAllIcons];
iconComparisonAvailableGroups = groups;

iconComparisonInitGroupSelect(groups);
iconComparisonRenderFilteredIcons();
}

async function iconComparisonLoadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

iconComparisonRenderIcons(processedImages, data.availableGroups || []);
} else {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
document.getElementById('iconComparisonContainer').innerHTML = '<div class="icon-comparison-loading">Ошибка загрузки иконок</div>';
}
}

function iconComparisonSetupSearch() {
const searchInput = document.getElementById('iconComparisonSearch');
let searchTimeout;

searchInput.addEventListener('input', function(e) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('iconComparisonGroupSelect').value;
iconComparisonFilterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('iconComparisonGroupSelect').value;
iconComparisonFilterIcons('', selectedGroup);
}
});

searchInput.addEventListener('keypress', function(e) {
e.stopPropagation();
});

searchInput.addEventListener('keydown', function(e) {
e.stopPropagation();
});
}

function iconComparisonSetupToggle() {
const toggle = document.getElementById('iconComparisonShowGroups');

toggle.addEventListener('change', function() {
iconComparisonShowGroups = this.checked;
iconComparisonRenderFilteredIcons();
});
}

window.addEventListener('DOMContentLoaded', function() {
// Применяем тему при загрузке
iconComparisonApplyTheme();

// Настраиваем наблюдатель за изменениями темы
iconComparisonSetupThemeObserver();

// Загружаем остальные компоненты
iconComparisonLoadIcons();
iconComparisonSetupSearch();
iconComparisonSetupToggle();
iconComparisonSetupResizeHandler();
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
/* Изолированные CSS-переменные с уникальными префиксами */
.icon-compare-isolated-root {
/* Светлая тема (по умолчанию) */
--icon-compare-bg-color: #ffffff;
--icon-compare-text-color: #333333;
--icon-compare-panel-bg: #fafafa;
--icon-compare-border-color: #e0e0e0;
--icon-compare-header-bg: #f8f9fa;
--icon-compare-header-text: #495057;
--icon-compare-controls-bg: #f0f0f0;
--icon-compare-search-border: #ddd;
--icon-compare-search-focus: #007bff;
--icon-compare-arrow-color: #999;
--icon-compare-loading-color: #666;
--icon-compare-row-border: #f0f0f0;
--icon-compare-icon-bg: #f5f5f5;
--icon-compare-select-bg: #ffffff;
--icon-compare-checkbox-color: #007bff;
}

/* Темная тема */
.icon-compare-isolated-root[data-icon-compare-theme="dark"],
.icon-compare-isolated-root.icon-compare-dark {
--icon-compare-bg-color: #1a1a1a;
--icon-compare-text-color: #e0e0e0;
--icon-compare-panel-bg: #2d2d2d;
--icon-compare-border-color: #404040;
--icon-compare-header-bg: #3d3d3d;
--icon-compare-header-text: #cccccc;
--icon-compare-controls-bg: #333333;
--icon-compare-search-border: #555;
--icon-compare-search-focus: #4dabf7;
--icon-compare-arrow-color: #888;
--icon-compare-loading-color: #999;
--icon-compare-row-border: #3a3a3a;
--icon-compare-icon-bg: #2a2a2a;
--icon-compare-select-bg: #2d2d2d;
--icon-compare-checkbox-color: #4dabf7;
}

/* Основной контейнер с уникальным классом */
.icon-compare-isolated-root {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, sans-serif;
background-color: var(--icon-compare-bg-color);
color: var(--icon-compare-text-color);
padding: 10px;
font-size: 11px;
min-height: 100vh;
transition: background-color 0.3s ease, color 0.3s ease;
isolation: isolate; /* Изолируем от внешних стилей */
}

/* Все классы с уникальным префиксом */
.icon-compare-wrapper {
max-width: 1200px;
margin: 0 auto;
}

.icon-compare-title {
text-align: center;
color: var(--icon-compare-text-color);
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.icon-compare-search-area {
margin: 15px 0;
text-align: center;
}

.icon-compare-search {
width: 300px;
padding: 8px 12px;
border: 1px solid var(--icon-compare-search-border);
border-radius: 4px;
font-size: 14px;
background-color: var(--icon-compare-bg-color);
color: var(--icon-compare-text-color);
transition: all 0.3s ease;
}

.icon-compare-search:focus {
outline: none;
border-color: var(--icon-compare-search-focus);
box-shadow: 0 0 0 2px rgba(77, 171, 247, 0.25);
}

.icon-compare-search::placeholder {
color: var(--icon-compare-arrow-color);
}

.icon-compare-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: var(--icon-compare-controls-bg);
border-radius: 4px;
border: 1px solid var(--icon-compare-border-color);
transition: all 0.3s ease;
}

.icon-compare-stats {
font-size: 12px;
color: var(--icon-compare-text-color);
}

.icon-compare-group-select {
padding: 6px 10px;
border: 1px solid var(--icon-compare-search-border);
border-radius: 4px;
font-size: 12px;
background: var(--icon-compare-select-bg);
color: var(--icon-compare-text-color);
transition: all 0.3s ease;
cursor: pointer;
}

.icon-compare-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
color: var(--icon-compare-text-color);
}

.icon-compare-checkbox {
width: 16px;
height: 16px;
accent-color: var(--icon-compare-checkbox-color);
cursor: pointer;
}

.icon-compare-grid {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: flex-start;
justify-content: center;
}

.icon-compare-group {
break-inside: avoid;
}

.icon-compare-group-title {
background: var(--icon-compare-header-bg);
padding: 6px 10px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: var(--icon-compare-header-text);
font-size: 13px;
transition: all 0.3s ease;
}

.icon-compare-panel {
border: 1px solid var(--icon-compare-border-color);
border-radius: 5px;
padding: 6px;
background: var(--icon-compare-panel-bg);
width: 400px;
flex-shrink: 0;
transition: all 0.3s ease;
}

.icon-compare-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid var(--icon-compare-border-color);
font-weight: bold;
text-align: center;
color: var(--icon-compare-text-color);
}

.icon-compare-header-label {
font-size: 11px;
color: var(--icon-compare-text-color);
white-space: nowrap;
}

.icon-compare-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid var(--icon-compare-row-border);
min-height: 36px;
transition: border-color 0.3s ease;
}

.icon-compare-row:last-child {
border-bottom: none;
}

.icon-compare-image {
width: 32px;
height: 32px;
object-fit: contain;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
background-color: var(--icon-compare-icon-bg);
border-radius: 3px;
padding: 2px;
box-sizing: border-box;
}

.icon-compare-bmp-processed {
filter: none;
}

.icon-compare-arrow {
text-align: center;
color: var(--icon-compare-arrow-color);
font-size: 13px;
font-weight: bold;
white-space: nowrap;
}

.icon-compare-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
width: 100%;
}

.icon-compare-name {
color: var(--icon-compare-text-color);
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 220px;
}

.icon-compare-loading {
text-align: center;
padding: 20px;
color: var(--icon-compare-loading-color);
width: 100%;
}

.icon-compare-no-results {
text-align: center;
padding: 40px;
color: var(--icon-compare-loading-color);
width: 100%;
font-size: 14px;
}

.icon-compare-columns {
display: flex;
flex-wrap: wrap;
gap: 12px;
width: 100%;
justify-content: center;
}

.icon-compare-masonry-column {
display: flex;
flex-direction: column;
gap: 12px;
}

/* Стили для оптимизации перерисовки */
.icon-compare-transition-none {
transition: none !important;
}

/* Адаптивность для мобильных устройств */
@media (max-width: 768px) {
.icon-compare-wrapper {
max-width: 100%;
padding: 0 10px;
}

.icon-compare-panel {
width: 100%;
max-width: 400px;
}

.icon-compare-search {
width: 100%;
max-width: 300px;
}

.icon-compare-controls {
flex-wrap: wrap;
gap: 10px;
}

.icon-compare-panel-header {
gap: 4px;
padding: 4px 2px;
}

.icon-compare-header-label {
font-size: 10px;
}

.icon-compare-name {
font-size: 11px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.icon-compare-panel {
width: 100%;
max-width: 100%;
}

.icon-compare-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 3px;
}

.icon-compare-header-label {
font-size: 9px;
}

.icon-compare-arrow {
font-size: 12px;
}

.icon-compare-name {
font-size: 11px;
max-width: 200px;
}
}

/* Для широких экранов - больше колонок */
@media (min-width: 1400px) {
.icon-compare-wrapper {
max-width: 1400px;
}
}

@media (min-width: 1600px) {
.icon-compare-wrapper {
max-width: 1600px;
}
}

/* Глобальный сброс только для нашего контейнера */
.icon-compare-isolated-root * {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: inherit;
font-size: inherit;
}
</style>
</head>
<body class="icon-compare-isolated-root">
<div class="icon-compare-wrapper">
<h1 class="icon-compare-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="icon-compare-search-area">
<input type="text"
id="iconCompareSearch"
class="icon-compare-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="icon-compare-controls">
<div class="icon-compare-stats">
Всего иконок для сравнения: <span id="iconCompareTotalCount">0</span> |
Отображено: <span id="iconCompareShownCount">0</span>
</div>
<select id="iconCompareGroupSelect" class="icon-compare-group-select" style="display: none;">
<option value="">Все группы</option>
</select>
<div class="icon-compare-toggle">
<input type="checkbox" id="iconCompareShowGroups" class="icon-compare-checkbox" checked>
<label for="iconCompareShowGroups">Показывать группы</label>
</div>
</div>

<div class="icon-compare-grid" id="iconCompareContainer">
<div class="icon-compare-loading">Загрузка иконок...</div>
</div>
</div>

<script>
// Изолированные переменные с уникальными префиксами
let iconCompareAllIcons = [];
let iconCompareFilteredIcons = [];
let iconCompareAvailableGroups = [];
let iconCompareShowGroups = true;
let iconCompareThemeObserver = null;
let iconCompareThemeCheckInterval = null;

// Оптимизированная функция для определения темы Hugo
function iconCompareDetectHugoTheme() {
const htmlElement = document.documentElement;
const bodyElement = document.body;

// Быстрая проверка основных способов Hugo
if (htmlElement.getAttribute('data-theme') === 'dark' ||
htmlElement.getAttribute('data-mode') === 'dark' ||
htmlElement.classList.contains('dark') ||
htmlElement.classList.contains('dark-mode') ||
bodyElement.classList.contains('dark') ||
bodyElement.classList.contains('dark-theme') ||
bodyElement.classList.contains('dark-mode')) {
return 'dark';
}

return 'light';
}

// Оптимизированная функция для применения темы
function iconCompareApplyTheme() {
try {
const theme = iconCompareDetectHugoTheme();
const rootElement = document.querySelector('.icon-compare-isolated-root');

if (!rootElement) return;

// Временно отключаем transitions для предотвращения зависания
rootElement.classList.add('icon-compare-transition-none');

if (theme === 'dark') {
rootElement.setAttribute('data-icon-compare-theme', 'dark');
rootElement.classList.add('icon-compare-dark');
} else {
rootElement.removeAttribute('data-icon-compare-theme');
rootElement.classList.remove('icon-compare-dark');
}

// Возвращаем transitions через небольшой таймаут
setTimeout(() => {
rootElement.classList.remove('icon-compare-transition-none');
}, 50);

} catch (error) {
console.warn('Ошибка применения темы:', error);
}
}

// Оптимизированный наблюдатель с ограничением частоты проверки
function iconCompareSetupThemeObserver() {
// Очищаем предыдущие наблюдатели
if (iconCompareThemeObserver) {
iconCompareThemeObserver.disconnect();
}
if (iconCompareThemeCheckInterval) {
clearInterval(iconCompareThemeCheckInterval);
}

let lastTheme = iconCompareDetectHugoTheme();

// Используем легковесный интервал вместо MutationObserver
iconCompareThemeCheckInterval = setInterval(() => {
const currentTheme = iconCompareDetectHugoTheme();
if (currentTheme !== lastTheme) {
lastTheme = currentTheme;
iconCompareApplyTheme();
}
}, 500); // Проверка каждые 500ms вместо мгновенной реакции

// Минимальный MutationObserver только для атрибутов
iconCompareThemeObserver = new MutationObserver((mutations) => {
let shouldUpdate = false;
for (const mutation of mutations) {
if (mutation.type === 'attributes' &&
(mutation.attributeName === 'class' ||
mutation.attributeName === 'data-theme' ||
mutation.attributeName === 'data-mode')) {
shouldUpdate = true;
break;
}
}
if (shouldUpdate) {
// Используем requestAnimationFrame для предотвращения зависания
requestAnimationFrame(() => {
iconCompareApplyTheme();
});
}
});

// Наблюдаем только за основными элементами
try {
iconCompareThemeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'data-theme', 'data-mode'],
attributeOldValue: false // Убираем лишнюю нагрузку
});

iconCompareThemeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class'],
attributeOldValue: false
});
} catch (e) {
console.warn('Не удалось настроить наблюдатель тем:', e);
}
}

// Функция для разбивки больших групп на части
function iconCompareSplitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для расчета примерной высоты группы
function iconCompareCalculateGroupHeight(iconsCount) {
const headerHeight = 36;
const rowHeight = 30;
const padding = 12;
return headerHeight + (iconsCount * rowHeight) + padding;
}

// Функция для создания адаптивной masonry компоновки
function iconCompareCreateMasonryLayout(groupsChunks) {
const container = document.getElementById('iconCompareContainer');
if (!container) return [];

const containerWidth = container.clientWidth;
const columnWidth = 400 + 12;

const maxColumns = Math.floor(1600 / columnWidth);
const availableColumns = Math.min(maxColumns, Math.max(1, Math.floor(containerWidth / columnWidth)));

// Создаем колонки
const columns = Array.from({ length: availableColumns }, () => {
const col = document.createElement('div');
col.className = 'icon-compare-masonry-column';
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(availableColumns).fill(0);

// Распределяем группы по колонкам (алгоритм "наименьшая высота")
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = iconCompareCreateGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

columnHeights[columnIndex] += group.height;
});

return columns;
}

// Функция для отображения иконок с группировкой (masonry компоновка)
function iconCompareRenderWithGroups() {
const container = document.getElementById('iconCompareContainer');
if (!container) return;

container.innerHTML = '';

if (iconCompareFilteredIcons.length === 0) {
container.innerHTML = '<div class="icon-compare-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
iconCompareUpdateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = iconCompareGroupIcons(iconCompareFilteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = iconCompareSplitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: iconCompareCalculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы
if (noGroup.length > 0) {
const noGroupChunks = iconCompareSplitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: iconCompareCalculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте (от высоких к низким для лучшего заполнения)
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем адаптивную masonry компоновку
const columns = iconCompareCreateMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'icon-compare-columns';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
iconCompareUpdateStats();
}

// Функция для создания секции группы
function iconCompareCreateGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'icon-compare-group';

const header = document.createElement('div');
header.className = 'icon-compare-group-title';
header.textContent = groupName;
section.appendChild(header);

const column = iconCompareCreateIconColumn(icons);
section.appendChild(column);

return section;
}

// Функция для создания колонки с иконками
function iconCompareCreateIconColumn(icons) {
const column = document.createElement('div');
column.className = 'icon-compare-panel';

const header = document.createElement('div');
header.className = 'icon-compare-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'icon-compare-header-label';
beforeLabel.textContent = 'ДО';
beforeLabel.style.whiteSpace = 'nowrap';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'icon-compare-arrow';
arrowSpace.textContent = '→';
arrowSpace.style.whiteSpace = 'nowrap';

const afterLabel = document.createElement('div');
afterLabel.className = 'icon-compare-header-label';
afterLabel.textContent = 'ПОСЛЕ';
afterLabel.style.whiteSpace = 'nowrap';

const nameLabel = document.createElement('div');
nameLabel.className = 'icon-compare-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';
nameLabel.style.whiteSpace = 'nowrap';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(iconCompareCreateIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function iconCompareSetupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (iconCompareShowGroups && iconCompareFilteredIcons.length > 0) {
iconCompareRenderWithGroups();
}
}, 250);
});
}

// Остальные функции с уникальными префиксами
function iconCompareProcessBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
console.warn('Ошибка обработки BMP:', error);
resolve({
element: img,
processed: false
});
}
});
}

function iconCompareLoadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await iconCompareProcessBMP(img);
result.element.alt = alt;
resolve(result);
} else {
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
console.warn('Ошибка обработки изображения:', error, src);
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
console.warn('Ошибка загрузки изображения:', src);
const placeholder = new Image();
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function iconCompareGroupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function iconCompareCreateIconRow(icon) {
const row = document.createElement('div');
row.className = 'icon-compare-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
iconCompareLoadImage(icon.before, `${icon.name} (до)`),
iconCompareLoadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'icon-compare-image' + (beforeResult.processed ? ' icon-compare-bmp-processed' : '');
afterImg.className = 'icon-compare-image' + (afterResult.processed ? ' icon-compare-bmp-processed' : '');

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'icon-compare-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'icon-compare-info';

const name = document.createElement('div');
name.className = 'icon-compare-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function iconCompareRenderWithoutGroups() {
const container = document.getElementById('iconCompareContainer');
if (!container) return;

container.innerHTML = '';

if (iconCompareFilteredIcons.length === 0) {
container.innerHTML = '<div class="icon-compare-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
iconCompareUpdateStats();
return;
}

const sortedIcons = [...iconCompareFilteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = iconCompareCreateIconColumn(columnIcons);
container.appendChild(column);
}

iconCompareUpdateStats();
}

function iconCompareFilterIcons(searchTerm, selectedGroup = '') {
let filtered = [...iconCompareAllIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}

iconCompareFilteredIcons = filtered;
iconCompareRenderFilteredIcons();
}

function iconCompareRenderFilteredIcons() {
if (iconCompareShowGroups) {
iconCompareRenderWithGroups();
} else {
iconCompareRenderWithoutGroups();
}
}

function iconCompareUpdateStats() {
const totalCount = document.getElementById('iconCompareTotalCount');
const shownCount = document.getElementById('iconCompareShownCount');

if (totalCount) totalCount.textContent = iconCompareAllIcons.length;
if (shownCount) shownCount.textContent = iconCompareFilteredIcons.length;
}

function iconCompareInitGroupSelect(groups) {
const groupSelect = document.getElementById('iconCompareGroupSelect');
if (!groupSelect) return;

groupSelect.innerHTML = '<option value="">Все группы</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = groups.length > 0 ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('iconCompareSearch').value;
iconCompareFilterIcons(searchTerm, this.value);
});
}

function iconCompareRenderIcons(images, groups) {
iconCompareAllIcons = images;
iconCompareFilteredIcons = [...iconCompareAllIcons];
iconCompareAvailableGroups = groups;

iconCompareInitGroupSelect(groups);
iconCompareRenderFilteredIcons();
}

async function iconCompareLoadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

iconCompareRenderIcons(processedImages, data.availableGroups || []);
} else {
const container = document.getElementById('iconCompareContainer');
if (container) container.innerHTML = '<div class="icon-compare-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
const container = document.getElementById('iconCompareContainer');
if (container) container.innerHTML = '<div class="icon-compare-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
const container = document.getElementById('iconCompareContainer');
if (container) container.innerHTML = '<div class="icon-compare-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
const container = document.getElementById('iconCompareContainer');
if (container) container.innerHTML = '<div class="icon-compare-loading">Ошибка загрузки иконок</div>';
}
}

function iconCompareSetupSearch() {
const searchInput = document.getElementById('iconCompareSearch');
if (!searchInput) return;

let searchTimeout;

searchInput.addEventListener('input', function(e) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('iconCompareGroupSelect').value;
iconCompareFilterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('iconCompareGroupSelect').value;
iconCompareFilterIcons('', selectedGroup);
}
});
}

function iconCompareSetupToggle() {
const toggle = document.getElementById('iconCompareShowGroups');
if (!toggle) return;

toggle.addEventListener('change', function() {
iconCompareShowGroups = this.checked;
iconCompareRenderFilteredIcons();
});
}

// Очистка при разгрузке страницы
function iconCompareCleanup() {
if (iconCompareThemeObserver) {
iconCompareThemeObserver.disconnect();
iconCompareThemeObserver = null;
}
if (iconCompareThemeCheckInterval) {
clearInterval(iconCompareThemeCheckInterval);
iconCompareThemeCheckInterval = null;
}
}

// Основная инициализация
document.addEventListener('DOMContentLoaded', function() {
try {
// Применяем тему при загрузке
iconCompareApplyTheme();

// Настраиваем наблюдатель за изменениями темы
iconCompareSetupThemeObserver();

// Загружаем остальные компоненты
iconCompareLoadIcons();
iconCompareSetupSearch();
iconCompareSetupToggle();
iconCompareSetupResizeHandler();

// Очистка при закрытии страницы
window.addEventListener('beforeunload', iconCompareCleanup);
window.addEventListener('pagehide', iconCompareCleanup);

} catch (error) {
console.error('Ошибка инициализации:', error);
}
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
/* Полностью изолированные стили только для этой страницы */
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}

/* Изолированный контейнер для всей страницы */
.ic-isolated-page {
/* Светлая тема (по умолчанию) */
--ic-bg-color: #ffffff;
--ic-text-color: #333333;
--ic-panel-bg: #fafafa;
--ic-border-color: #e0e0e0;
--ic-header-bg: #f8f9fa;
--ic-header-text: #495057;
--ic-controls-bg: #f0f0f0;
--ic-search-border: #ddd;
--ic-search-focus: #007bff;
--ic-arrow-color: #999;
--ic-loading-color: #666;
--ic-row-border: #f0f0f0;
--ic-icon-bg: #f5f5f5;
--ic-select-bg: #ffffff;
--ic-checkbox-color: #007bff;

font-family: Arial, sans-serif;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
padding: 10px;
font-size: 11px;
min-height: 100vh;
box-sizing: border-box;
transition: background-color 0.3s ease, color 0.3s ease;

/* Изоляция от внешних стилей */
all: initial;
font-family: Arial, sans-serif !important;
}

/* Темная тема - будет активироваться когда Hugo в темном режиме */
.ic-isolated-page[data-ic-theme="dark"] {
--ic-bg-color: #1a1a1a;
--ic-text-color: #e0e0e0;
--ic-panel-bg: #2d2d2d;
--ic-border-color: #404040;
--ic-header-bg: #3d3d3d;
--ic-header-text: #cccccc;
--ic-controls-bg: #333333;
--ic-search-border: #555;
--ic-search-focus: #4dabf7;
--ic-arrow-color: #888;
--ic-loading-color: #999;
--ic-row-border: #3a3a3a;
--ic-icon-bg: #2a2a2a;
--ic-select-bg: #2d2d2d;
--ic-checkbox-color: #4dabf7;
}

/* Восстанавливаем оригинальные стили с уникальными префиксами */
.ic-isolated-page .ic-container {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.ic-isolated-page .ic-body {
font-family: Arial, sans-serif;
background-color: var(--ic-bg-color);
padding: 10px;
font-size: 11px;
min-height: 100vh;
}

.ic-isolated-page .ic-wrapper {
max-width: 1200px;
margin: 0 auto;
}

.ic-isolated-page .ic-title {
text-align: center;
color: var(--ic-text-color);
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.ic-isolated-page .ic-search-area {
margin: 15px 0;
text-align: center;
}

.ic-isolated-page .ic-search {
width: 300px;
padding: 8px 12px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 14px;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-search:focus {
outline: none;
border-color: var(--ic-search-focus);
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.ic-isolated-page .ic-search::placeholder {
color: var(--ic-arrow-color);
}

.ic-isolated-page .ic-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: var(--ic-controls-bg);
border-radius: 4px;
border: 1px solid var(--ic-border-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-stats {
font-size: 12px;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-group-select {
padding: 6px 10px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 12px;
background: var(--ic-select-bg);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-checkbox {
width: 16px;
height: 16px;
accent-color: var(--ic-checkbox-color);
}

.ic-isolated-page .ic-grid {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: flex-start;
justify-content: center;
}

.ic-isolated-page .ic-group {
break-inside: avoid;
}

.ic-isolated-page .ic-group-title {
background: var(--ic-header-bg);
padding: 6px 10px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: var(--ic-header-text);
font-size: 13px;
transition: all 0.3s ease;
}

.ic-isolated-page .ic-panel {
border: 1px solid var(--ic-border-color);
border-radius: 5px;
padding: 6px;
background: var(--ic-panel-bg);
width: 400px;
flex-shrink: 0;
transition: all 0.3s ease;
}

.ic-isolated-page .ic-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid var(--ic-border-color);
font-weight: bold;
text-align: center;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-header-label {
font-size: 11px;
color: var(--ic-text-color);
white-space: nowrap;
}

.ic-isolated-page .ic-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid var(--ic-row-border);
min-height: 36px;
transition: border-color 0.3s ease;
}

.ic-isolated-page .ic-row:last-child {
border-bottom: none;
}

.ic-isolated-page .ic-image {
width: 32px;
height: 32px;
object-fit: contain;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
background-color: var(--ic-icon-bg);
border-radius: 3px;
padding: 2px;
box-sizing: border-box;
}

.ic-isolated-page .ic-bmp-processed {
filter: none;
}

.ic-isolated-page .ic-arrow {
text-align: center;
color: var(--ic-arrow-color);
font-size: 13px;
font-weight: bold;
white-space: nowrap;
}

.ic-isolated-page .ic-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
width: 100%;
}

.ic-isolated-page .ic-name {
color: var(--ic-text-color);
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 220px;
}

.ic-isolated-page .ic-loading {
text-align: center;
padding: 20px;
color: var(--ic-loading-color);
width: 100%;
}

.ic-isolated-page .ic-no-results {
text-align: center;
padding: 40px;
color: var(--ic-loading-color);
width: 100%;
font-size: 14px;
}

.ic-isolated-page .ic-columns {
display: flex;
flex-wrap: wrap;
gap: 12px;
width: 100%;
justify-content: center;
}

.ic-isolated-page .ic-masonry-column {
display: flex;
flex-direction: column;
gap: 12px;
}

/* Адаптивность для мобильных устройств */
@media (max-width: 768px) {
.ic-isolated-page .ic-wrapper {
max-width: 100%;
padding: 0 10px;
}

.ic-isolated-page .ic-panel {
width: 100%;
max-width: 400px;
}

.ic-isolated-page .ic-search {
width: 100%;
max-width: 300px;
}

.ic-isolated-page .ic-controls {
flex-wrap: wrap;
gap: 10px;
}

.ic-isolated-page .ic-panel-header {
gap: 4px;
padding: 4px 2px;
}

.ic-isolated-page .ic-header-label {
font-size: 10px;
}

.ic-isolated-page .ic-name {
font-size: 11px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.ic-isolated-page .ic-panel {
width: 100%;
max-width: 100%;
}

.ic-isolated-page .ic-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 3px;
}

.ic-isolated-page .ic-header-label {
font-size: 9px;
}

.ic-isolated-page .ic-arrow {
font-size: 12px;
}

.ic-isolated-page .ic-name {
font-size: 11px;
max-width: 200px;
}
}

/* Для широких экранов - больше колонок */
@media (min-width: 1400px) {
.ic-isolated-page .ic-wrapper {
max-width: 1400px;
}
}

@media (min-width: 1600px) {
.ic-isolated-page .ic-wrapper {
max-width: 1600px;
}
}
</style>
</head>
<body class="ic-isolated-page">
<div class="ic-container">
<div class="ic-body">
<div class="ic-wrapper">
<h1 class="ic-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="ic-search-area">
<input type="text"
id="icSearch"
class="ic-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="ic-controls">
<div class="ic-stats">
Всего иконок для сравнения: <span id="icTotalCount">0</span> |
Отображено: <span id="icShownCount">0</span>
</div>
<select id="icGroupSelect" class="ic-group-select" style="display: none;">
<option value="">Все группы</option>
</select>
<div class="ic-toggle">
<input type="checkbox" id="icShowGroups" class="ic-checkbox" checked>
<label for="icShowGroups">Показывать группы</label>
</div>
</div>

<div class="ic-grid" id="icContainer">
<div class="ic-loading">Загрузка иконок...</div>
</div>
</div>
</div>
</div>

<script>
// Используем IIFE для полной изоляции
(function() {
'use strict';

let icAllIcons = [];
let icFilteredIcons = [];
let icAvailableGroups = [];
let icShowGroups = true;
let icThemeCheckInterval = null;
let icResizeTimeout = null;
let icSearchTimeout = null;

// Функция для определения темы Hugo - легковесная
function icDetectHugoTheme() {
const html = document.documentElement;
const body = document.body;

// Быстрая проверка основных способов Hugo
if (html.getAttribute('data-theme') === 'dark' ||
html.getAttribute('data-mode') === 'dark' ||
html.classList.contains('dark') ||
html.classList.contains('dark-mode') ||
body.classList.contains('dark') ||
body.classList.contains('dark-theme') ||
body.classList.contains('dark-mode') ||
document.querySelector('.dark-mode, .dark-theme, [data-theme="dark"]')) {
return 'dark';
}

return 'light';
}

// Функция для применения темы - без transitions чтобы не зависать
function icApplyTheme() {
try {
const theme = icDetectHugoTheme();
const page = document.querySelector('.ic-isolated-page');

if (!page) return;

// Быстрое переключение без анимации
if (theme === 'dark') {
page.setAttribute('data-ic-theme', 'dark');
} else {
page.removeAttribute('data-ic-theme');
}
} catch (error) {
// Игнорируем ошибки, чтобы не ломать страницу
}
}

// Простой наблюдатель за темой
function icSetupThemeObserver() {
// Очищаем предыдущий интервал
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
}

let lastTheme = icDetectHugoTheme();

// Проверяем тему раз в секунду - этого достаточно
icThemeCheckInterval = setInterval(() => {
const currentTheme = icDetectHugoTheme();
if (currentTheme !== lastTheme) {
lastTheme = currentTheme;
icApplyTheme();
}
}, 1000);

// Применяем тему сразу
icApplyTheme();
}

// Оригинальные функции с короткими именами
function icSplitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

function icCalculateGroupHeight(iconsCount) {
const headerHeight = 36;
const rowHeight = 30;
const padding = 12;
return headerHeight + (iconsCount * rowHeight) + padding;
}

function icCreateMasonryLayout(groupsChunks) {
const container = document.getElementById('icContainer');
const containerWidth = container.clientWidth;
const columnWidth = 400 + 12;

const maxColumns = Math.floor(1600 / columnWidth);
const availableColumns = Math.min(maxColumns, Math.max(1, Math.floor(containerWidth / columnWidth)));

// Создаем колонки
const columns = Array.from({ length: availableColumns }, () => {
const col = document.createElement('div');
col.className = 'ic-masonry-column';
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(availableColumns).fill(0);

// Распределяем группы по колонкам
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = icCreateGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

columnHeights[columnIndex] += group.height;
});

return columns;
}

function icRenderWithGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = icGroupIcons(icFilteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = icSplitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: icCalculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы
if (noGroup.length > 0) {
const noGroupChunks = icSplitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: icCalculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем адаптивную masonry компоновку
const columns = icCreateMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'ic-columns';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
icUpdateStats();
}

function icCreateGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'ic-group';

const header = document.createElement('div');
header.className = 'ic-group-title';
header.textContent = groupName;
section.appendChild(header);

const column = icCreateIconColumn(icons);
section.appendChild(column);

return section;
}

function icCreateIconColumn(icons) {
const column = document.createElement('div');
column.className = 'ic-panel';

const header = document.createElement('div');
header.className = 'ic-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'ic-header-label';
beforeLabel.textContent = 'ДО';
beforeLabel.style.whiteSpace = 'nowrap';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'ic-arrow';
arrowSpace.textContent = '→';
arrowSpace.style.whiteSpace = 'nowrap';

const afterLabel = document.createElement('div');
afterLabel.className = 'ic-header-label';
afterLabel.textContent = 'ПОСЛЕ';
afterLabel.style.whiteSpace = 'nowrap';

const nameLabel = document.createElement('div');
nameLabel.className = 'ic-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';
nameLabel.style.whiteSpace = 'nowrap';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(icCreateIconRow(icon));
});

return column;
}

function icSetupResizeHandler() {
window.addEventListener('resize', function() {
clearTimeout(icResizeTimeout);
icResizeTimeout = setTimeout(() => {
if (icShowGroups && icFilteredIcons.length > 0) {
icRenderWithGroups();
}
}, 250);
});
}

function icProcessBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
resolve({
element: img,
processed: false
});
}
});
}

function icLoadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await icProcessBMP(img);
result.element.alt = alt;
resolve(result);
} else {
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
const placeholder = new Image();
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function icGroupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function icCreateIconRow(icon) {
const row = document.createElement('div');
row.className = 'ic-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
icLoadImage(icon.before, `${icon.name} (до)`),
icLoadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'ic-image' + (beforeResult.processed ? ' ic-bmp-processed' : '');
afterImg.className = 'ic-image' + (afterResult.processed ? ' ic-bmp-processed' : '');

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'ic-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'ic-info';

const name = document.createElement('div');
name.className = 'ic-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function icRenderWithoutGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

const sortedIcons = [...icFilteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = icCreateIconColumn(columnIcons);
container.appendChild(column);
}

icUpdateStats();
}

function icFilterIcons(searchTerm, selectedGroup = '') {
let filtered = [...icAllIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}

icFilteredIcons = filtered;
icRenderFilteredIcons();
}

function icRenderFilteredIcons() {
if (icShowGroups) {
icRenderWithGroups();
} else {
icRenderWithoutGroups();
}
}

function icUpdateStats() {
document.getElementById('icTotalCount').textContent = icAllIcons.length;
document.getElementById('icShownCount').textContent = icFilteredIcons.length;
}

function icInitGroupSelect(groups) {
const groupSelect = document.getElementById('icGroupSelect');
groupSelect.innerHTML = '<option value="">Все группы</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = groups.length > 0 ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('icSearch').value;
icFilterIcons(searchTerm, this.value);
});
}

function icRenderIcons(images, groups) {
icAllIcons = images;
icFilteredIcons = [...icAllIcons];
icAvailableGroups = groups;

icInitGroupSelect(groups);
icRenderFilteredIcons();
}

function icLoadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

icRenderIcons(processedImages, data.availableGroups || []);
} else {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка загрузки иконок</div>';
}
}

function icSetupSearch() {
const searchInput = document.getElementById('icSearch');

searchInput.addEventListener('input', function(e) {
clearTimeout(icSearchTimeout);
icSearchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons('', selectedGroup);
}
});
}

function icSetupToggle() {
const toggle = document.getElementById('icShowGroups');

toggle.addEventListener('change', function() {
icShowGroups = this.checked;
icRenderFilteredIcons();
});
}

// Очистка при разгрузке
function icCleanup() {
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
icThemeCheckInterval = null;
}
clearTimeout(icResizeTimeout);
clearTimeout(icSearchTimeout);
}

// Инициализация
document.addEventListener('DOMContentLoaded', function() {
// Настраиваем тему
icSetupThemeObserver();

// Загружаем иконки
icLoadIcons();

// Настраиваем остальное
icSetupSearch();
icSetupToggle();
icSetupResizeHandler();

// Очистка
window.addEventListener('beforeunload', icCleanup);
window.addEventListener('pagehide', icCleanup);
});
})();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
/* Полностью изолированные стили только для этой страницы */
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}

/* Изолированный контейнер для всей страницы */
.ic-isolated-page {
/* Светлая тема (по умолчанию) */
--ic-bg-color: #ffffff;
--ic-text-color: #333333;
--ic-panel-bg: #fafafa;
--ic-border-color: #e0e0e0;
--ic-header-bg: #f8f9fa;
--ic-header-text: #495057;
--ic-controls-bg: #f0f0f0;
--ic-search-border: #ddd;
--ic-search-focus: #007bff;
--ic-arrow-color: #999;
--ic-loading-color: #666;
--ic-row-border: #f0f0f0;
--ic-icon-bg: #f5f5f5;
--ic-select-bg: #ffffff;
--ic-checkbox-color: #007bff;

font-family: Arial, sans-serif;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
padding: 10px;
font-size: 11px;
min-height: 100vh;
box-sizing: border-box;
transition: background-color 0.3s ease, color 0.3s ease;

/* Изоляция от внешних стилей */
all: initial;
font-family: Arial, sans-serif !important;
}

/* Темная тема - будет активироваться когда Hugo в темном режиме */
.ic-isolated-page[data-ic-theme="dark"] {
--ic-bg-color: #1a1a1a;
--ic-text-color: #e0e0e0;
--ic-panel-bg: #2d2d2d;
--ic-border-color: #404040;
--ic-header-bg: #3d3d3d;
--ic-header-text: #cccccc;
--ic-controls-bg: #333333;
--ic-search-border: #555;
--ic-search-focus: #4dabf7;
--ic-arrow-color: #888;
--ic-loading-color: #999;
--ic-row-border: #3a3a3a;
--ic-icon-bg: #2a2a2a;
--ic-select-bg: #2d2d2d;
--ic-checkbox-color: #4dabf7;
}

/* Восстанавливаем оригинальные стили с уникальными префиксами */
.ic-isolated-page .ic-container {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.ic-isolated-page .ic-body {
font-family: Arial, sans-serif;
background-color: var(--ic-bg-color);
padding: 10px;
font-size: 11px;
min-height: 100vh;
}

.ic-isolated-page .ic-wrapper {
max-width: 1200px;
margin: 0 auto;
}

.ic-isolated-page .ic-title {
text-align: center;
color: var(--ic-text-color);
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.ic-isolated-page .ic-search-area {
margin: 15px 0;
text-align: center;
}

.ic-isolated-page .ic-search {
width: 300px;
padding: 8px 12px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 14px;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-search:focus {
outline: none;
border-color: var(--ic-search-focus);
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.ic-isolated-page .ic-search::placeholder {
color: var(--ic-arrow-color);
}

.ic-isolated-page .ic-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: var(--ic-controls-bg);
border-radius: 4px;
border: 1px solid var(--ic-border-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-stats {
font-size: 12px;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-group-select {
padding: 6px 10px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 12px;
background: var(--ic-select-bg);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-checkbox {
width: 16px;
height: 16px;
accent-color: var(--ic-checkbox-color);
}

.ic-isolated-page .ic-grid {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: flex-start;
justify-content: center;
}

.ic-isolated-page .ic-group {
break-inside: avoid;
}

.ic-isolated-page .ic-group-title {
background: var(--ic-header-bg);
padding: 6px 10px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: var(--ic-header-text);
font-size: 13px;
transition: all 0.3s ease;
}

.ic-isolated-page .ic-panel {
border: 1px solid var(--ic-border-color);
border-radius: 5px;
padding: 6px;
background: var(--ic-panel-bg);
width: 400px;
flex-shrink: 0;
transition: all 0.3s ease;
}

.ic-isolated-page .ic-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid var(--ic-border-color);
font-weight: bold;
text-align: center;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-header-label {
font-size: 11px;
color: var(--ic-text-color);
white-space: nowrap;
}

.ic-isolated-page .ic-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid var(--ic-row-border);
min-height: 36px;
transition: border-color 0.3s ease;
}

.ic-isolated-page .ic-row:last-child {
border-bottom: none;
}

.ic-isolated-page .ic-image {
width: 32px;
height: 32px;
object-fit: contain;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
background-color: var(--ic-icon-bg);
border-radius: 3px;
padding: 2px;
box-sizing: border-box;
}

.ic-isolated-page .ic-bmp-processed {
filter: none;
}

.ic-isolated-page .ic-arrow {
text-align: center;
color: var(--ic-arrow-color);
font-size: 13px;
font-weight: bold;
white-space: nowrap;
}

.ic-isolated-page .ic-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
width: 100%;
}

.ic-isolated-page .ic-name {
color: var(--ic-text-color);
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 220px;
}

.ic-isolated-page .ic-loading {
text-align: center;
padding: 20px;
color: var(--ic-loading-color);
width: 100%;
}

.ic-isolated-page .ic-no-results {
text-align: center;
padding: 40px;
color: var(--ic-loading-color);
width: 100%;
font-size: 14px;
}

.ic-isolated-page .ic-columns {
display: flex;
flex-wrap: wrap;
gap: 12px;
width: 100%;
justify-content: center;
}

.ic-isolated-page .ic-masonry-column {
display: flex;
flex-direction: column;
gap: 12px;
}

/* Медиа-запросы для адаптивной ширины колонок */
@media (max-width: 831px) {
.ic-isolated-page .ic-panel {
width: 100%;
max-width: 400px;
}

.ic-isolated-page .ic-wrapper {
max-width: 100%;
padding: 0 10px;
}

.ic-isolated-page .ic-search {
width: 100%;
max-width: 300px;
}

.ic-isolated-page .ic-controls {
flex-wrap: wrap;
gap: 10px;
}

.ic-isolated-page .ic-panel-header {
gap: 4px;
padding: 4px 2px;
}

.ic-isolated-page .ic-header-label {
font-size: 10px;
}

.ic-isolated-page .ic-name {
font-size: 11px;
}
}

/* При ширине 832px и выше - две колонки */
@media (min-width: 832px) and (max-width: 1199px) {
.ic-isolated-page .ic-panel {
width: calc(50% - 6px);
max-width: none;
min-width: 300px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.ic-isolated-page .ic-panel {
width: 100%;
max-width: 100%;
}

.ic-isolated-page .ic-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 3px;
}

.ic-isolated-page .ic-header-label {
font-size: 9px;
}

.ic-isolated-page .ic-arrow {
font-size: 12px;
}

.ic-isolated-page .ic-name {
font-size: 11px;
max-width: 200px;
}
}

/* Для широких экранов - больше колонок */
@media (min-width: 1200px) {
.ic-isolated-page .ic-wrapper {
max-width: 1200px;
}
}

@media (min-width: 1400px) {
.ic-isolated-page .ic-wrapper {
max-width: 1400px;
}
}

@media (min-width: 1600px) {
.ic-isolated-page .ic-wrapper {
max-width: 1600px;
}
}
</style>
</head>
<body class="ic-isolated-page">
<div class="ic-container">
<div class="ic-body">
<div class="ic-wrapper">
<h1 class="ic-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="ic-search-area">
<input type="text"
id="icSearch"
class="ic-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="ic-controls">
<div class="ic-stats">
Всего иконок для сравнения: <span id="icTotalCount">0</span> |
Отображено: <span id="icShownCount">0</span>
</div>
<select id="icGroupSelect" class="ic-group-select" style="display: none;">
<option value="">Все группы</option>
</select>
<div class="ic-toggle">
<input type="checkbox" id="icShowGroups" class="ic-checkbox" checked>
<label for="icShowGroups">Показывать группы</label>
</div>
</div>

<div class="ic-grid" id="icContainer">
<div class="ic-loading">Загрузка иконок...</div>
</div>
</div>
</div>
</div>

<script>
(function() {
'use strict';

let icAllIcons = [];
let icFilteredIcons = [];
let icAvailableGroups = [];
let icShowGroups = true;
let icThemeCheckInterval = null;
let icResizeTimeout = null;
let icSearchTimeout = null;

// Функция для определения темы Hugo - легковесная
function icDetectHugoTheme() {
const html = document.documentElement;
const body = document.body;

// Быстрая проверка основных способов Hugo
if (html.getAttribute('data-theme') === 'dark' ||
html.getAttribute('data-mode') === 'dark' ||
html.classList.contains('dark') ||
html.classList.contains('dark-mode') ||
body.classList.contains('dark') ||
body.classList.contains('dark-theme') ||
body.classList.contains('dark-mode') ||
document.querySelector('.dark-mode, .dark-theme, [data-theme="dark"]')) {
return 'dark';
}

return 'light';
}

// Функция для применения темы - без transitions чтобы не зависать
function icApplyTheme() {
try {
const theme = icDetectHugoTheme();
const page = document.querySelector('.ic-isolated-page');

if (!page) return;

// Быстрое переключение без анимации
if (theme === 'dark') {
page.setAttribute('data-ic-theme', 'dark');
} else {
page.removeAttribute('data-ic-theme');
}
} catch (error) {
// Игнорируем ошибки, чтобы не ломать страницу
}
}

// Простой наблюдатель за темой
function icSetupThemeObserver() {
// Очищаем предыдущий интервал
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
}

let lastTheme = icDetectHugoTheme();

// Проверяем тему раз в секунду - этого достаточно
icThemeCheckInterval = setInterval(() => {
const currentTheme = icDetectHugoTheme();
if (currentTheme !== lastTheme) {
lastTheme = currentTheme;
icApplyTheme();
}
}, 1000);

// Применяем тему сразу
icApplyTheme();
}

// Оригинальные функции с короткими именами
function icSplitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

function icCalculateGroupHeight(iconsCount) {
const headerHeight = 36;
const rowHeight = 30;
const padding = 12;
return headerHeight + (iconsCount * rowHeight) + padding;
}

function icCreateMasonryLayout(groupsChunks) {
const container = document.getElementById('icContainer');
if (!container) return [];

const containerWidth = container.clientWidth;

// Определяем количество колонок на основе ширины контейнера
let columnCount;
if (containerWidth >= 1200) {
// Широкие экраны - 3 колонки
columnCount = Math.min(3, groupsChunks.length);
} else if (containerWidth >= 832) {
// Средние экраны (832px и выше) - 2 колонки
columnCount = Math.min(2, groupsChunks.length);
} else {
// Узкие экраны - 1 колонка
columnCount = 1;
}

// Создаем колонки
const columns = Array.from({ length: columnCount }, () => {
const col = document.createElement('div');
col.className = 'ic-masonry-column';
col.style.flex = '1';
col.style.minWidth = '0';
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(columnCount).fill(0);

// Распределяем группы по колонкам (алгоритм "наименьшая высота")
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = icCreateGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

// Учитываем высоту группы
columnHeights[columnIndex] += group.height;
});

return columns;
}

function icRenderWithGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = icGroupIcons(icFilteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = icSplitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: icCalculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы
if (noGroup.length > 0) {
const noGroupChunks = icSplitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: icCalculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте (от высоких к низким для лучшего заполнения)
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем адаптивную masonry компоновку
const columns = icCreateMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'ic-columns';
columnsContainer.style.display = 'flex';
columnsContainer.style.flexWrap = 'wrap';
columnsContainer.style.gap = '12px';
columnsContainer.style.justifyContent = 'center';
columnsContainer.style.width = '100%';

columns.forEach(col => {
if (col.children.length > 0) {
// Рассчитываем ширину колонки в зависимости от их количества
const containerWidth = container.clientWidth;
let columnWidth;

if (containerWidth >= 1200) {
// 3 колонки
columnWidth = `calc(33.333% - 8px)`;
} else if (containerWidth >= 832) {
// 2 колонки
columnWidth = `calc(50% - 6px)`;
} else {
// 1 колонка
columnWidth = '100%';
}

col.style.width = columnWidth;
col.style.maxWidth = '400px';
col.style.minWidth = '300px';
col.style.flexShrink = '0';

columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
icUpdateStats();
}

function icCreateGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'ic-group';

const header = document.createElement('div');
header.className = 'ic-group-title';
header.textContent = groupName;
section.appendChild(header);

const column = icCreateIconColumn(icons);
section.appendChild(column);

return section;
}

function icCreateIconColumn(icons) {
const column = document.createElement('div');
column.className = 'ic-panel';
column.style.width = '100%';
column.style.boxSizing = 'border-box';

const header = document.createElement('div');
header.className = 'ic-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'ic-header-label';
beforeLabel.textContent = 'ДО';
beforeLabel.style.whiteSpace = 'nowrap';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'ic-arrow';
arrowSpace.textContent = '→';
arrowSpace.style.whiteSpace = 'nowrap';

const afterLabel = document.createElement('div');
afterLabel.className = 'ic-header-label';
afterLabel.textContent = 'ПОСЛЕ';
afterLabel.style.whiteSpace = 'nowrap';

const nameLabel = document.createElement('div');
nameLabel.className = 'ic-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';
nameLabel.style.whiteSpace = 'nowrap';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(icCreateIconRow(icon));
});

return column;
}

function icSetupResizeHandler() {
window.addEventListener('resize', function() {
clearTimeout(icResizeTimeout);
icResizeTimeout = setTimeout(() => {
if (icShowGroups && icFilteredIcons.length > 0) {
icRenderWithGroups();
}
}, 250);
});
}

function icProcessBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
resolve({
element: img,
processed: false
});
}
});
}

function icLoadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await icProcessBMP(img);
result.element.alt = alt;
resolve(result);
} else {
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
const placeholder = new Image();
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function icGroupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function icCreateIconRow(icon) {
const row = document.createElement('div');
row.className = 'ic-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
icLoadImage(icon.before, `${icon.name} (до)`),
icLoadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'ic-image' + (beforeResult.processed ? ' ic-bmp-processed' : '');
afterImg.className = 'ic-image' + (afterResult.processed ? ' ic-bmp-processed' : '');

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'ic-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'ic-info';

const name = document.createElement('div');
name.className = 'ic-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function icRenderWithoutGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

const sortedIcons = [...icFilteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

// Создаем контейнер для колонок
const columnsContainer = document.createElement('div');
columnsContainer.className = 'ic-columns';
columnsContainer.style.display = 'flex';
columnsContainer.style.flexWrap = 'wrap';
columnsContainer.style.gap = '12px';
columnsContainer.style.justifyContent = 'center';
columnsContainer.style.width = '100%';

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = icCreateIconColumn(columnIcons);

// Применяем ту же логику ширины что и в режиме с группами
const containerWidth = container.clientWidth;
let columnWidth;

if (containerWidth >= 1200) {
columnWidth = '400px';
} else if (containerWidth >= 832) {
columnWidth = `calc(50% - 6px)`;
} else {
columnWidth = '100%';
}

column.style.width = columnWidth;
column.style.maxWidth = '400px';
column.style.minWidth = '300px';
column.style.flexShrink = '0';

columnsContainer.appendChild(column);
}

container.appendChild(columnsContainer);
icUpdateStats();
}

function icFilterIcons(searchTerm, selectedGroup = '') {
let filtered = [...icAllIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}

icFilteredIcons = filtered;
icRenderFilteredIcons();
}

function icRenderFilteredIcons() {
if (icShowGroups) {
icRenderWithGroups();
} else {
icRenderWithoutGroups();
}
}

function icUpdateStats() {
document.getElementById('icTotalCount').textContent = icAllIcons.length;
document.getElementById('icShownCount').textContent = icFilteredIcons.length;
}

function icInitGroupSelect(groups) {
const groupSelect = document.getElementById('icGroupSelect');
groupSelect.innerHTML = '<option value="">Все группы</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = groups.length > 0 ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('icSearch').value;
icFilterIcons(searchTerm, this.value);
});
}

function icRenderIcons(images, groups) {
icAllIcons = images;
icFilteredIcons = [...icAllIcons];
icAvailableGroups = groups;

icInitGroupSelect(groups);
icRenderFilteredIcons();
}

function icLoadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

icRenderIcons(processedImages, data.availableGroups || []);
} else {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка загрузки иконок</div>';
}
}

function icSetupSearch() {
const searchInput = document.getElementById('icSearch');

searchInput.addEventListener('input', function(e) {
clearTimeout(icSearchTimeout);
icSearchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons('', selectedGroup);
}
});
}

function icSetupToggle() {
const toggle = document.getElementById('icShowGroups');

toggle.addEventListener('change', function() {
icShowGroups = this.checked;
icRenderFilteredIcons();
});
}

// Очистка при разгрузке
function icCleanup() {
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
icThemeCheckInterval = null;
}
clearTimeout(icResizeTimeout);
clearTimeout(icSearchTimeout);
}

// Инициализация
document.addEventListener('DOMContentLoaded', function() {
// Настраиваем тему
icSetupThemeObserver();

// Загружаем иконки
icLoadIcons();

// Настраиваем остальное
icSetupSearch();
icSetupToggle();
icSetupResizeHandler();

// Очистка
window.addEventListener('beforeunload', icCleanup);
window.addEventListener('pagehide', icCleanup);
});
})();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
/* Полностью изолированные стили только для этой страницы */
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}

/* Изолированный контейнер для всей страницы */
.ic-isolated-page {
/* Светлая тема (по умолчанию) */
--ic-bg-color: #ffffff;
--ic-text-color: #333333;
--ic-panel-bg: #fafafa;
--ic-border-color: #e0e0e0;
--ic-header-bg: #f8f9fa;
--ic-header-text: #495057;
--ic-controls-bg: #f0f0f0;
--ic-search-border: #ddd;
--ic-search-focus: #007bff;
--ic-arrow-color: #999;
--ic-loading-color: #666;
--ic-row-border: #f0f0f0;
--ic-icon-bg: #f5f5f5;
--ic-select-bg: #ffffff;
--ic-checkbox-color: #007bff;

font-family: Arial, sans-serif;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
padding: 10px;
font-size: 11px;
min-height: 100vh;
box-sizing: border-box;
transition: background-color 0.3s ease, color 0.3s ease;

/* Изоляция от внешних стилей */
all: initial;
font-family: Arial, sans-serif !important;
}

/* Темная тема - будет активироваться когда Hugo в темном режиме */
.ic-isolated-page[data-ic-theme="dark"] {
--ic-bg-color: #1a1a1a;
--ic-text-color: #e0e0e0;
--ic-panel-bg: #2d2d2d;
--ic-border-color: #404040;
--ic-header-bg: #3d3d3d;
--ic-header-text: #cccccc;
--ic-controls-bg: #333333;
--ic-search-border: #555;
--ic-search-focus: #4dabf7;
--ic-arrow-color: #888;
--ic-loading-color: #999;
--ic-row-border: #3a3a3a;
--ic-icon-bg: #2a2a2a;
--ic-select-bg: #2d2d2d;
--ic-checkbox-color: #4dabf7;
}

/* Восстанавливаем оригинальные стили с уникальными префиксами */
.ic-isolated-page .ic-container {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.ic-isolated-page .ic-body {
font-family: Arial, sans-serif;
background-color: var(--ic-bg-color);
padding: 10px;
font-size: 11px;
min-height: 100vh;
}

.ic-isolated-page .ic-wrapper {
max-width: 1400px;
margin: 0 auto;
}

.ic-isolated-page .ic-title {
text-align: center;
color: var(--ic-text-color);
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.ic-isolated-page .ic-search-area {
margin: 15px 0;
text-align: center;
}

.ic-isolated-page .ic-search {
width: 300px;
padding: 8px 12px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 14px;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-search:focus {
outline: none;
border-color: var(--ic-search-focus);
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.ic-isolated-page .ic-search::placeholder {
color: var(--ic-arrow-color);
}

.ic-isolated-page .ic-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: var(--ic-controls-bg);
border-radius: 4px;
border: 1px solid var(--ic-border-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-stats {
font-size: 12px;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-group-select {
padding: 6px 10px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 12px;
background: var(--ic-select-bg);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-checkbox {
width: 16px;
height: 16px;
accent-color: var(--ic-checkbox-color);
}

.ic-isolated-page .ic-grid {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: flex-start;
justify-content: center;
}

.ic-isolated-page .ic-group {
break-inside: avoid;
width: 100%;
}

.ic-isolated-page .ic-group-title {
background: var(--ic-header-bg);
padding: 6px 10px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: var(--ic-header-text);
font-size: 13px;
transition: all 0.3s ease;
}

.ic-isolated-page .ic-panel {
border: 1px solid var(--ic-border-color);
border-radius: 5px;
padding: 6px;
background: var(--ic-panel-bg);
width: 400px;
flex-shrink: 0;
transition: all 0.3s ease;
}

.ic-isolated-page .ic-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid var(--ic-border-color);
font-weight: bold;
text-align: center;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-header-label {
font-size: 11px;
color: var(--ic-text-color);
white-space: nowrap;
}

.ic-isolated-page .ic-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid var(--ic-row-border);
min-height: 36px;
transition: border-color 0.3s ease;
}

.ic-isolated-page .ic-row:last-child {
border-bottom: none;
}

.ic-isolated-page .ic-image {
width: 32px;
height: 32px;
object-fit: contain;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
background-color: var(--ic-icon-bg);
border-radius: 3px;
padding: 2px;
box-sizing: border-box;
}

.ic-isolated-page .ic-bmp-processed {
filter: none;
}

.ic-isolated-page .ic-arrow {
text-align: center;
color: var(--ic-arrow-color);
font-size: 13px;
font-weight: bold;
white-space: nowrap;
}

.ic-isolated-page .ic-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
width: 100%;
}

.ic-isolated-page .ic-name {
color: var(--ic-text-color);
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 220px;
}

.ic-isolated-page .ic-loading {
text-align: center;
padding: 20px;
color: var(--ic-loading-color);
width: 100%;
}

.ic-isolated-page .ic-no-results {
text-align: center;
padding: 40px;
color: var(--ic-loading-color);
width: 100%;
font-size: 14px;
}

.ic-isolated-page .ic-columns {
display: flex;
flex-wrap: wrap;
gap: 12px;
width: 100%;
justify-content: center;
}

.ic-isolated-page .ic-masonry-column {
display: flex;
flex-direction: column;
gap: 12px;
}

/* Адаптивность для мобильных устройств */
@media (max-width: 768px) {
.ic-isolated-page .ic-wrapper {
max-width: 100%;
padding: 0 10px;
}

.ic-isolated-page .ic-search {
width: 100%;
max-width: 300px;
}

.ic-isolated-page .ic-controls {
flex-wrap: wrap;
gap: 10px;
}

.ic-isolated-page .ic-panel-header {
gap: 4px;
padding: 4px 2px;
}

.ic-isolated-page .ic-header-label {
font-size: 10px;
}

.ic-isolated-page .ic-name {
font-size: 11px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.ic-isolated-page .ic-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 3px;
}

.ic-isolated-page .ic-header-label {
font-size: 9px;
}

.ic-isolated-page .ic-arrow {
font-size: 12px;
}

.ic-isolated-page .ic-name {
font-size: 11px;
max-width: 200px;
}
}

/* Для широких экранов */
@media (min-width: 1400px) {
.ic-isolated-page .ic-wrapper {
max-width: 1400px;
}
}

@media (min-width: 1600px) {
.ic-isolated-page .ic-wrapper {
max-width: 1600px;
}
}
</style>
</head>
<body class="ic-isolated-page">
<div class="ic-container">
<div class="ic-body">
<div class="ic-wrapper">
<h1 class="ic-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="ic-search-area">
<input type="text"
id="icSearch"
class="ic-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="ic-controls">
<div class="ic-stats">
Всего иконок для сравнения: <span id="icTotalCount">0</span> |
Отображено: <span id="icShownCount">0</span>
</div>
<select id="icGroupSelect" class="ic-group-select" style="display: none;">
<option value="">Все группы</option>
<option value="no_group">Прочие</option>
</select>
<div class="ic-toggle">
<input type="checkbox" id="icShowGroups" class="ic-checkbox" checked>
<label for="icShowGroups">Показывать группы</label>
</div>
</div>

<div class="ic-grid" id="icContainer">
<div class="ic-loading">Загрузка иконок...</div>
</div>
</div>
</div>
</div>

<script>
(function() {
'use strict';

let icAllIcons = [];
let icFilteredIcons = [];
let icAvailableGroups = [];
let icShowGroups = true;
let icThemeCheckInterval = null;
let icResizeTimeout = null;
let icSearchTimeout = null;

// Функция для определения темы Hugo - легковесная
function icDetectHugoTheme() {
const html = document.documentElement;
const body = document.body;

// Быстрая проверка основных способов Hugo
if (html.getAttribute('data-theme') === 'dark' ||
html.getAttribute('data-mode') === 'dark' ||
html.classList.contains('dark') ||
html.classList.contains('dark-mode') ||
body.classList.contains('dark') ||
body.classList.contains('dark-theme') ||
body.classList.contains('dark-mode') ||
document.querySelector('.dark-mode, .dark-theme, [data-theme="dark"]')) {
return 'dark';
}

return 'light';
}

// Функция для применения темы - без transitions чтобы не зависать
function icApplyTheme() {
try {
const theme = icDetectHugoTheme();
const page = document.querySelector('.ic-isolated-page');

if (!page) return;

// Быстрое переключение без анимации
if (theme === 'dark') {
page.setAttribute('data-ic-theme', 'dark');
} else {
page.removeAttribute('data-ic-theme');
}
} catch (error) {
// Игнорируем ошибки, чтобы не ломать страницу
}
}

// Простой наблюдатель за темой
function icSetupThemeObserver() {
// Очищаем предыдущий интервал
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
}

let lastTheme = icDetectHugoTheme();

// Проверяем тему раз в секунду - этого достаточно
icThemeCheckInterval = setInterval(() => {
const currentTheme = icDetectHugoTheme();
if (currentTheme !== lastTheme) {
lastTheme = currentTheme;
icApplyTheme();
}
}, 1000);

// Применяем тему сразу
icApplyTheme();
}

// Функция для разбивки больших групп на части
function icSplitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для расчета примерной высоты группы
function icCalculateGroupHeight(iconsCount) {
const headerHeight = 36;
const rowHeight = 30;
const padding = 12;
return headerHeight + (iconsCount * rowHeight) + padding;
}

// Функция для создания адаптивной masonry компоновки
function icCreateMasonryLayout(groupsChunks) {
const container = document.getElementById('icContainer');
if (!container) return [];

const containerWidth = container.clientWidth;
const columnWidth = 400 + 12; // Ширина панели + отступ

// Динамическое количество колонок
let maxColumns;
if (containerWidth >= 1400) {
maxColumns = 4;
} else if (containerWidth >= 1200) {
maxColumns = 3;
} else if (containerWidth >= 832) {
maxColumns = 2;
} else {
maxColumns = 1;
}

const availableColumns = Math.min(maxColumns, Math.max(1, Math.floor(containerWidth / columnWidth)));

console.log(`Container width: ${containerWidth}, Column width: ${columnWidth}, Columns: ${availableColumns}`);

// Создаем колонки
const columns = Array.from({ length: availableColumns }, () => {
const col = document.createElement('div');
col.className = 'ic-masonry-column';
col.style.width = '100%';
col.style.maxWidth = '412px'; // 400px + 12px отступ
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(availableColumns).fill(0);

// Распределяем группы по колонкам (алгоритм "наименьшая высота")
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = icCreateGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

columnHeights[columnIndex] += group.height;
});

return columns;
}

// Функция для отображения иконок с группировкой (masonry компоновка)
function icRenderWithGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = icGroupIcons(icFilteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = icSplitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: icCalculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы как "Прочие"
if (noGroup.length > 0) {
const noGroupChunks = icSplitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: icCalculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте (от высоких к низким для лучшего заполнения)
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем адаптивную masonry компоновку
const columns = icCreateMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'ic-columns';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
icUpdateStats();
}

// Функция для создания секции группы
function icCreateGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'ic-group';

const header = document.createElement('div');
header.className = 'ic-group-title';
header.textContent = groupName;
section.appendChild(header);

const column = icCreateIconColumn(icons);
section.appendChild(column);

return section;
}

// Функция для создания колонки с иконками
function icCreateIconColumn(icons) {
const column = document.createElement('div');
column.className = 'ic-panel';

const header = document.createElement('div');
header.className = 'ic-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'ic-header-label';
beforeLabel.textContent = 'ДО';
beforeLabel.style.whiteSpace = 'nowrap';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'ic-arrow';
arrowSpace.textContent = '→';
arrowSpace.style.whiteSpace = 'nowrap';

const afterLabel = document.createElement('div');
afterLabel.className = 'ic-header-label';
afterLabel.textContent = 'ПОСЛЕ';
afterLabel.style.whiteSpace = 'nowrap';

const nameLabel = document.createElement('div');
nameLabel.className = 'ic-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';
nameLabel.style.whiteSpace = 'nowrap';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(icCreateIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function icSetupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (icShowGroups && icFilteredIcons.length > 0) {
icRenderWithGroups();
}
}, 250);
});
}

// Остальные функции с уникальными префиксами
function icProcessBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
resolve({
element: img,
processed: false
});
}
});
}

function icLoadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await icProcessBMP(img);
result.element.alt = alt;
resolve(result);
} else {
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
const placeholder = new Image();
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function icGroupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function icCreateIconRow(icon) {
const row = document.createElement('div');
row.className = 'ic-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
icLoadImage(icon.before, `${icon.name} (до)`),
icLoadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'ic-image' + (beforeResult.processed ? ' ic-bmp-processed' : '');
afterImg.className = 'ic-image' + (afterResult.processed ? ' ic-bmp-processed' : '');

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'ic-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'ic-info';

const name = document.createElement('div');
name.className = 'ic-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function icRenderWithoutGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

const sortedIcons = [...icFilteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = icCreateIconColumn(columnIcons);
container.appendChild(column);
}

icUpdateStats();
}

function icFilterIcons(searchTerm, selectedGroup = '') {
let filtered = [...icAllIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
if (selectedGroup === 'no_group') {
// Фильтруем иконки без группы
filtered = filtered.filter(icon => !icon.group || icon.group.trim() === '');
} else {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}
}

icFilteredIcons = filtered;
icRenderFilteredIcons();
}

function icRenderFilteredIcons() {
if (icShowGroups) {
icRenderWithGroups();
} else {
icRenderWithoutGroups();
}
}

function icUpdateStats() {
document.getElementById('icTotalCount').textContent = icAllIcons.length;
document.getElementById('icShownCount').textContent = icFilteredIcons.length;
}

function icInitGroupSelect(groups) {
const groupSelect = document.getElementById('icGroupSelect');
groupSelect.innerHTML = '<option value="">Все группы</option>';

// Добавляем опцию "Прочие"
groupSelect.innerHTML += '<option value="no_group">Прочие</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = (groups.length > 0) ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('icSearch').value;
icFilterIcons(searchTerm, this.value);
});
}

function icRenderIcons(images, groups) {
icAllIcons = images;
icFilteredIcons = [...icAllIcons];
icAvailableGroups = groups;

icInitGroupSelect(groups);
icRenderFilteredIcons();
}

async function icLoadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

icRenderIcons(processedImages, data.availableGroups || []);
} else {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка загрузки иконок</div>';
}
}

function icSetupSearch() {
const searchInput = document.getElementById('icSearch');

searchInput.addEventListener('input', function(e) {
clearTimeout(icSearchTimeout);
icSearchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons('', selectedGroup);
}
});
}

function icSetupToggle() {
const toggle = document.getElementById('icShowGroups');

toggle.addEventListener('change', function() {
icShowGroups = this.checked;
icRenderFilteredIcons();
});
}

// Очистка при разгрузке
function icCleanup() {
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
icThemeCheckInterval = null;
}
clearTimeout(icResizeTimeout);
clearTimeout(icSearchTimeout);
}

// Инициализация
document.addEventListener('DOMContentLoaded', function() {
// Настраиваем тему
icSetupThemeObserver();

// Загружаем иконки
icLoadIcons();

// Настраиваем остальное
icSetupSearch();
icSetupToggle();
icSetupResizeHandler();

// Очистка
window.addEventListener('beforeunload', icCleanup);
window.addEventListener('pagehide', icCleanup);
});
})();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
/* Полностью изолированные стили только для этой страницы */
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}

/* Изолированный контейнер для всей страницы */
.ic-isolated-page {
/* Светлая тема (по умолчанию) */
--ic-bg-color: #ffffff;
--ic-text-color: #333333;
--ic-panel-bg: #fafafa;
--ic-border-color: #e0e0e0;
--ic-header-bg: #f8f9fa;
--ic-header-text: #495057;
--ic-controls-bg: #f0f0f0;
--ic-search-border: #ddd;
--ic-search-focus: #007bff;
--ic-arrow-color: #999;
--ic-loading-color: #666;
--ic-row-border: #f0f0f0;
--ic-icon-bg: #f5f5f5;
--ic-select-bg: #ffffff;
--ic-checkbox-color: #007bff;

font-family: Arial, sans-serif;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
padding: 10px;
font-size: 11px;
min-height: 100vh;
box-sizing: border-box;
transition: background-color 0.3s ease, color 0.3s ease;

/* Изоляция от внешних стилей */
all: initial;
font-family: Arial, sans-serif !important;
}

/* Темная тема - будет активироваться когда Hugo в темном режиме */
.ic-isolated-page[data-ic-theme="dark"] {
--ic-bg-color: #1a1a1a;
--ic-text-color: #e0e0e0;
--ic-panel-bg: #2d2d2d;
--ic-border-color: #404040;
--ic-header-bg: #3d3d3d;
--ic-header-text: #cccccc;
--ic-controls-bg: #333333;
--ic-search-border: #555;
--ic-search-focus: #4dabf7;
--ic-arrow-color: #888;
--ic-loading-color: #999;
--ic-row-border: #3a3a3a;
--ic-icon-bg: #2a2a2a;
--ic-select-bg: #2d2d2d;
--ic-checkbox-color: #4dabf7;
}

/* Восстанавливаем оригинальные стили с уникальными префиксами */
.ic-isolated-page .ic-container {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.ic-isolated-page .ic-body {
font-family: Arial, sans-serif;
background-color: var(--ic-bg-color);
padding: 10px;
font-size: 11px;
min-height: 100vh;
}

.ic-isolated-page .ic-wrapper {
max-width: 1400px;
margin: 0 auto;
}

.ic-isolated-page .ic-title {
text-align: center;
color: var(--ic-text-color);
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.ic-isolated-page .ic-search-area {
margin: 15px 0;
text-align: center;
}

.ic-isolated-page .ic-search {
width: 300px;
padding: 8px 12px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 14px;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-search:focus {
outline: none;
border-color: var(--ic-search-focus);
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.ic-isolated-page .ic-search::placeholder {
color: var(--ic-arrow-color);
}

.ic-isolated-page .ic-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: var(--ic-controls-bg);
border-radius: 4px;
border: 1px solid var(--ic-border-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-stats {
font-size: 12px;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-group-select {
padding: 6px 10px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 12px;
background: var(--ic-select-bg);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-checkbox {
width: 16px;
height: 16px;
accent-color: var(--ic-checkbox-color);
}

.ic-isolated-page .ic-grid {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: flex-start;
justify-content: center;
}

.ic-isolated-page .ic-group {
break-inside: avoid;
width: 100%;
}

.ic-isolated-page .ic-group-title {
background: var(--ic-header-bg);
padding: 6px 10px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: var(--ic-header-text);
font-size: 13px;
transition: all 0.3s ease;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.ic-isolated-page .ic-panel {
border: 1px solid var(--ic-border-color);
border-radius: 5px;
padding: 6px;
background: var(--ic-panel-bg);
width: 380px; /* Уменьшено с 400px до 380px */
flex-shrink: 0;
transition: all 0.3s ease;
}

.ic-isolated-page .ic-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid var(--ic-border-color);
font-weight: bold;
text-align: center;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-header-label {
font-size: 11px;
color: var(--ic-text-color);
white-space: nowrap;
}

.ic-isolated-page .ic-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid var(--ic-row-border);
min-height: 36px;
transition: border-color 0.3s ease;
}

.ic-isolated-page .ic-row:last-child {
border-bottom: none;
}

.ic-isolated-page .ic-image {
width: 32px;
height: 32px;
object-fit: contain;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
background-color: var(--ic-icon-bg);
border-radius: 3px;
padding: 2px;
box-sizing: border-box;
}

.ic-isolated-page .ic-bmp-processed {
filter: none;
}

.ic-isolated-page .ic-arrow {
text-align: center;
color: var(--ic-arrow-color);
font-size: 13px;
font-weight: bold;
white-space: nowrap;
}

.ic-isolated-page .ic-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
width: 100%;
}

.ic-isolated-page .ic-name {
color: var(--ic-text-color);
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 200px; /* Уменьшено с 220px до 200px */
}

.ic-isolated-page .ic-loading {
text-align: center;
padding: 20px;
color: var(--ic-loading-color);
width: 100%;
}

.ic-isolated-page .ic-no-results {
text-align: center;
padding: 40px;
color: var(--ic-loading-color);
width: 100%;
font-size: 14px;
}

.ic-isolated-page .ic-columns {
display: flex;
flex-wrap: wrap;
gap: 10px; /* Уменьшено с 12px до 10px */
width: 100%;
justify-content: center;
}

.ic-isolated-page .ic-masonry-column {
display: flex;
flex-direction: column;
gap: 12px;
}

/* Адаптивность для мобильных устройств */
@media (max-width: 768px) {
.ic-isolated-page .ic-wrapper {
max-width: 100%;
padding: 0 10px;
}

.ic-isolated-page .ic-search {
width: 100%;
max-width: 300px;
}

.ic-isolated-page .ic-controls {
flex-wrap: wrap;
gap: 10px;
}

.ic-isolated-page .ic-panel-header {
gap: 4px;
padding: 4px 2px;
}

.ic-isolated-page .ic-header-label {
font-size: 10px;
}

.ic-isolated-page .ic-name {
font-size: 11px;
max-width: 180px;
}

.ic-isolated-page .ic-panel {
width: 100%;
max-width: 380px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.ic-isolated-page .ic-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 3px;
}

.ic-isolated-page .ic-header-label {
font-size: 9px;
}

.ic-isolated-page .ic-arrow {
font-size: 12px;
}

.ic-isolated-page .ic-name {
font-size: 11px;
max-width: 150px;
}

.ic-isolated-page .ic-group-title {
font-size: 12px;
padding: 4px 8px;
}
}

/* Для широких экранов */
@media (min-width: 1400px) {
.ic-isolated-page .ic-wrapper {
max-width: 1400px;
}
}

@media (min-width: 1600px) {
.ic-isolated-page .ic-wrapper {
max-width: 1600px;
}

.ic-isolated-page .ic-panel {
width: 380px;
}
}
</style>
</head>
<body class="ic-isolated-page">
<div class="ic-container">
<div class="ic-body">
<div class="ic-wrapper">
<h1 class="ic-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="ic-search-area">
<input type="text"
id="icSearch"
class="ic-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="ic-controls">
<div class="ic-stats">
Всего иконок для сравнения: <span id="icTotalCount">0</span> |
Отображено: <span id="icShownCount">0</span>
</div>
<select id="icGroupSelect" class="ic-group-select" style="display: none;">
<option value="">Все группы</option>
<option value="no_group">Прочие</option>
</select>
<div class="ic-toggle">
<input type="checkbox" id="icShowGroups" class="ic-checkbox" checked>
<label for="icShowGroups">Показывать группы</label>
</div>
</div>

<div class="ic-grid" id="icContainer">
<div class="ic-loading">Загрузка иконок...</div>
</div>
</div>
</div>
</div>

<script>
(function() {
'use strict';

let icAllIcons = [];
let icFilteredIcons = [];
let icAvailableGroups = [];
let icShowGroups = true;
let icThemeCheckInterval = null;
let icResizeTimeout = null;
let icSearchTimeout = null;

// Функция для определения темы Hugo - легковесная
function icDetectHugoTheme() {
const html = document.documentElement;
const body = document.body;

// Быстрая проверка основных способов Hugo
if (html.getAttribute('data-theme') === 'dark' ||
html.getAttribute('data-mode') === 'dark' ||
html.classList.contains('dark') ||
html.classList.contains('dark-mode') ||
body.classList.contains('dark') ||
body.classList.contains('dark-theme') ||
body.classList.contains('dark-mode') ||
document.querySelector('.dark-mode, .dark-theme, [data-theme="dark"]')) {
return 'dark';
}

return 'light';
}

// Функция для применения темы - без transitions чтобы не зависать
function icApplyTheme() {
try {
const theme = icDetectHugoTheme();
const page = document.querySelector('.ic-isolated-page');

if (!page) return;

// Быстрое переключение без анимации
if (theme === 'dark') {
page.setAttribute('data-ic-theme', 'dark');
} else {
page.removeAttribute('data-ic-theme');
}
} catch (error) {
// Игнорируем ошибки, чтобы не ломать страницу
}
}

// Простой наблюдатель за темой
function icSetupThemeObserver() {
// Очищаем предыдущий интервал
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
}

let lastTheme = icDetectHugoTheme();

// Проверяем тему раз в секунду - этого достаточно
icThemeCheckInterval = setInterval(() => {
const currentTheme = icDetectHugoTheme();
if (currentTheme !== lastTheme) {
lastTheme = currentTheme;
icApplyTheme();
}
}, 1000);

// Применяем тему сразу
icApplyTheme();
}

// Функция для разбивки больших групп на части
function icSplitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для расчета примерной высоты группы
function icCalculateGroupHeight(iconsCount) {
const headerHeight = 36;
const rowHeight = 30;
const padding = 12;
return headerHeight + (iconsCount * rowHeight) + padding;
}

// Функция для создания адаптивной masonry компоновки
function icCreateMasonryLayout(groupsChunks) {
const container = document.getElementById('icContainer');
if (!container) return [];

const containerWidth = container.clientWidth;
const panelWidth = 380; // Ширина панели
const gap = 10; // Отступ между колонками
const totalPanelWidth = panelWidth + gap;

// Динамическое количество колонок
let maxColumns;
if (containerWidth >= 1400) {
maxColumns = 4;
} else if (containerWidth >= 1200) {
maxColumns = 3;
} else if (containerWidth >= 800) { // Уменьшено с 832px до 800px
maxColumns = 2;
} else {
maxColumns = 1;
}

const availableColumns = Math.min(maxColumns, Math.max(1, Math.floor(containerWidth / totalPanelWidth)));

console.log(`Container width: ${containerWidth}, Panel width: ${panelWidth}, Columns: ${availableColumns}`);

// Создаем колонки
const columns = Array.from({ length: availableColumns }, () => {
const col = document.createElement('div');
col.className = 'ic-masonry-column';
col.style.width = `${panelWidth}px`;
col.style.flexShrink = '0';
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(availableColumns).fill(0);

// Распределяем группы по колонкам (алгоритм "наименьшая высота")
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = icCreateGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

columnHeights[columnIndex] += group.height;
});

return columns;
}

// Функция для отображения иконок с группировкой (masonry компоновка)
function icRenderWithGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = icGroupIcons(icFilteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = icSplitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: icCalculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы как "Прочие"
if (noGroup.length > 0) {
const noGroupChunks = icSplitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: icCalculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте (от высоких к низким для лучшего заполнения)
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем адаптивную masonry компоновку
const columns = icCreateMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'ic-columns';
columnsContainer.style.display = 'flex';
columnsContainer.style.flexWrap = 'wrap';
columnsContainer.style.gap = '10px';
columnsContainer.style.justifyContent = 'center';
columnsContainer.style.width = '100%';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
icUpdateStats();
}

// Функция для создания секции группы
function icCreateGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'ic-group';

const header = document.createElement('div');
header.className = 'ic-group-title';
header.textContent = groupName;
header.title = groupName;
section.appendChild(header);

const column = icCreateIconColumn(icons);
section.appendChild(column);

return section;
}

// Функция для создания колонки с иконками
function icCreateIconColumn(icons) {
const column = document.createElement('div');
column.className = 'ic-panel';

const header = document.createElement('div');
header.className = 'ic-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'ic-header-label';
beforeLabel.textContent = 'ДО';
beforeLabel.style.whiteSpace = 'nowrap';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'ic-arrow';
arrowSpace.textContent = '→';
arrowSpace.style.whiteSpace = 'nowrap';

const afterLabel = document.createElement('div');
afterLabel.className = 'ic-header-label';
afterLabel.textContent = 'ПОСЛЕ';
afterLabel.style.whiteSpace = 'nowrap';

const nameLabel = document.createElement('div');
nameLabel.className = 'ic-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';
nameLabel.style.whiteSpace = 'nowrap';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(icCreateIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function icSetupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (icShowGroups && icFilteredIcons.length > 0) {
icRenderWithGroups();
}
}, 250);
});
}

// Остальные функции с уникальными префиксами
function icProcessBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;

ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
resolve({
element: img,
processed: false
});
}
});
}

function icLoadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await icProcessBMP(img);
result.element.alt = alt;
resolve(result);
} else {
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
const placeholder = new Image();
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function icGroupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function icCreateIconRow(icon) {
const row = document.createElement('div');
row.className = 'ic-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
icLoadImage(icon.before, `${icon.name} (до)`),
icLoadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'ic-image' + (beforeResult.processed ? ' ic-bmp-processed' : '');
afterImg.className = 'ic-image' + (afterResult.processed ? ' ic-bmp-processed' : '');

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'ic-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'ic-info';

const name = document.createElement('div');
name.className = 'ic-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function icRenderWithoutGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

const sortedIcons = [...icFilteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

// Создаем контейнер для колонок
const columnsContainer = document.createElement('div');
columnsContainer.className = 'ic-columns';
columnsContainer.style.display = 'flex';
columnsContainer.style.flexWrap = 'wrap';
columnsContainer.style.gap = '10px';
columnsContainer.style.justifyContent = 'center';
columnsContainer.style.width = '100%';

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = icCreateIconColumn(columnIcons);

columnsContainer.appendChild(column);
}

container.appendChild(columnsContainer);
icUpdateStats();
}

function icFilterIcons(searchTerm, selectedGroup = '') {
let filtered = [...icAllIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
if (selectedGroup === 'no_group') {
// Фильтруем иконки без группы
filtered = filtered.filter(icon => !icon.group || icon.group.trim() === '');
} else {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}
}

icFilteredIcons = filtered;
icRenderFilteredIcons();
}

function icRenderFilteredIcons() {
if (icShowGroups) {
icRenderWithGroups();
} else {
icRenderWithoutGroups();
}
}

function icUpdateStats() {
document.getElementById('icTotalCount').textContent = icAllIcons.length;
document.getElementById('icShownCount').textContent = icFilteredIcons.length;
}

function icInitGroupSelect(groups) {
const groupSelect = document.getElementById('icGroupSelect');
groupSelect.innerHTML = '<option value="">Все группы</option>';

// Добавляем опцию "Прочие"
groupSelect.innerHTML += '<option value="no_group">Прочие</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = (groups.length > 0) ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('icSearch').value;
icFilterIcons(searchTerm, this.value);
});
}

function icRenderIcons(images, groups) {
icAllIcons = images;
icFilteredIcons = [...icAllIcons];
icAvailableGroups = groups;

icInitGroupSelect(groups);
icRenderFilteredIcons();
}

async function icLoadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

icRenderIcons(processedImages, data.availableGroups || []);
} else {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
document.getElementById('icContainer').innerHTML = '<div class="ic-loading">Ошибка загрузки иконок</div>';
}
}

function icSetupSearch() {
const searchInput = document.getElementById('icSearch');

searchInput.addEventListener('input', function(e) {
clearTimeout(icSearchTimeout);
icSearchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons('', selectedGroup);
}
});
}

function icSetupToggle() {
const toggle = document.getElementById('icShowGroups');

toggle.addEventListener('change', function() {
icShowGroups = this.checked;
icRenderFilteredIcons();
});
}

// Очистка при разгрузке
function icCleanup() {
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
icThemeCheckInterval = null;
}
clearTimeout(icResizeTimeout);
clearTimeout(icSearchTimeout);
}

// Инициализация
document.addEventListener('DOMContentLoaded', function() {
// Настраиваем тему
icSetupThemeObserver();

// Загружаем иконки
icLoadIcons();

// Настраиваем остальное
icSetupSearch();
icSetupToggle();
icSetupResizeHandler();

// Очистка
window.addEventListener('beforeunload', icCleanup);
window.addEventListener('pagehide', icCleanup);
});
})();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
/* Полный сброс стилей для полной изоляции */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

/* Изолированный контейнер для всей страницы */
.ic-isolated-page {
/* Светлая тема (по умолчанию) */
--ic-bg-color: #ffffff;
--ic-text-color: #333333;
--ic-panel-bg: #fafafa;
--ic-border-color: #e0e0e0;
--ic-header-bg: #f8f9fa;
--ic-header-text: #495057;
--ic-controls-bg: #f0f0f0;
--ic-search-border: #ddd;
--ic-search-focus: #007bff;
--ic-arrow-color: #999;
--ic-loading-color: #666;
--ic-row-border: #f0f0f0;
--ic-icon-bg: #f5f5f5;
--ic-select-bg: #ffffff;
--ic-checkbox-color: #007bff;

/* Базовые стили */
font-family: Arial, sans-serif;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
padding: 10px;
font-size: 11px;
min-height: 100vh;
width: 100%;
overflow-x: hidden;
}

/* Темная тема - ТОЛЬКО для фона и текста, не для иконок */
.ic-isolated-page[data-ic-theme="dark"] {
--ic-bg-color: #1a1a1a;
--ic-text-color: #e0e0e0;
--ic-panel-bg: #2d2d2d;
--ic-border-color: #404040;
--ic-header-bg: #3d3d3d;
--ic-header-text: #cccccc;
--ic-controls-bg: #333333;
--ic-search-border: #555;
--ic-search-focus: #4dabf7;
--ic-arrow-color: #888;
--ic-loading-color: #999;
--ic-row-border: #3a3a3a;
/* Фон для иконок остается светлым для контраста */
--ic-icon-bg: #2a2a2a;
--ic-select-bg: #2d2d2d;
--ic-checkbox-color: #4dabf7;
}

/* Основные стили с уникальными префиксами */
.ic-isolated-page .ic-container {
width: 100%;
margin: 0;
padding: 0;
}

.ic-isolated-page .ic-body {
width: 100%;
min-height: 100vh;
}

.ic-isolated-page .ic-wrapper {
max-width: 1400px;
margin: 0 auto;
width: 100%;
}

.ic-isolated-page .ic-title {
text-align: center;
color: var(--ic-text-color);
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
padding: 0 10px;
}

.ic-isolated-page .ic-search-area {
margin: 15px 0;
text-align: center;
padding: 0 10px;
}

.ic-isolated-page .ic-search {
width: 300px;
max-width: 100%;
padding: 8px 12px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 14px;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-search:focus {
outline: none;
border-color: var(--ic-search-focus);
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.ic-isolated-page .ic-search::placeholder {
color: var(--ic-arrow-color);
}

.ic-isolated-page .ic-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 10px;
padding: 8px;
background: var(--ic-controls-bg);
border-radius: 4px;
border: 1px solid var(--ic-border-color);
transition: all 0.3s ease;
flex-wrap: wrap;
}

.ic-isolated-page .ic-stats {
font-size: 12px;
color: var(--ic-text-color);
white-space: nowrap;
}

.ic-isolated-page .ic-group-select {
padding: 6px 10px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 12px;
background: var(--ic-select-bg);
color: var(--ic-text-color);
transition: all 0.3s ease;
min-width: 150px;
}

.ic-isolated-page .ic-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-checkbox {
width: 16px;
height: 16px;
accent-color: var(--ic-checkbox-color);
}

.ic-isolated-page .ic-grid {
width: 100%;
padding: 0 10px;
}

.ic-isolated-page .ic-group {
margin-bottom: 12px;
width: 100%;
}

.ic-isolated-page .ic-group-title {
background: var(--ic-header-bg);
padding: 8px 12px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: var(--ic-header-text);
font-size: 13px;
transition: all 0.3s ease;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
}

.ic-isolated-page .ic-panel {
border: 1px solid var(--ic-border-color);
border-radius: 5px;
padding: 8px;
background: var(--ic-panel-bg);
width: 100%;
max-width: 380px;
min-width: 300px;
flex-shrink: 0;
transition: all 0.3s ease;
}

.ic-isolated-page .ic-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid var(--ic-border-color);
font-weight: bold;
text-align: center;
color: var(--ic-text-color);
width: 100%;
}

.ic-isolated-page .ic-header-label {
font-size: 11px;
color: var(--ic-text-color);
white-space: nowrap;
}

.ic-isolated-page .ic-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid var(--ic-row-border);
min-height: 36px;
transition: border-color 0.3s ease;
width: 100%;
}

.ic-isolated-page .ic-row:last-child {
border-bottom: none;
}

.ic-isolated-page .ic-image {
width: 32px;
height: 32px;
object-fit: contain;
background-color: var(--ic-icon-bg);
border-radius: 3px;
padding: 0;
display: block;
/* Убираем все фильтры для сохранения цветов */
filter: none !important;
-webkit-filter: none !important;
image-rendering: auto;
}

.ic-isolated-page .ic-bmp-processed {
/* Убираем все фильтры */
filter: none !important;
-webkit-filter: none !important;
}

.ic-isolated-page .ic-arrow {
text-align: center;
color: var(--ic-arrow-color);
font-size: 13px;
font-weight: bold;
white-space: nowrap;
}

.ic-isolated-page .ic-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
width: 100%;
}

.ic-isolated-page .ic-name {
color: var(--ic-text-color);
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 200px;
}

.ic-isolated-page .ic-loading {
text-align: center;
padding: 40px 20px;
color: var(--ic-loading-color);
width: 100%;
}

.ic-isolated-page .ic-no-results {
text-align: center;
padding: 40px;
color: var(--ic-loading-color);
width: 100%;
font-size: 14px;
}

.ic-isolated-page .ic-columns {
display: flex;
flex-wrap: wrap;
gap: 12px;
width: 100%;
justify-content: center;
}

.ic-isolated-page .ic-masonry-column {
display: flex;
flex-direction: column;
gap: 12px;
width: 100%;
max-width: 380px;
}

/* Адаптивность */
@media (max-width: 768px) {
.ic-isolated-page .ic-wrapper {
max-width: 100%;
}

.ic-isolated-page .ic-search {
width: 100%;
max-width: 300px;
}

.ic-isolated-page .ic-controls {
gap: 10px;
margin: 12px 5px;
}

.ic-isolated-page .ic-group-select {
min-width: 120px;
}

.ic-isolated-page .ic-name {
max-width: 180px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.ic-isolated-page .ic-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 4px;
}

.ic-isolated-page .ic-header-label {
font-size: 10px;
}

.ic-isolated-page .ic-arrow {
font-size: 12px;
}

.ic-isolated-page .ic-name {
font-size: 11px;
max-width: 150px;
}

.ic-isolated-page .ic-group-title {
font-size: 12px;
padding: 6px 10px;
}

.ic-isolated-page .ic-masonry-column {
max-width: 100%;
}

.ic-isolated-page .ic-panel {
max-width: 100%;
min-width: 280px;
}
}

/* Для ширины 800px и выше - 2 колонки */
@media (min-width: 800px) {
.ic-isolated-page .ic-masonry-column {
max-width: calc(50% - 6px);
}
}

/* Для ширины 1200px и выше - 3 колонки */
@media (min-width: 1200px) {
.ic-isolated-page .ic-masonry-column {
max-width: calc(33.333% - 8px);
}
}

/* Для ширины 1400px и выше - 4 колонки */
@media (min-width: 1400px) {
.ic-isolated-page .ic-wrapper {
max-width: 1400px;
}

.ic-isolated-page .ic-masonry-column {
max-width: calc(25% - 9px);
}
}
</style>
</head>
<body class="ic-isolated-page">
<div class="ic-container">
<div class="ic-body">
<div class="ic-wrapper">
<h1 class="ic-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="ic-search-area">
<input type="text"
id="icSearch"
class="ic-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="ic-controls">
<div class="ic-stats">
Всего иконок для сравнения: <span id="icTotalCount">0</span> |
Отображено: <span id="icShownCount">0</span>
</div>
<select id="icGroupSelect" class="ic-group-select" style="display: none;">
<option value="">Все группы</option>
<option value="no_group">Прочие</option>
</select>
<div class="ic-toggle">
<input type="checkbox" id="icShowGroups" class="ic-checkbox" checked>
<label for="icShowGroups">Показывать группы</label>
</div>
</div>

<div class="ic-grid" id="icContainer">
<div class="ic-loading">Загрузка иконок...</div>
</div>
</div>
</div>
</div>

<script>
(function() {
'use strict';

let icAllIcons = [];
let icFilteredIcons = [];
let icAvailableGroups = [];
let icShowGroups = true;
let icThemeCheckInterval = null;
let icResizeTimeout = null;
let icSearchTimeout = null;

// Функция для определения темы Hugo - легковесная
function icDetectHugoTheme() {
const html = document.documentElement;
const body = document.body;

// Быстрая проверка основных способов Hugo
if (html.getAttribute('data-theme') === 'dark' ||
html.getAttribute('data-mode') === 'dark' ||
html.classList.contains('dark') ||
html.classList.contains('dark-mode') ||
body.classList.contains('dark') ||
body.classList.contains('dark-theme') ||
body.classList.contains('dark-mode') ||
document.querySelector('.dark-mode, .dark-theme, [data-theme="dark"]')) {
return 'dark';
}

return 'light';
}

// Функция для применения темы - без transitions чтобы не зависать
function icApplyTheme() {
try {
const theme = icDetectHugoTheme();
const page = document.querySelector('.ic-isolated-page');

if (!page) return;

// Быстрое переключение без анимации
if (theme === 'dark') {
page.setAttribute('data-ic-theme', 'dark');
} else {
page.removeAttribute('data-ic-theme');
}
} catch (error) {
// Игнорируем ошибки, чтобы не ломать страницу
}
}

// Простой наблюдатель за темой
function icSetupThemeObserver() {
// Очищаем предыдущий интервал
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
}

let lastTheme = icDetectHugoTheme();

// Проверяем тему раз в секунду - этого достаточно
icThemeCheckInterval = setInterval(() => {
const currentTheme = icDetectHugoTheme();
if (currentTheme !== lastTheme) {
lastTheme = currentTheme;
icApplyTheme();
}
}, 1000);

// Применяем тему сразу
icApplyTheme();
}

// Функция для разбивки больших групп на части
function icSplitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для создания адаптивной masonry компоновки
function icCreateMasonryLayout(groupsChunks) {
const container = document.getElementById('icContainer');
if (!container) return [];

const containerWidth = container.clientWidth;

// Определяем количество колонок на основе ширины
let columnCount;
if (containerWidth >= 1400) {
columnCount = 4;
} else if (containerWidth >= 1200) {
columnCount = 3;
} else if (containerWidth >= 800) {
columnCount = 2;
} else {
columnCount = 1;
}

// Ограничиваем количеством групп
columnCount = Math.min(columnCount, groupsChunks.length);

// Создаем колонки
const columns = Array.from({ length: columnCount }, () => {
const col = document.createElement('div');
col.className = 'ic-masonry-column';
return col;
});

// Распределяем группы по колонкам равномерно
groupsChunks.forEach((group, index) => {
const columnIndex = index % columnCount;
const section = icCreateGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);
});

return columns;
}

// Функция для отображения иконок с группировкой
function icRenderWithGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = icGroupIcons(icFilteredIcons);

// Собираем все группы
const allGroupChunks = [];

// Добавляем группы с иконками
Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = icSplitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName
});
});
});

// Добавляем иконки без группы как "Прочие"
if (noGroup.length > 0) {
const noGroupChunks = icSplitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group'
});
});
}

// Создаем masonry раскладку
const columns = icCreateMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'ic-columns';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
icUpdateStats();
}

// Функция для создания секции группы
function icCreateGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'ic-group';

const header = document.createElement('div');
header.className = 'ic-group-title';
header.textContent = groupName;
header.title = groupName;
section.appendChild(header);

const column = icCreateIconColumn(icons);
section.appendChild(column);

return section;
}

// Функция для создания колонки с иконками
function icCreateIconColumn(icons) {
const column = document.createElement('div');
column.className = 'ic-panel';

const header = document.createElement('div');
header.className = 'ic-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'ic-header-label';
beforeLabel.textContent = 'ДО';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'ic-arrow';
arrowSpace.textContent = '→';

const afterLabel = document.createElement('div');
afterLabel.className = 'ic-header-label';
afterLabel.textContent = 'ПОСЛЕ';

const nameLabel = document.createElement('div');
nameLabel.className = 'ic-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(icCreateIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function icSetupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (icShowGroups && icFilteredIcons.length > 0) {
icRenderWithGroups();
}
}, 250);
});
}

// Упрощенная функция для обработки BMP (только убираем magenta)
function icProcessBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 32;
canvas.height = 32;

// Рисуем изображение с масштабированием до 32x32
ctx.drawImage(img, 0, 0, 32, 32);

// Убираем только magenta (#FF00FF)
const imageData = ctx.getImageData(0, 0, 32, 32);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
// Проверяем на чистый magenta
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0; // Делаем полностью прозрачным
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
// В случае ошибки возвращаем оригинальное изображение
const fallbackImg = new Image();
fallbackImg.onload = () => resolve({
element: fallbackImg,
processed: false
});
fallbackImg.src = img.src;
}
});
}

// Упрощенная функция загрузки изображений
function icLoadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
// Только для BMP файлов делаем простую обработку
if (src.toLowerCase().endsWith('.bmp')) {
const result = await icProcessBMP(img);
result.element.alt = alt;
resolve(result);
} else {
// Для остальных форматов - оригинальное изображение
img.alt = alt;
resolve({ element: img, processed: false });
}
} catch (error) {
// В случае ошибки возвращаем placeholder
img.alt = alt;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
// Заглушка для ошибок загрузки
const placeholder = new Image();
placeholder.width = 32;
placeholder.height = 32;
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
img.width = 32;
img.height = 32;
});
}

function icGroupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function icCreateIconRow(icon) {
const row = document.createElement('div');
row.className = 'ic-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

// Загружаем изображения
Promise.all([
icLoadImage(icon.before, `${icon.name} (до)`),
icLoadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

// Применяем классы
beforeImg.className = 'ic-image';
afterImg.className = 'ic-image';

// Добавляем класс для обработанных BMP
if (beforeResult.processed) {
beforeImg.classList.add('ic-bmp-processed');
}
if (afterResult.processed) {
afterImg.classList.add('ic-bmp-processed');
}

// Гарантируем размер 32x32
beforeImg.width = 32;
beforeImg.height = 32;
afterImg.width = 32;
afterImg.height = 32;

// Добавляем в контейнеры
beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'ic-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'ic-info';

const name = document.createElement('div');
name.className = 'ic-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function icRenderWithoutGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

const sortedIcons = [...icFilteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

// Создаем контейнер для колонок
const columnsContainer = document.createElement('div');
columnsContainer.className = 'ic-columns';

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = icCreateIconColumn(columnIcons);
columnsContainer.appendChild(column);
}

container.appendChild(columnsContainer);
icUpdateStats();
}

function icFilterIcons(searchTerm, selectedGroup = '') {
let filtered = [...icAllIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
if (selectedGroup === 'no_group') {
// Фильтруем иконки без группы
filtered = filtered.filter(icon => !icon.group || icon.group.trim() === '');
} else {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}
}

icFilteredIcons = filtered;
icRenderFilteredIcons();
}

function icRenderFilteredIcons() {
if (icShowGroups) {
icRenderWithGroups();
} else {
icRenderWithoutGroups();
}
}

function icUpdateStats() {
const totalCount = document.getElementById('icTotalCount');
const shownCount = document.getElementById('icShownCount');

if (totalCount) totalCount.textContent = icAllIcons.length;
if (shownCount) shownCount.textContent = icFilteredIcons.length;
}

function icInitGroupSelect(groups) {
const groupSelect = document.getElementById('icGroupSelect');
if (!groupSelect) return;

groupSelect.innerHTML = '<option value="">Все группы</option>';

// Добавляем опцию "Прочие"
groupSelect.innerHTML += '<option value="no_group">Прочие</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = (groups.length > 0) ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('icSearch').value;
icFilterIcons(searchTerm, this.value);
});
}

function icRenderIcons(images, groups) {
icAllIcons = images;
icFilteredIcons = [...icAllIcons];
icAvailableGroups = groups;

icInitGroupSelect(groups);
icRenderFilteredIcons();
}

async function icLoadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

icRenderIcons(processedImages, data.availableGroups || []);
} else {
const container = document.getElementById('icContainer');
if (container) container.innerHTML = '<div class="ic-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
const container = document.getElementById('icContainer');
if (container) container.innerHTML = '<div class="ic-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
const container = document.getElementById('icContainer');
if (container) container.innerHTML = '<div class="ic-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
const container = document.getElementById('icContainer');
if (container) container.innerHTML = '<div class="ic-loading">Ошибка загрузки иконок</div>';
}
}

function icSetupSearch() {
const searchInput = document.getElementById('icSearch');
if (!searchInput) return;

let searchTimeout;

searchInput.addEventListener('input', function(e) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons('', selectedGroup);
}
});
}

function icSetupToggle() {
const toggle = document.getElementById('icShowGroups');
if (!toggle) return;

toggle.addEventListener('change', function() {
icShowGroups = this.checked;
icRenderFilteredIcons();
});
}

// Очистка при разгрузке
function icCleanup() {
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
icThemeCheckInterval = null;
}
clearTimeout(icResizeTimeout);
clearTimeout(icSearchTimeout);
}

// Инициализация
document.addEventListener('DOMContentLoaded', function() {
try {
// Настраиваем тему
icSetupThemeObserver();

// Загружаем иконки
icLoadIcons();

// Настраиваем остальное
icSetupSearch();
icSetupToggle();
icSetupResizeHandler();

// Очистка
window.addEventListener('beforeunload', icCleanup);
window.addEventListener('pagehide', icCleanup);

} catch (error) {
console.error('Ошибка инициализации:', error);
}
});
})();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
/* Полный сброс стилей для полной изоляции */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

/* Изолированный контейнер для всей страницы */
.ic-isolated-page {
/* Светлая тема (по умолчанию) */
--ic-bg-color: #ffffff;
--ic-text-color: #333333;
--ic-panel-bg: #fafafa;
--ic-border-color: #e0e0e0;
--ic-header-bg: #f8f9fa;
--ic-header-text: #495057;
--ic-controls-bg: #f0f0f0;
--ic-search-border: #ddd;
--ic-search-focus: #007bff;
--ic-arrow-color: #999;
--ic-loading-color: #666;
--ic-row-border: #f0f0f0;
--ic-select-bg: #ffffff;
--ic-checkbox-color: #007bff;

/* Иконки НЕ меняются в темной теме */
--ic-icon-bg: #f5f5f5; /* Всегда светло-серый */

/* Базовые стили */
font-family: Arial, sans-serif;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
padding: 10px;
font-size: 11px;
min-height: 100vh;
width: 100%;
overflow-x: hidden;
}

/* Темная тема - ТОЛЬКО для фона и текста, НЕ для иконок */
.ic-isolated-page[data-ic-theme="dark"] {
--ic-bg-color: #1a1a1a;
--ic-text-color: #e0e0e0;
--ic-panel-bg: #2d2d2d;
--ic-border-color: #404040;
--ic-header-bg: #3d3d3d;
--ic-header-text: #cccccc;
--ic-controls-bg: #333333;
--ic-search-border: #555;
--ic-search-focus: #4dabf7;
--ic-arrow-color: #888;
--ic-loading-color: #999;
--ic-row-border: #3a3a3a;
--ic-select-bg: #2d2d2d;
--ic-checkbox-color: #4dabf7;

/* Иконки остаются со светлым фоном для контраста */
--ic-icon-bg: #2a2a2a;
}

/* Основные стили с уникальными префиксами */
.ic-isolated-page .ic-container {
width: 100%;
margin: 0;
padding: 0;
}

.ic-isolated-page .ic-body {
width: 100%;
min-height: 100vh;
}

.ic-isolated-page .ic-wrapper {
max-width: 1400px;
margin: 0 auto;
width: 100%;
padding: 0 10px;
}

.ic-isolated-page .ic-title {
text-align: center;
color: var(--ic-text-color);
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.ic-isolated-page .ic-search-area {
margin: 15px 0;
text-align: center;
}

.ic-isolated-page .ic-search {
width: 300px;
max-width: 100%;
padding: 8px 12px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 14px;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-search:focus {
outline: none;
border-color: var(--ic-search-focus);
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.ic-isolated-page .ic-search::placeholder {
color: var(--ic-arrow-color);
}

.ic-isolated-page .ic-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: var(--ic-controls-bg);
border-radius: 4px;
border: 1px solid var(--ic-border-color);
transition: all 0.3s ease;
flex-wrap: wrap;
}

.ic-isolated-page .ic-stats {
font-size: 12px;
color: var(--ic-text-color);
white-space: nowrap;
}

.ic-isolated-page .ic-group-select {
padding: 6px 10px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 12px;
background: var(--ic-select-bg);
color: var(--ic-text-color);
transition: all 0.3s ease;
min-width: 150px;
}

.ic-isolated-page .ic-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-checkbox {
width: 16px;
height: 16px;
accent-color: var(--ic-checkbox-color);
}

.ic-isolated-page .ic-grid {
width: 100%;
}

.ic-isolated-page .ic-group-container {
width: 100%;
margin-bottom: 20px;
}

.ic-isolated-page .ic-group-title {
background: var(--ic-header-bg);
padding: 8px 12px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: var(--ic-header-text);
font-size: 13px;
transition: all 0.3s ease;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
}

.ic-isolated-page .ic-panel {
border: 1px solid var(--ic-border-color);
border-radius: 5px;
padding: 8px;
background: var(--ic-panel-bg);
width: 400px;
flex-shrink: 0;
transition: all 0.3s ease;
margin-bottom: 12px;
}

.ic-isolated-page .ic-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid var(--ic-border-color);
font-weight: bold;
text-align: center;
color: var(--ic-text-color);
width: 100%;
}

.ic-isolated-page .ic-header-label {
font-size: 11px;
color: var(--ic-text-color);
white-space: nowrap;
}

.ic-isolated-page .ic-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid var(--ic-row-border);
min-height: 36px;
transition: border-color 0.3s ease;
width: 100%;
}

.ic-isolated-page .ic-row:last-child {
border-bottom: none;
}

.ic-isolated-page .ic-image {
width: 32px;
height: 32px;
object-fit: contain;
background-color: var(--ic-icon-bg);
border-radius: 3px;
padding: 0;
display: block;
/* Иконки защищены от любых фильтров */
filter: none !important;
-webkit-filter: none !important;
image-rendering: auto;
}

.ic-isolated-page .ic-bmp-processed {
/* Только для BMP */
filter: none !important;
-webkit-filter: none !important;
}

.ic-isolated-page .ic-arrow {
text-align: center;
color: var(--ic-arrow-color);
font-size: 13px;
font-weight: bold;
white-space: nowrap;
}

.ic-isolated-page .ic-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
width: 100%;
}

.ic-isolated-page .ic-name {
color: var(--ic-text-color);
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 220px;
}

.ic-isolated-page .ic-loading {
text-align: center;
padding: 40px 20px;
color: var(--ic-loading-color);
width: 100%;
}

.ic-isolated-page .ic-no-results {
text-align: center;
padding: 40px;
color: var(--ic-loading-color);
width: 100%;
font-size: 14px;
}

.ic-isolated-page .ic-columns {
display: flex;
flex-wrap: wrap;
gap: 12px;
width: 100%;
justify-content: center;
}

.ic-isolated-page .ic-column-panels {
display: flex;
flex-direction: column;
gap: 12px;
width: 400px;
flex-shrink: 0;
}

/* Адаптивность */
@media (max-width: 768px) {
.ic-isolated-page .ic-wrapper {
max-width: 100%;
padding: 0 10px;
}

.ic-isolated-page .ic-search {
width: 100%;
max-width: 300px;
}

.ic-isolated-page .ic-controls {
gap: 10px;
}

.ic-isolated-page .ic-group-select {
min-width: 120px;
}

.ic-isolated-page .ic-name {
max-width: 180px;
}

.ic-isolated-page .ic-panel {
width: 100%;
max-width: 400px;
}

.ic-isolated-page .ic-column-panels {
width: 100%;
max-width: 400px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.ic-isolated-page .ic-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 4px;
}

.ic-isolated-page .ic-header-label {
font-size: 10px;
}

.ic-isolated-page .ic-arrow {
font-size: 12px;
}

.ic-isolated-page .ic-name {
font-size: 11px;
max-width: 150px;
}

.ic-isolated-page .ic-group-title {
font-size: 12px;
padding: 6px 10px;
}
}

/* Для ширины 800px и выше - 2 колонки */
@media (min-width: 800px) {
.ic-isolated-page .ic-column-panels {
width: calc(50% - 6px);
max-width: 400px;
}
}

/* Для ширины 1200px и выше - 3 колонки */
@media (min-width: 1200px) {
.ic-isolated-page .ic-wrapper {
max-width: 1200px;
}

.ic-isolated-page .ic-column-panels {
width: calc(33.333% - 8px);
max-width: 400px;
}
}

/* Для ширины 1400px и выше - 4 колонки */
@media (min-width: 1400px) {
.ic-isolated-page .ic-wrapper {
max-width: 1400px;
}

.ic-isolated-page .ic-column-panels {
width: calc(25% - 9px);
max-width: 400px;
}
}
</style>
</head>
<body class="ic-isolated-page">
<div class="ic-container">
<div class="ic-body">
<div class="ic-wrapper">
<h1 class="ic-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="ic-search-area">
<input type="text"
id="icSearch"
class="ic-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="ic-controls">
<div class="ic-stats">
Всего иконок для сравнения: <span id="icTotalCount">0</span> |
Отображено: <span id="icShownCount">0</span>
</div>
<select id="icGroupSelect" class="ic-group-select" style="display: none;">
<option value="">Все группы</option>
<option value="no_group">Прочие</option>
</select>
<div class="ic-toggle">
<input type="checkbox" id="icShowGroups" class="ic-checkbox" checked>
<label for="icShowGroups">Показывать группы</label>
</div>
</div>

<div class="ic-grid" id="icContainer">
<div class="ic-loading">Загрузка иконок...</div>
</div>
</div>
</div>
</div>

<script>
(function() {
'use strict';

let icAllIcons = [];
let icFilteredIcons = [];
let icAvailableGroups = [];
let icShowGroups = true;
let icThemeCheckInterval = null;
let icResizeTimeout = null;
let icSearchTimeout = null;

// Функция для определения темы Hugo
function icDetectHugoTheme() {
const html = document.documentElement;
const body = document.body;

// Быстрая проверка основных способов Hugo
if (html.getAttribute('data-theme') === 'dark' ||
html.getAttribute('data-mode') === 'dark' ||
html.classList.contains('dark') ||
html.classList.contains('dark-mode') ||
body.classList.contains('dark') ||
body.classList.contains('dark-theme') ||
body.classList.contains('dark-mode') ||
document.querySelector('.dark-mode, .dark-theme, [data-theme="dark"]')) {
return 'dark';
}

return 'light';
}

// Функция для применения темы
function icApplyTheme() {
try {
const theme = icDetectHugoTheme();
const page = document.querySelector('.ic-isolated-page');

if (!page) return;

// Быстрое переключение
if (theme === 'dark') {
page.setAttribute('data-ic-theme', 'dark');
} else {
page.removeAttribute('data-ic-theme');
}
} catch (error) {
console.warn('Ошибка применения темы:', error);
}
}

// Простой наблюдатель за темой
function icSetupThemeObserver() {
// Очищаем предыдущий интервал
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
}

let lastTheme = icDetectHugoTheme();

// Проверяем тему раз в секунду
icThemeCheckInterval = setInterval(() => {
const currentTheme = icDetectHugoTheme();
if (currentTheme !== lastTheme) {
lastTheme = currentTheme;
icApplyTheme();
}
}, 1000);

// Применяем тему сразу
icApplyTheme();
}

// Функция для разбивки больших групп на части
function icSplitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для создания адаптивной masonry компоновки - УПРОЩЕННАЯ
function icCreateMasonryLayout(groupsChunks) {
const container = document.getElementById('icContainer');
if (!container) return [];

const containerWidth = container.clientWidth;

// Определяем количество колонок на основе ширины
let columnCount;
if (containerWidth >= 1400) {
columnCount = 4;
} else if (containerWidth >= 1200) {
columnCount = 3;
} else if (containerWidth >= 800) {
columnCount = 2;
} else {
columnCount = 1;
}

// Создаем колонки
const columns = Array.from({ length: columnCount }, () => {
const col = document.createElement('div');
col.className = 'ic-column-panels';
return col;
});

// Распределяем группы по колонкам равномерно
groupsChunks.forEach((group, index) => {
const columnIndex = index % columnCount;
const panel = icCreateGroupPanel(group.name, group.icons);
columns[columnIndex].appendChild(panel);
});

return columns;
}

// Функция для отображения иконок с группировкой - НОВАЯ
function icRenderWithGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = icGroupIcons(icFilteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

// Добавляем группы с иконками
Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = icSplitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName
});
});
});

// Добавляем иконки без группы как "Прочие"
if (noGroup.length > 0) {
const noGroupChunks = icSplitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group'
});
});
}

// Создаем masonry раскладку
const columns = icCreateMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'ic-columns';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
icUpdateStats();
}

// Функция для создания панели с группой - НОВАЯ
function icCreateGroupPanel(groupName, icons) {
const container = document.createElement('div');
container.className = 'ic-group-container';

const header = document.createElement('div');
header.className = 'ic-group-title';
header.textContent = groupName;
header.title = groupName;
container.appendChild(header);

const panel = icCreateIconColumn(icons);
container.appendChild(panel);

return container;
}

// Функция для создания колонки с иконками
function icCreateIconColumn(icons) {
const column = document.createElement('div');
column.className = 'ic-panel';

const header = document.createElement('div');
header.className = 'ic-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'ic-header-label';
beforeLabel.textContent = 'ДО';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'ic-arrow';
arrowSpace.textContent = '→';

const afterLabel = document.createElement('div');
afterLabel.className = 'ic-header-label';
afterLabel.textContent = 'ПОСЛЕ';

const nameLabel = document.createElement('div');
nameLabel.className = 'ic-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(icCreateIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function icSetupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (icShowGroups && icFilteredIcons.length > 0) {
icRenderWithGroups();
}
}, 250);
});
}

// Упрощенная функция для обработки BMP (только убираем magenta)
function icProcessBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth || 32;
canvas.height = img.naturalHeight || 32;

// Рисуем оригинальное изображение
ctx.drawImage(img, 0, 0);

// Убираем только magenta (#FF00FF)
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
// Проверяем на чистый magenta
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0; // Делаем полностью прозрачным
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
// В случае ошибки возвращаем оригинальное изображение
resolve({
element: img,
processed: false
});
}
});
}

// Функция загрузки изображений
function icLoadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
// Только для BMP файлов делаем обработку magenta
if (src.toLowerCase().endsWith('.bmp')) {
const result = await icProcessBMP(img);
result.element.alt = alt;
result.element.width = 32;
result.element.height = 32;
resolve(result);
} else {
// Для остальных форматов - оригинальное изображение
img.alt = alt;
img.width = 32;
img.height = 32;
resolve({ element: img, processed: false });
}
} catch (error) {
// В случае ошибки возвращаем оригинальное изображение
img.alt = alt;
img.width = 32;
img.height = 32;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
// Заглушка для ошибок загрузки
const placeholder = new Image();
placeholder.width = 32;
placeholder.height = 32;
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function icGroupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function icCreateIconRow(icon) {
const row = document.createElement('div');
row.className = 'ic-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

// Загружаем изображения
Promise.all([
icLoadImage(icon.before, `${icon.name} (до)`),
icLoadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

// Применяем классы
beforeImg.className = 'ic-image';
afterImg.className = 'ic-image';

// Добавляем класс для обработанных BMP
if (beforeResult.processed) {
beforeImg.classList.add('ic-bmp-processed');
}
if (afterResult.processed) {
afterImg.classList.add('ic-bmp-processed');
}

// Гарантируем размер 32x32
beforeImg.width = 32;
beforeImg.height = 32;
beforeImg.style.width = '32px';
beforeImg.style.height = '32px';

afterImg.width = 32;
afterImg.height = 32;
afterImg.style.width = '32px';
afterImg.style.height = '32px';

// Добавляем в контейнеры
beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'ic-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'ic-info';

const name = document.createElement('div');
name.className = 'ic-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function icRenderWithoutGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

const sortedIcons = [...icFilteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

// Создаем контейнер для колонок
const columnsContainer = document.createElement('div');
columnsContainer.className = 'ic-columns';

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = icCreateIconColumn(columnIcons);
columnsContainer.appendChild(column);
}

container.appendChild(columnsContainer);
icUpdateStats();
}

function icFilterIcons(searchTerm, selectedGroup = '') {
let filtered = [...icAllIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
if (selectedGroup === 'no_group') {
// Фильтруем иконки без группы
filtered = filtered.filter(icon => !icon.group || icon.group.trim() === '');
} else {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}
}

icFilteredIcons = filtered;
icRenderFilteredIcons();
}

function icRenderFilteredIcons() {
if (icShowGroups) {
icRenderWithGroups();
} else {
icRenderWithoutGroups();
}
}

function icUpdateStats() {
const totalCount = document.getElementById('icTotalCount');
const shownCount = document.getElementById('icShownCount');

if (totalCount) totalCount.textContent = icAllIcons.length;
if (shownCount) shownCount.textContent = icFilteredIcons.length;
}

function icInitGroupSelect(groups) {
const groupSelect = document.getElementById('icGroupSelect');
if (!groupSelect) return;

groupSelect.innerHTML = '<option value="">Все группы</option>';

// Добавляем опцию "Прочие"
groupSelect.innerHTML += '<option value="no_group">Прочие</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = (groups.length > 0) ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('icSearch').value;
icFilterIcons(searchTerm, this.value);
});
}

function icRenderIcons(images, groups) {
icAllIcons = images;
icFilteredIcons = [...icAllIcons];
icAvailableGroups = groups;

icInitGroupSelect(groups);
icRenderFilteredIcons();
}

async function icLoadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

icRenderIcons(processedImages, data.availableGroups || []);
} else {
const container = document.getElementById('icContainer');
if (container) container.innerHTML = '<div class="ic-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
const container = document.getElementById('icContainer');
if (container) container.innerHTML = '<div class="ic-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
const container = document.getElementById('icContainer');
if (container) container.innerHTML = '<div class="ic-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
const container = document.getElementById('icContainer');
if (container) container.innerHTML = '<div class="ic-loading">Ошибка загрузки иконок</div>';
}
}

function icSetupSearch() {
const searchInput = document.getElementById('icSearch');
if (!searchInput) return;

let searchTimeout;

searchInput.addEventListener('input', function(e) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons('', selectedGroup);
}
});
}

function icSetupToggle() {
const toggle = document.getElementById('icShowGroups');
if (!toggle) return;

toggle.addEventListener('change', function() {
icShowGroups = this.checked;
icRenderFilteredIcons();
});
}

// Очистка при разгрузке
function icCleanup() {
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
icThemeCheckInterval = null;
}
clearTimeout(icResizeTimeout);
clearTimeout(icSearchTimeout);
}

// Инициализация
document.addEventListener('DOMContentLoaded', function() {
try {
// Настраиваем тему
icSetupThemeObserver();

// Загружаем иконки
icLoadIcons();

// Настраиваем остальное
icSetupSearch();
icSetupToggle();
icSetupResizeHandler();

// Очистка
window.addEventListener('beforeunload', icCleanup);
window.addEventListener('pagehide', icCleanup);

} catch (error) {
console.error('Ошибка инициализации:', error);
}
});
})();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сравнение иконок ИСИХОГИ</title>
<style>
/* Полный сброс стилей */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

/* Изолированный контейнер для всей страницы */
.ic-isolated-page {
/* Светлая тема (по умолчанию) */
--ic-bg-color: #ffffff;
--ic-text-color: #333333;
--ic-panel-bg: #fafafa;
--ic-border-color: #e0e0e0;
--ic-header-bg: #f8f9fa;
--ic-header-text: #495057;
--ic-controls-bg: #f0f0f0;
--ic-search-border: #ddd;
--ic-search-focus: #007bff;
--ic-arrow-color: #999;
--ic-loading-color: #666;
--ic-row-border: #f0f0f0;
--ic-select-bg: #ffffff;
--ic-checkbox-color: #007bff;

/* Иконки НЕ меняются в темной теме */
--ic-icon-bg: #f5f5f5;

font-family: Arial, sans-serif;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
padding: 10px;
font-size: 11px;
min-height: 100vh;
width: 100%;
overflow-x: hidden;
}

/* Темная тема - ТОЛЬКО для фона и текста */
.ic-isolated-page[data-ic-theme="dark"] {
--ic-bg-color: #1a1a1a;
--ic-text-color: #e0e0e0;
--ic-panel-bg: #2d2d2d;
--ic-border-color: #404040;
--ic-header-bg: #3d3d3d;
--ic-header-text: #cccccc;
--ic-controls-bg: #333333;
--ic-search-border: #555;
--ic-search-focus: #4dabf7;
--ic-arrow-color: #888;
--ic-loading-color: #999;
--ic-row-border: #3a3a3a;
--ic-select-bg: #2d2d2d;
--ic-checkbox-color: #4dabf7;

/* Иконки остаются со светлым фоном */
--ic-icon-bg: #2a2a2a;
}

/* Основные стили */
.ic-isolated-page .ic-container {
width: 100%;
}

.ic-isolated-page .ic-body {
width: 100%;
min-height: 100vh;
}

.ic-isolated-page .ic-wrapper {
max-width: 1400px;
margin: 0 auto;
width: 100%;
padding: 0 10px;
}

.ic-isolated-page .ic-title {
text-align: center;
color: var(--ic-text-color);
font-size: 16px;
margin-bottom: 15px;
font-weight: bold;
}

.ic-isolated-page .ic-search-area {
margin: 15px 0;
text-align: center;
}

.ic-isolated-page .ic-search {
width: 300px;
max-width: 100%;
padding: 8px 12px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 14px;
background-color: var(--ic-bg-color);
color: var(--ic-text-color);
transition: all 0.3s ease;
}

.ic-isolated-page .ic-search:focus {
outline: none;
border-color: var(--ic-search-focus);
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.ic-isolated-page .ic-search::placeholder {
color: var(--ic-arrow-color);
}

.ic-isolated-page .ic-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin: 12px 0;
padding: 8px;
background: var(--ic-controls-bg);
border-radius: 4px;
border: 1px solid var(--ic-border-color);
transition: all 0.3s ease;
flex-wrap: wrap;
}

.ic-isolated-page .ic-stats {
font-size: 12px;
color: var(--ic-text-color);
white-space: nowrap;
}

.ic-isolated-page .ic-group-select {
padding: 6px 10px;
border: 1px solid var(--ic-search-border);
border-radius: 4px;
font-size: 12px;
background: var(--ic-select-bg);
color: var(--ic-text-color);
transition: all 0.3s ease;
min-width: 150px;
}

.ic-isolated-page .ic-toggle {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
order: 2;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-checkbox {
width: 16px;
height: 16px;
accent-color: var(--ic-checkbox-color);
}

.ic-isolated-page .ic-grid {
width: 100%;
}

/* Стили для групп с masonry раскладкой */
.ic-isolated-page .ic-group-section {
width: 100%;
margin-bottom: 15px;
}

.ic-isolated-page .ic-group-title {
background: var(--ic-header-bg);
padding: 8px 12px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: bold;
color: var(--ic-header-text);
font-size: 13px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 400px; /* Фиксированная ширина как у панелей */
max-width: 100%;
flex-shrink: 0;
}

.ic-isolated-page .ic-group-content {
display: flex;
flex-direction: column;
width: 400px; /* Фиксированная ширина */
max-width: 100%;
}

.ic-isolated-page .ic-panel {
border: 1px solid var(--ic-border-color);
border-radius: 5px;
padding: 8px;
background: var(--ic-panel-bg);
width: 400px;
max-width: 100%;
flex-shrink: 0;
}

.ic-isolated-page .ic-panel-header {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
margin-bottom: 4px;
border-bottom: 1px solid var(--ic-border-color);
font-weight: bold;
text-align: center;
color: var(--ic-text-color);
}

.ic-isolated-page .ic-header-label {
font-size: 11px;
color: var(--ic-text-color);
white-space: nowrap;
}

.ic-isolated-page .ic-row {
display: grid;
grid-template-columns: 32px 18px 32px 1fr;
gap: 6px;
align-items: center;
padding: 4px 2px;
border-bottom: 1px solid var(--ic-row-border);
min-height: 36px;
}

.ic-isolated-page .ic-row:last-child {
border-bottom: none;
}

.ic-isolated-page .ic-image {
width: 32px;
height: 32px;
object-fit: contain;
background-color: var(--ic-icon-bg);
border-radius: 3px;
padding: 0;
display: block;
filter: none !important;
-webkit-filter: none !important;
}

.ic-isolated-page .ic-bmp-processed {
filter: none !important;
-webkit-filter: none !important;
}

.ic-isolated-page .ic-arrow {
text-align: center;
color: var(--ic-arrow-color);
font-size: 13px;
font-weight: bold;
white-space: nowrap;
}

.ic-isolated-page .ic-info {
padding-left: 6px;
padding-right: 3px;
min-width: 0;
}

.ic-isolated-page .ic-name {
color: var(--ic-text-color);
line-height: 1.3;
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
text-align: left;
font-size: 12px;
max-width: 220px;
}

.ic-isolated-page .ic-loading {
text-align: center;
padding: 40px 20px;
color: var(--ic-loading-color);
width: 100%;
}

.ic-isolated-page .ic-no-results {
text-align: center;
padding: 40px;
color: var(--ic-loading-color);
width: 100%;
font-size: 14px;
}

/* Masonry колонки */
.ic-isolated-page .ic-masonry-columns {
display: flex;
flex-wrap: wrap;
gap: 15px;
width: 100%;
justify-content: center;
}

.ic-isolated-page .ic-masonry-column {
display: flex;
flex-direction: column;
gap: 15px;
width: 400px; /* Фиксированная ширина колонки */
max-width: 100%;
}

/* Обычные колонки (без групп) */
.ic-isolated-page .ic-columns {
display: flex;
flex-wrap: wrap;
gap: 15px;
width: 100%;
justify-content: center;
}

/* Адаптивность */
@media (max-width: 768px) {
.ic-isolated-page .ic-wrapper {
max-width: 100%;
padding: 0 10px;
}

.ic-isolated-page .ic-search {
width: 100%;
max-width: 300px;
}

.ic-isolated-page .ic-controls {
gap: 10px;
}

.ic-isolated-page .ic-group-select {
min-width: 120px;
}

.ic-isolated-page .ic-name {
max-width: 180px;
}

.ic-isolated-page .ic-group-title,
.ic-isolated-page .ic-group-content,
.ic-isolated-page .ic-panel,
.ic-isolated-page .ic-masonry-column {
width: 100%;
max-width: 400px;
}
}

/* Для очень маленьких экранов */
@media (max-width: 480px) {
.ic-isolated-page .ic-panel-header {
grid-template-columns: 30px 16px 30px 1fr;
gap: 4px;
}

.ic-isolated-page .ic-header-label {
font-size: 10px;
}

.ic-isolated-page .ic-arrow {
font-size: 12px;
}

.ic-isolated-page .ic-name {
font-size: 11px;
max-width: 150px;
}

.ic-isolated-page .ic-group-title {
font-size: 12px;
padding: 6px 10px;
}
}

/* Для ширины 800px и выше - 2 колонки */
@media (min-width: 800px) {
.ic-isolated-page .ic-masonry-column {
width: calc(50% - 8px);
max-width: 400px;
}
}

/* Для ширины 1200px и выше - 3 колонки */
@media (min-width: 1200px) {
.ic-isolated-page .ic-wrapper {
max-width: 1200px;
}

.ic-isolated-page .ic-masonry-column {
width: calc(33.333% - 10px);
max-width: 400px;
}
}

/* Для ширины 1400px и выше - 4 колонки */
@media (min-width: 1400px) {
.ic-isolated-page .ic-wrapper {
max-width: 1400px;
}

.ic-isolated-page .ic-masonry-column {
width: calc(25% - 12px);
max-width: 400px;
}
}
</style>
</head>
<body class="ic-isolated-page">
<div class="ic-container">
<div class="ic-body">
<div class="ic-wrapper">
<h1 class="ic-title">Сравнение иконок ИСИХОГИ старой и новой версий</h1>

<div class="ic-search-area">
<input type="text"
id="icSearch"
class="ic-search"
placeholder="Поиск по названию иконки..."
autocomplete="off">
</div>

<div class="ic-controls">
<div class="ic-stats">
Всего иконок для сравнения: <span id="icTotalCount">0</span> |
Отображено: <span id="icShownCount">0</span>
</div>
<select id="icGroupSelect" class="ic-group-select" style="display: none;">
<option value="">Все группы</option>
<option value="no_group">Прочие</option>
</select>
<div class="ic-toggle">
<input type="checkbox" id="icShowGroups" class="ic-checkbox" checked>
<label for="icShowGroups">Показывать группы</label>
</div>
</div>

<div class="ic-grid" id="icContainer">
<div class="ic-loading">Загрузка иконок...</div>
</div>
</div>
</div>
</div>

<script>
(function() {
'use strict';

let icAllIcons = [];
let icFilteredIcons = [];
let icAvailableGroups = [];
let icShowGroups = true;
let icThemeCheckInterval = null;
let icResizeTimeout = null;
let icSearchTimeout = null;

// Функция для определения темы Hugo
function icDetectHugoTheme() {
const html = document.documentElement;
const body = document.body;

if (html.getAttribute('data-theme') === 'dark' ||
html.getAttribute('data-mode') === 'dark' ||
html.classList.contains('dark') ||
html.classList.contains('dark-mode') ||
body.classList.contains('dark') ||
body.classList.contains('dark-theme') ||
body.classList.contains('dark-mode') ||
document.querySelector('.dark-mode, .dark-theme, [data-theme="dark"]')) {
return 'dark';
}

return 'light';
}

// Функция для применения темы
function icApplyTheme() {
try {
const theme = icDetectHugoTheme();
const page = document.querySelector('.ic-isolated-page');

if (!page) return;

if (theme === 'dark') {
page.setAttribute('data-ic-theme', 'dark');
} else {
page.removeAttribute('data-ic-theme');
}
} catch (error) {
console.warn('Ошибка применения темы:', error);
}
}

// Простой наблюдатель за темой
function icSetupThemeObserver() {
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
}

let lastTheme = icDetectHugoTheme();

icThemeCheckInterval = setInterval(() => {
const currentTheme = icDetectHugoTheme();
if (currentTheme !== lastTheme) {
lastTheme = currentTheme;
icApplyTheme();
}
}, 1000);

icApplyTheme();
}

// Функция для разбивки больших групп на части
function icSplitLargeGroup(icons, maxItems = 15) {
if (icons.length <= maxItems) {
return [icons];
}

const chunks = [];
for (let i = 0; i < icons.length; i += maxItems) {
chunks.push(icons.slice(i, i + maxItems));
}
return chunks;
}

// Функция для расчета примерной высоты группы
function icCalculateGroupHeight(iconsCount) {
const headerHeight = 36;
const rowHeight = 30;
const padding = 12;
return headerHeight + (iconsCount * rowHeight) + padding;
}

// Функция для создания адаптивной masonry компоновки - ВОЗВРАЩАЕМ ОРИГИНАЛЬНУЮ ЛОГИКУ
function icCreateMasonryLayout(groupsChunks) {
const container = document.getElementById('icContainer');
if (!container) return [];

const containerWidth = container.clientWidth;
const columnWidth = 400 + 15; // Ширина панели + отступ

// Динамическое количество колонок
let maxColumns;
if (containerWidth >= 1400) {
maxColumns = 4;
} else if (containerWidth >= 1200) {
maxColumns = 3;
} else if (containerWidth >= 800) {
maxColumns = 2;
} else {
maxColumns = 1;
}

const availableColumns = Math.min(maxColumns, Math.max(1, Math.floor(containerWidth / columnWidth)));

// Создаем колонки
const columns = Array.from({ length: availableColumns }, () => {
const col = document.createElement('div');
col.className = 'ic-masonry-column';
return col;
});

// Массив для отслеживания высоты каждой колонки
const columnHeights = Array(availableColumns).fill(0);

// Распределяем группы по колонкам (алгоритм "наименьшая высота")
groupsChunks.forEach(group => {
let minHeight = Math.min(...columnHeights);
let columnIndex = columnHeights.indexOf(minHeight);

const section = icCreateGroupSection(group.name, group.icons);
columns[columnIndex].appendChild(section);

columnHeights[columnIndex] += group.height;
});

return columns;
}

// Функция для отображения иконок с группировкой
function icRenderWithGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

// Группируем иконки
const { groups, noGroup } = icGroupIcons(icFilteredIcons);

// Собираем все группы и разбиваем большие
const allGroupChunks = [];

Object.entries(groups).forEach(([groupName, icons]) => {
const chunks = icSplitLargeGroup(icons, 15);
chunks.forEach((chunk, index) => {
const chunkName = chunks.length > 1 ? `${groupName} (${index + 1}/${chunks.length})` : groupName;
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: groupName,
height: icCalculateGroupHeight(chunk.length)
});
});
});

// Добавляем иконки без группы как "Прочие"
if (noGroup.length > 0) {
const noGroupChunks = icSplitLargeGroup(noGroup, 15);
noGroupChunks.forEach((chunk, index) => {
const chunkName = noGroupChunks.length > 1 ? `Прочие иконки (${index + 1}/${noGroupChunks.length})` : 'Прочие иконки';
allGroupChunks.push({
name: chunkName,
icons: chunk,
originalGroup: 'no_group',
height: icCalculateGroupHeight(chunk.length)
});
});
}

// Сортируем по высоте (от высоких к низким для лучшего заполнения)
allGroupChunks.sort((a, b) => b.height - a.height);

// Создаем адаптивную masonry компоновку
const columns = icCreateMasonryLayout(allGroupChunks);

// Очищаем контейнер и добавляем колонки
container.innerHTML = '';
const columnsContainer = document.createElement('div');
columnsContainer.className = 'ic-masonry-columns';

columns.forEach(col => {
if (col.children.length > 0) {
columnsContainer.appendChild(col);
}
});

container.appendChild(columnsContainer);
icUpdateStats();
}

// Функция для создания секции группы - ВСЕ ЭЛЕМЕНТЫ В ОДНОМ КОНТЕЙНЕРЕ
function icCreateGroupSection(groupName, icons) {
const section = document.createElement('div');
section.className = 'ic-group-section';

// Заголовок группы с ФИКСИРОВАННОЙ шириной как у панели
const header = document.createElement('div');
header.className = 'ic-group-title';
header.textContent = groupName;
header.title = groupName;
section.appendChild(header);

// Контейнер для панели
const content = document.createElement('div');
content.className = 'ic-group-content';

const panel = icCreateIconColumn(icons);
content.appendChild(panel);

section.appendChild(content);

return section;
}

// Функция для создания колонки с иконками
function icCreateIconColumn(icons) {
const column = document.createElement('div');
column.className = 'ic-panel';

const header = document.createElement('div');
header.className = 'ic-panel-header';

const beforeLabel = document.createElement('div');
beforeLabel.className = 'ic-header-label';
beforeLabel.textContent = 'ДО';

const arrowSpace = document.createElement('div');
arrowSpace.className = 'ic-arrow';
arrowSpace.textContent = '→';

const afterLabel = document.createElement('div');
afterLabel.className = 'ic-header-label';
afterLabel.textContent = 'ПОСЛЕ';

const nameLabel = document.createElement('div');
nameLabel.className = 'ic-header-label';
nameLabel.textContent = 'Название';
nameLabel.style.textAlign = 'center';

header.appendChild(beforeLabel);
header.appendChild(arrowSpace);
header.appendChild(afterLabel);
header.appendChild(nameLabel);

column.appendChild(header);

icons.forEach(icon => {
column.appendChild(icCreateIconRow(icon));
});

return column;
}

// Обработчик изменения размера окна
function icSetupResizeHandler() {
let resizeTimeout;
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (icShowGroups && icFilteredIcons.length > 0) {
icRenderWithGroups();
}
}, 250);
});
}

// Упрощенная функция для обработки BMP
function icProcessBMP(img) {
return new Promise((resolve) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth || 32;
canvas.height = img.naturalHeight || 32;

ctx.drawImage(img, 0, 0);

// Убираем только magenta (#FF00FF)
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;

for (let i = 0; i < data.length; i += 4) {
if (data[i] === 255 && data[i + 1] === 0 && data[i + 2] === 255) {
data[i + 3] = 0;
}
}

ctx.putImageData(imageData, 0, 0);

const processedImg = new Image();
processedImg.onload = () => resolve({
element: processedImg,
processed: true
});
processedImg.src = canvas.toDataURL('image/png');
} catch (error) {
resolve({
element: img,
processed: false
});
}
});
}

// Функция загрузки изображений
function icLoadImage(src, alt) {
return new Promise((resolve) => {
const img = new Image();

img.onload = async function() {
try {
if (src.toLowerCase().endsWith('.bmp')) {
const result = await icProcessBMP(img);
result.element.alt = alt;
result.element.width = 32;
result.element.height = 32;
resolve(result);
} else {
img.alt = alt;
img.width = 32;
img.height = 32;
resolve({ element: img, processed: false });
}
} catch (error) {
img.alt = alt;
img.width = 32;
img.height = 32;
resolve({ element: img, processed: false });
}
};

img.onerror = function() {
const placeholder = new Image();
placeholder.width = 32;
placeholder.height = 32;
placeholder.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSIjRjVGNUY1Ii8+CjxwYXRoIGQ9Ik0xNiAxOEMxNi41NTIzIDE4IDE3IDE3LjU1MjMgMTcgMTdWMTFDMTcgMTAuNDQ3NyAxNi41NTIzIDEwIDE2IDEwQzE1LjQ0NzcgMTAgMTUgMTAuNDQ3NyAxNSAxMVYxN0MxNSAxNy41NTIzIDE1LjQ0NzcgMTggMTYgMThaIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0xNiAyMkMxNi41NTIzIDIyIDE3IDIxLjU1MjMgMTcgMjFDMTcgMjAuNDQ3NyAxNi41NTIzIDIwIDE2IDIwQzE1LjQ0NzcgMjAgMTUgMjAuNDQ3NyAxNSAyMUMxNSAyMS41NTIzIDE1LjQ0NzcgMjIgMTYgMjJaIiBmaWxsPSIjOTk5OTk5Ii8+Cjwvc3ZnPgo=';
placeholder.alt = alt;
resolve({ element: placeholder, processed: false });
};

img.src = src;
});
}

function icGroupIcons(icons) {
const groups = {};
const noGroup = [];

icons.forEach(icon => {
if (icon.group && icon.group.trim() !== '') {
if (!groups[icon.group]) {
groups[icon.group] = [];
}
groups[icon.group].push(icon);
} else {
noGroup.push(icon);
}
});

return { groups, noGroup };
}

function icCreateIconRow(icon) {
const row = document.createElement('div');
row.className = 'ic-row';

const beforeContainer = document.createElement('div');
const afterContainer = document.createElement('div');

Promise.all([
icLoadImage(icon.before, `${icon.name} (до)`),
icLoadImage(icon.after, `${icon.name} (после)`)
]).then(([beforeResult, afterResult]) => {
const beforeImg = beforeResult.element;
const afterImg = afterResult.element;

beforeImg.className = 'ic-image';
afterImg.className = 'ic-image';

if (beforeResult.processed) beforeImg.classList.add('ic-bmp-processed');
if (afterResult.processed) afterImg.classList.add('ic-bmp-processed');

beforeImg.width = 32;
beforeImg.height = 32;
beforeImg.style.width = '32px';
beforeImg.style.height = '32px';

afterImg.width = 32;
afterImg.height = 32;
afterImg.style.width = '32px';
afterImg.style.height = '32px';

beforeContainer.appendChild(beforeImg);
afterContainer.appendChild(afterImg);
});

const arrow = document.createElement('div');
arrow.className = 'ic-arrow';
arrow.textContent = '→';

const infoDiv = document.createElement('div');
infoDiv.className = 'ic-info';

const name = document.createElement('div');
name.className = 'ic-name';
name.textContent = icon.name;
name.title = icon.name;

infoDiv.appendChild(name);

row.appendChild(beforeContainer);
row.appendChild(arrow);
row.appendChild(afterContainer);
row.appendChild(infoDiv);

return row;
}

function icRenderWithoutGroups() {
const container = document.getElementById('icContainer');
container.innerHTML = '';

if (icFilteredIcons.length === 0) {
container.innerHTML = '<div class="ic-no-results">Ничего не найдено. Попробуйте изменить поисковый запрос или выбрать другую группу.</div>';
icUpdateStats();
return;
}

const sortedIcons = [...icFilteredIcons].sort((a, b) => {
const groupA = a.group || 'zzz';
const groupB = b.group || 'zzz';

if (groupA !== groupB) {
return groupA.localeCompare(groupB);
}

return a.name.localeCompare(b.name);
});

const itemsPerColumn = 20;
const columnCount = Math.ceil(sortedIcons.length / itemsPerColumn);

const columnsContainer = document.createElement('div');
columnsContainer.className = 'ic-columns';

for (let i = 0; i < columnCount; i++) {
const startIndex = i * itemsPerColumn;
const endIndex = startIndex + itemsPerColumn;
const columnIcons = sortedIcons.slice(startIndex, endIndex);
const column = icCreateIconColumn(columnIcons);
columnsContainer.appendChild(column);
}

container.appendChild(columnsContainer);
icUpdateStats();
}

function icFilterIcons(searchTerm, selectedGroup = '') {
let filtered = [...icAllIcons];

if (searchTerm) {
const term = searchTerm.toLowerCase();
filtered = filtered.filter(icon =>
icon.name.toLowerCase().includes(term) ||
(icon.group && icon.group.toLowerCase().includes(term))
);
}

if (selectedGroup) {
if (selectedGroup === 'no_group') {
filtered = filtered.filter(icon => !icon.group || icon.group.trim() === '');
} else {
filtered = filtered.filter(icon => icon.group === selectedGroup);
}
}

icFilteredIcons = filtered;
icRenderFilteredIcons();
}

function icRenderFilteredIcons() {
if (icShowGroups) {
icRenderWithGroups();
} else {
icRenderWithoutGroups();
}
}

function icUpdateStats() {
const totalCount = document.getElementById('icTotalCount');
const shownCount = document.getElementById('icShownCount');

if (totalCount) totalCount.textContent = icAllIcons.length;
if (shownCount) shownCount.textContent = icFilteredIcons.length;
}

function icInitGroupSelect(groups) {
const groupSelect = document.getElementById('icGroupSelect');
if (!groupSelect) return;

groupSelect.innerHTML = '<option value="">Все группы</option>';
groupSelect.innerHTML += '<option value="no_group">Прочие</option>';

groups.forEach(group => {
const option = document.createElement('option');
option.value = group;
option.textContent = group;
groupSelect.appendChild(option);
});

groupSelect.style.display = (groups.length > 0) ? 'block' : 'none';

groupSelect.addEventListener('change', function() {
const searchTerm = document.getElementById('icSearch').value;
icFilterIcons(searchTerm, this.value);
});
}

function icRenderIcons(images, groups) {
icAllIcons = images;
icFilteredIcons = [...icAllIcons];
icAvailableGroups = groups;

icInitGroupSelect(groups);
icRenderFilteredIcons();
}

async function icLoadIcons() {
try {
const script = document.createElement('script');
script.src = 'image_list.js';
document.head.appendChild(script);

script.onload = function() {
try {
const data = loadBeforeAfterImages();

if (data && data.images) {
const processedImages = data.images.map(icon => {
const displayName = icon.name.replace(/^32x32_/, '');
return {
...icon,
name: displayName
};
});

icRenderIcons(processedImages, data.availableGroups || []);
} else {
const container = document.getElementById('icContainer');
if (container) container.innerHTML = '<div class="ic-loading">Ошибка загрузки данных</div>';
}
} catch (error) {
const container = document.getElementById('icContainer');
if (container) container.innerHTML = '<div class="ic-loading">Ошибка обработки данных</div>';
}
};

script.onerror = function() {
const container = document.getElementById('icContainer');
if (container) container.innerHTML = '<div class="ic-loading">Ошибка загрузки файла image_list.js</div>';
};

} catch (error) {
const container = document.getElementById('icContainer');
if (container) container.innerHTML = '<div class="ic-loading">Ошибка загрузки иконок</div>';
}
}

function icSetupSearch() {
const searchInput = document.getElementById('icSearch');
if (!searchInput) return;

let searchTimeout;

searchInput.addEventListener('input', function(e) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons(e.target.value, selectedGroup);
}, 300);
});

searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
const selectedGroup = document.getElementById('icGroupSelect').value;
icFilterIcons('', selectedGroup);
}
});
}

function icSetupToggle() {
const toggle = document.getElementById('icShowGroups');
if (!toggle) return;

toggle.addEventListener('change', function() {
icShowGroups = this.checked;
icRenderFilteredIcons();
});
}

// Очистка при разгрузке
function icCleanup() {
if (icThemeCheckInterval) {
clearInterval(icThemeCheckInterval);
icThemeCheckInterval = null;
}
clearTimeout(icResizeTimeout);
clearTimeout(icSearchTimeout);
}

// Инициализация
document.addEventListener('DOMContentLoaded', function() {
try {
icSetupThemeObserver();
icLoadIcons();
icSetupSearch();
icSetupToggle();
icSetupResizeHandler();

window.addEventListener('beforeunload', icCleanup);
window.addEventListener('pagehide', icCleanup);

} catch (error) {
console.error('Ошибка инициализации:', error);
}
});
})();
</script>
</body>
</html>
Поиск:
Новый ответ
Имя:
Текст сообщения: