YouTube Channel Analytics Pro

Расширенная статистика для YouTube: отображение скрытых метрик каналов, анализ просмотров, динамики и активности.

当前为 2025-11-17 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         YouTube Channel Analytics Pro
// @version      0.1
// @description  Расширенная статистика для YouTube: отображение скрытых метрик каналов, анализ просмотров, динамики и активности.
// @author       lumo
// @match        https://www.youtube.com/*
// @grant        none
// @license      Proprietary - запрещено копировать, изменять, распространять и использовать код без разрешения автора
// @homepageURL  https://greasyfork.org/
// @supportURL   https://greasyfork.org/
// @namespace http://tampermonkey.net/
// ==/UserScript==

(function() {
'use strict';

const style = document.createElement('style');
style.textContent = `
    .lumo-analytics-wrapper {
        width: 100%;
        margin-top: 16px;
    }

    .lumo-analytics-container {
        background: linear-gradient(135deg, #0f0f0f 0%, #1a1a1a 100%);
        border-radius: 16px;
        padding: 20px;
        border: 1px solid #303030;
        width: 100%;
        max-width: 100%;
        box-sizing: border-box;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        font-family: "Roboto", "Arial", sans-serif;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    }

    .lumo-analytics-container:hover {
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border-color: #404040;
        box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
        transform: translateY(-2px);
    }

    .lumo-analytics-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 16px;
        gap: 12px;
        flex-wrap: wrap;
    }

    .lumo-analytics-title {
        font-size: 16px;
        font-weight: 600;
        color: #ffffff;
        display: flex;
        align-items: center;
        gap: 10px;
        font-family: "Roboto", "Arial", sans-serif;
        letter-spacing: 0.5px;
    }

    .lumo-analytics-badge {
        background: linear-gradient(135deg, #ff0000 0%, #cc0000 100%);
        padding: 4px 10px;
        border-radius: 4px;
        font-size: 11px;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 1px;
        color: #ffffff;
        box-shadow: 0 2px 8px rgba(255, 0, 0, 0.3);
    }

    .lumo-analytics-badge.live {
        background: linear-gradient(135deg, #ff0000 0%, #ff4444 100%);
        animation: lumo-pulse 1.5s infinite;
    }

    @keyframes lumo-pulse {
        0%, 100% { opacity: 1; transform: scale(1); }
        50% { opacity: 0.8; transform: scale(1.05); }
    }

    .lumo-analytics-expand-btn {
        background: linear-gradient(135deg, #272727 0%, #3f3f3f 100%);
        border: none;
        color: #ffffff;
        padding: 10px 18px;
        border-radius: 20px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        display: flex;
        align-items: center;
        gap: 8px;
        font-family: "Roboto", "Arial", sans-serif;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    }

    .lumo-analytics-expand-btn:hover {
        background: linear-gradient(135deg, #3f3f3f 0%, #4f4f4f 100%);
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
    }

    .lumo-analytics-expand-btn:active {
        transform: scale(0.95);
    }

    .lumo-stats-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
        gap: 12px;
    }

    .lumo-stat-card {
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border-radius: 12px;
        padding: 16px;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        border: 1px solid #303030;
        position: relative;
        overflow: hidden;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    }

    .lumo-stat-card::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 2px;
        background: linear-gradient(90deg, #ff0000, #ff4444);
        transform: scaleX(0);
        transition: transform 0.3s;
    }

    .lumo-stat-card:hover::before {
        transform: scaleX(1);
    }

    .lumo-stat-card:hover {
        background: linear-gradient(135deg, #242424 0%, #2f2f2f 100%);
        border-color: #505050;
        transform: translateY(-4px);
        box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
    }

    .lumo-stat-label {
        font-size: 13px;
        color: #cccccc;
        margin-bottom: 8px;
        font-family: "Roboto", "Arial", sans-serif;
        font-weight: 500;
        letter-spacing: 0.5px;
    }

    .lumo-stat-value {
        font-size: 18px;
        font-weight: 700;
        color: #ffffff;
        display: flex;
        align-items: center;
        gap: 8px;
        font-family: "Roboto", "Arial", sans-serif;
    }

    .lumo-stat-icon {
        font-size: 16px;
        opacity: 0.95;
        color: #ff0000;
    }

    .lumo-loading {
        text-align: center;
        padding: 20px;
    }

    .lumo-spinner {
        width: 24px;
        height: 24px;
        border: 3px solid #272727;
        border-top-color: #ff0000;
        border-radius: 50%;
        animation: lumo-spin 0.8s linear infinite;
        margin: 0 auto 12px;
    }

    @keyframes lumo-spin {
        to { transform: rotate(360deg); }
    }

    .lumo-loading-text {
        font-size: 14px;
        color: #cccccc;
        font-family: "Roboto", "Arial", sans-serif;
        font-weight: 500;
    }

    .lumo-country-info {
        display: flex;
        align-items: center;
        gap: 10px;
    }

    .lumo-country-flag {
        width: 28px;
        height: 20px;
        border-radius: 3px;
        object-fit: cover;
        border: 1px solid #3f3f3f;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
    }

    .lumo-country-name {
        font-size: 15px;
        color: #ffffff;
        font-family: "Roboto", "Arial", sans-serif;
        font-weight: 600;
    }

    .lumo-modal {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.92);
        z-index: 99999;
        display: none;
        align-items: center;
        justify-content: center;
        animation: lumo-fade-in 0.25s;
        backdrop-filter: blur(4px);
    }

    .lumo-modal.active {
        display: flex;
    }

    .lumo-modal-content {
        background: linear-gradient(135deg, #0f0f0f 0%, #1a1a1a 100%);
        border-radius: 16px;
        padding: 28px;
        max-width: 1400px;
        width: 94%;
        max-height: 90vh;
        overflow-y: auto;
        animation: lumo-slide-up 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        box-shadow: 0 12px 48px rgba(0, 0, 0, 0.8);
        border: 1px solid #303030;
    }

    .lumo-modal-content::-webkit-scrollbar {
        width: 12px;
    }

    .lumo-modal-content::-webkit-scrollbar-track {
        background: #0f0f0f;
        border-radius: 6px;
    }

    .lumo-modal-content::-webkit-scrollbar-thumb {
        background: linear-gradient(135deg, #3f3f3f 0%, #5f5f5f 100%);
        border-radius: 6px;
    }

    .lumo-modal-content::-webkit-scrollbar-thumb:hover {
        background: linear-gradient(135deg, #5f5f5f 0%, #7f7f7f 100%);
    }

    @keyframes lumo-slide-up {
        from {
            opacity: 0;
            transform: translateY(40px) scale(0.95);
        }
        to {
            opacity: 1;
            transform: translateY(0) scale(1);
        }
    }

    @keyframes lumo-fade-in {
        from { opacity: 0; }
        to { opacity: 1; }
    }

    .lumo-modal-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 24px;
        padding-bottom: 20px;
        border-bottom: 2px solid #303030;
    }

    .lumo-modal-title {
        font-size: 24px;
        font-weight: 700;
        color: #ffffff;
        font-family: "Roboto", "Arial", sans-serif;
        letter-spacing: 0.5px;
    }

    .lumo-modal-close {
        background: linear-gradient(135deg, #272727 0%, #3f3f3f 100%);
        border: none;
        color: #ffffff;
        width: 42px;
        height: 42px;
        border-radius: 50%;
        cursor: pointer;
        font-size: 24px;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 0;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    }

    .lumo-modal-close:hover {
        background: linear-gradient(135deg, #ff0000 0%, #cc0000 100%);
        transform: rotate(90deg) scale(1.1);
        box-shadow: 0 4px 16px rgba(255, 0, 0, 0.4);
    }

    .lumo-modal-close:active {
        transform: rotate(90deg) scale(0.95);
    }

    .lumo-tabs {
        display: flex;
        gap: 8px;
        margin-bottom: 24px;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 6px;
    }

    .lumo-tabs::-webkit-scrollbar {
        height: 0;
    }

    .lumo-tab {
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border: 1px solid #303030;
        color: #cccccc;
        padding: 12px 22px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        border-radius: 10px;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        position: relative;
        white-space: nowrap;
        font-family: "Roboto", "Arial", sans-serif;
        letter-spacing: 0.5px;
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
    }

    .lumo-tab:hover {
        color: #ffffff;
        background: linear-gradient(135deg, #272727 0%, #3f3f3f 100%);
        border-color: #505050;
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
    }

    .lumo-tab.active {
        color: #ffffff;
        background: linear-gradient(135deg, #ff0000 0%, #cc0000 100%);
        border-color: #ff0000;
        box-shadow: 0 4px 16px rgba(255, 0, 0, 0.4);
    }

    .lumo-tab-content {
        display: none;
    }

    .lumo-tab-content.active {
        display: block;
        animation: lumo-fade-in 0.3s;
    }

    .lumo-detail-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: 16px;
        margin-bottom: 20px;
    }

    .lumo-detail-card {
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border-radius: 12px;
        padding: 20px;
        border: 1px solid #303030;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    }

    .lumo-detail-card:hover {
        background: linear-gradient(135deg, #242424 0%, #2f2f2f 100%);
        border-color: #505050;
        transform: translateY(-4px);
        box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
    }

    .lumo-detail-card-title {
        font-size: 12px;
        color: #cccccc;
        margin-bottom: 12px;
        text-transform: uppercase;
        letter-spacing: 1.2px;
        font-family: "Roboto", "Arial", sans-serif;
        font-weight: 600;
    }

    .lumo-detail-card-value {
        font-size: 28px;
        font-weight: 700;
        color: #ffffff;
        margin-bottom: 8px;
        font-family: "Roboto", "Arial", sans-serif;
    }

    .lumo-detail-card-subtitle {
        font-size: 13px;
        color: #aaaaaa;
        font-family: "Roboto", "Arial", sans-serif;
        letter-spacing: 0.3px;
        font-weight: 500;
    }

    .lumo-chart-bar {
        margin-bottom: 16px;
    }

    .lumo-chart-label {
        font-size: 13px;
        color: #cccccc;
        margin-bottom: 10px;
        display: flex;
        justify-content: space-between;
        font-family: "Roboto", "Arial", sans-serif;
        letter-spacing: 0.3px;
        font-weight: 600;
    }

    .lumo-chart-bar-bg {
        background: #272727;
        height: 10px;
        border-radius: 5px;
        overflow: hidden;
        box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
    }

    .lumo-chart-bar-fill {
        height: 100%;
        background: linear-gradient(90deg, #ff0000, #ff4444);
        border-radius: 5px;
        transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1);
        box-shadow: 0 0 10px rgba(255, 0, 0, 0.5);
    }

    .lumo-day-distribution {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
        gap: 12px;
        margin-top: 16px;
    }

    .lumo-day-item {
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border-radius: 12px;
        padding: 16px 12px;
        text-align: center;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        border: 1px solid #303030;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    }

    .lumo-day-item:hover {
        background: linear-gradient(135deg, #242424 0%, #2f2f2f 100%);
        transform: translateY(-4px) scale(1.05);
        border-color: #505050;
        box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
    }

    .lumo-day-item.active {
        background: linear-gradient(135deg, #ff0000 0%, #cc0000 100%);
        border-color: #ff0000;
        box-shadow: 0 6px 24px rgba(255, 0, 0, 0.5);
    }

    .lumo-day-name {
        font-size: 12px;
        color: #cccccc;
        margin-bottom: 8px;
        font-family: "Roboto", "Arial", sans-serif;
        letter-spacing: 0.6px;
        text-transform: uppercase;
        font-weight: 600;
    }

    .lumo-day-item.active .lumo-day-name {
        color: #ffffff;
    }

    .lumo-day-count {
        font-size: 20px;
        font-weight: 700;
        color: #ffffff;
        font-family: "Roboto", "Arial", sans-serif;
    }

    .lumo-trend-up {
        color: #00ff88;
    }

    .lumo-trend-down {
        color: #ff4444;
    }

    .lumo-trend-stable {
        color: #ffbb33;
    }

    .lumo-chart-wrapper {
        position: relative;
        margin-bottom: 24px;
    }

    .lumo-chart-canvas {
        width: 100%;
        height: 320px;
        border-radius: 12px;
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border: 1px solid #303030;
        cursor: crosshair;
        box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
    }

    .lumo-chart-tooltip {
        position: fixed;
        background: linear-gradient(135deg, #1f1f1f 0%, #2a2a2a 100%);
        border: 1px solid #505050;
        border-radius: 10px;
        padding: 12px 16px;
        pointer-events: none;
        opacity: 0;
        transition: opacity 0.2s;
        font-family: "Roboto", "Arial", sans-serif;
        font-size: 13px;
        color: #ffffff;
        box-shadow: 0 6px 20px rgba(0, 0, 0, 0.6);
        z-index: 100000;
        white-space: nowrap;
    }

    .lumo-chart-tooltip.visible {
        opacity: 1;
    }

    .lumo-chart-tooltip-label {
        font-weight: 600;
        margin-bottom: 6px;
        color: #ff4444;
        letter-spacing: 0.5px;
    }

    .lumo-chart-tooltip-value {
        font-size: 18px;
        font-weight: 700;
        color: #ffffff;
    }

    .lumo-trend-indicator {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 20px;
        padding: 28px;
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border-radius: 16px;
        margin-bottom: 24px;
        border: 2px solid #303030;
        box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
    }

    .lumo-trend-indicator.explosive-growth {
        border-color: #00ff88;
        background: linear-gradient(135deg, rgba(0, 255, 136, 0.15) 0%, rgba(0, 255, 136, 0.03) 100%);
        box-shadow: 0 4px 24px rgba(0, 255, 136, 0.3);
    }

    .lumo-trend-indicator.strong-growth {
        border-color: #33ff99;
        background: linear-gradient(135deg, rgba(51, 255, 153, 0.12) 0%, rgba(51, 255, 153, 0.02) 100%);
        box-shadow: 0 4px 20px rgba(51, 255, 153, 0.25);
    }

    .lumo-trend-indicator.moderate-growth {
        border-color: #66ffaa;
        background: linear-gradient(135deg, rgba(102, 255, 170, 0.1) 0%, rgba(102, 255, 170, 0.02) 100%);
        box-shadow: 0 4px 16px rgba(102, 255, 170, 0.2);
    }

    .lumo-trend-indicator.slight-growth {
        border-color: #99ffbb;
        background: linear-gradient(135deg, rgba(153, 255, 187, 0.08) 0%, rgba(153, 255, 187, 0.01) 100%);
    }

    .lumo-trend-indicator.stable {
        border-color: #ffbb33;
        background: linear-gradient(135deg, rgba(255, 187, 51, 0.12) 0%, rgba(255, 187, 51, 0.02) 100%);
        box-shadow: 0 4px 16px rgba(255, 187, 51, 0.2);
    }

    .lumo-trend-indicator.stagnant {
        border-color: #999999;
        background: linear-gradient(135deg, rgba(153, 153, 153, 0.12) 0%, rgba(153, 153, 153, 0.02) 100%);
    }

    .lumo-trend-indicator.slight-decline {
        border-color: #ffaa99;
        background: linear-gradient(135deg, rgba(255, 170, 153, 0.08) 0%, rgba(255, 170, 153, 0.01) 100%);
    }

    .lumo-trend-indicator.moderate-decline {
        border-color: #ff6666;
        background: linear-gradient(135deg, rgba(255, 102, 102, 0.1) 0%, rgba(255, 102, 102, 0.02) 100%);
        box-shadow: 0 4px 16px rgba(255, 102, 102, 0.2);
    }

    .lumo-trend-indicator.strong-decline {
        border-color: #ff3333;
        background: linear-gradient(135deg, rgba(255, 51, 51, 0.12) 0%, rgba(255, 51, 51, 0.02) 100%);
        box-shadow: 0 4px 20px rgba(255, 51, 51, 0.25);
    }

    .lumo-trend-indicator.critical-decline {
        border-color: #ff0000;
        background: linear-gradient(135deg, rgba(255, 0, 0, 0.15) 0%, rgba(255, 0, 0, 0.03) 100%);
        box-shadow: 0 4px 24px rgba(255, 0, 0, 0.3);
    }

    .lumo-trend-icon {
        font-size: 56px;
        line-height: 1;
        filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.4));
    }

    .lumo-trend-info {
        flex: 1;
    }

    .lumo-trend-status {
        font-size: 28px;
        font-weight: 700;
        margin-bottom: 8px;
        font-family: "Roboto", "Arial", sans-serif;
        letter-spacing: 0.5px;
        color: #ffffff;
    }

    .lumo-trend-desc {
        font-size: 15px;
        color: #cccccc;
        font-family: "Roboto", "Arial", sans-serif;
        letter-spacing: 0.3px;
        font-weight: 500;
    }

    .lumo-metrics-row {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
        gap: 16px;
        margin-bottom: 24px;
    }

    .lumo-metric-card {
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border-radius: 12px;
        padding: 20px;
        border-left: 4px solid #ff0000;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    }

    .lumo-metric-card:hover {
        background: linear-gradient(135deg, #242424 0%, #2f2f2f 100%);
        transform: translateX(4px);
        box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
    }

    .lumo-metric-card.positive {
        border-left-color: #00ff88;
    }

    .lumo-metric-card.negative {
        border-left-color: #ff4444;
    }

    .lumo-metric-card.neutral {
        border-left-color: #ffbb33;
    }

    .lumo-metric-label {
        font-size: 12px;
        color: #cccccc;
        margin-bottom: 12px;
        font-family: "Roboto", "Arial", sans-serif;
        text-transform: uppercase;
        letter-spacing: 1.2px;
        font-weight: 600;
    }

    .lumo-metric-value {
        font-size: 24px;
        font-weight: 700;
        margin-bottom: 8px;
        font-family: "Roboto", "Arial", sans-serif;
        color: #ffffff;
    }

    .lumo-metric-change {
        font-size: 14px;
        font-family: "Roboto", "Arial", sans-serif;
        display: flex;
        align-items: center;
        gap: 8px;
        color: #ffffff;
        letter-spacing: 0.3px;
        font-weight: 500;
    }

    .lumo-author {
        text-align: center;
        margin-top: 24px;
        padding-top: 20px;
        border-top: 1px solid #303030;
        font-size: 12px;
        color: #888888;
        font-family: "Roboto", "Arial", sans-serif;
        letter-spacing: 0.6px;
        font-weight: 500;
    }

    .lumo-performance-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
        gap: 16px;
    }

    .lumo-performance-item {
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border-radius: 12px;
        padding: 20px;
        border: 1px solid #303030;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    }

    .lumo-performance-item:hover {
        transform: translateY(-4px);
        box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
        border-color: #505050;
    }

    .lumo-performance-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 14px;
    }

    .lumo-performance-title {
        font-size: 13px;
        color: #cccccc;
        text-transform: uppercase;
        letter-spacing: 1px;
        font-weight: 600;
    }

    .lumo-performance-score {
        font-size: 28px;
        font-weight: 700;
        font-family: "Roboto", "Arial", sans-serif;
    }

    .lumo-performance-desc {
        font-size: 13px;
        color: #aaaaaa;
        margin-top: 10px;
        line-height: 1.6;
        font-weight: 500;
    }

    .lumo-score-excellent {
        color: #00ff88;
    }

    .lumo-score-good {
        color: #33ff99;
    }

    .lumo-score-average {
        color: #ffbb33;
    }

    .lumo-score-poor {
        color: #ff9966;
    }

    .lumo-score-bad {
        color: #ff4444;
    }

    .lumo-score-legend {
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border-radius: 12px;
        padding: 20px;
        margin-bottom: 20px;
        border: 1px solid #303030;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    }

    .lumo-score-legend-title {
        font-size: 16px;
        font-weight: 700;
        color: #ffffff;
        margin-bottom: 16px;
    }

    .lumo-score-legend-items {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
        gap: 12px;
    }

    .lumo-score-legend-item {
        display: flex;
        align-items: center;
        gap: 10px;
        font-size: 13px;
        font-weight: 600;
        color: #ffffff;
    }

    .lumo-score-legend-badge {
        font-size: 18px;
        font-weight: 700;
        min-width: 40px;
    }

    .lumo-compare-section {
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border-radius: 12px;
        padding: 24px;
        margin-bottom: 20px;
        border: 1px solid #303030;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    }

    .lumo-compare-title {
        font-size: 18px;
        font-weight: 700;
        color: #ffffff;
        margin-bottom: 20px;
        font-family: "Roboto", "Arial", sans-serif;
    }

    .lumo-compare-grid {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 24px;
    }

    .lumo-compare-column {
        text-align: center;
    }

    .lumo-compare-column-title {
        font-size: 14px;
        color: #cccccc;
        margin-bottom: 14px;
        text-transform: uppercase;
        letter-spacing: 1px;
        font-weight: 600;
    }

    .lumo-compare-value {
        font-size: 36px;
        font-weight: 700;
        color: #ffffff;
        margin-bottom: 10px;
        font-family: "Roboto", "Arial", sans-serif;
    }

    .lumo-compare-diff {
        font-size: 15px;
        font-weight: 600;
        font-family: "Roboto", "Arial", sans-serif;
    }

    .lumo-compare-diff.positive {
        color: #00ff88;
    }

    .lumo-compare-diff.negative {
        color: #ff4444;
    }

    .lumo-live-stats {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
        gap: 14px;
        margin-bottom: 20px;
    }

    .lumo-live-card {
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border-radius: 12px;
        padding: 18px;
        border: 1px solid #303030;
        text-align: center;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    }

    .lumo-live-card:hover {
        transform: translateY(-4px);
        box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
    }

    .lumo-live-card.highlight {
        border-color: #ff0000;
        box-shadow: 0 4px 24px rgba(255, 0, 0, 0.4);
        animation: lumo-pulse 2s infinite;
    }

    .lumo-live-label {
        font-size: 12px;
        color: #cccccc;
        margin-bottom: 10px;
        text-transform: uppercase;
        letter-spacing: 1px;
        font-weight: 600;
    }

    .lumo-live-value {
        font-size: 32px;
        font-weight: 700;
        color: #ffffff;
        font-family: "Roboto", "Arial", sans-serif;
    }

    .lumo-health-indicator {
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border-radius: 12px;
        padding: 24px;
        margin-bottom: 20px;
        border: 1px solid #303030;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    }

    .lumo-health-title {
        font-size: 16px;
        font-weight: 700;
        color: #ffffff;
        margin-bottom: 16px;
    }

    .lumo-health-bar {
        background: #272727;
        height: 14px;
        border-radius: 7px;
        overflow: hidden;
        margin-bottom: 12px;
        box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
    }

    .lumo-health-fill {
        height: 100%;
        transition: width 1s cubic-bezier(0.4, 0, 0.2, 1);
        border-radius: 7px;
        box-shadow: 0 0 12px rgba(255, 255, 255, 0.3);
    }

    .lumo-health-label {
        font-size: 14px;
        color: #cccccc;
        text-align: center;
        font-weight: 600;
    }

    .lumo-prediction-card {
        background: linear-gradient(135deg, #1a1a1a 0%, #242424 100%);
        border-radius: 12px;
        padding: 24px;
        margin-bottom: 20px;
        border: 1px solid #303030;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    }

    .lumo-prediction-title {
        font-size: 16px;
        font-weight: 700;
        color: #ffffff;
        margin-bottom: 16px;
    }

    .lumo-prediction-content {
        display: flex;
        align-items: center;
        gap: 16px;
    }

    .lumo-prediction-icon {
        font-size: 48px;
        filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
    }

    .lumo-prediction-text {
        flex: 1;
        font-size: 15px;
        color: #cccccc;
        line-height: 1.6;
        font-weight: 500;
    }

    @media (max-width: 768px) {
        .lumo-stats-grid {
            grid-template-columns: repeat(2, 1fr);
        }

        .lumo-detail-grid {
            grid-template-columns: 1fr;
        }

        .lumo-modal-content {
            width: 96%;
            padding: 20px;
        }

        .lumo-chart-canvas {
            height: 240px;
        }

        .lumo-metrics-row {
            grid-template-columns: 1fr;
        }

        .lumo-performance-grid {
            grid-template-columns: 1fr;
        }

        .lumo-compare-grid {
            grid-template-columns: 1fr;
        }
    }
`;
document.head.appendChild(style);

const countryFlags = {
    'Россия': 'https://flagcdn.com/w80/ru.png',
    'США': 'https://flagcdn.com/w80/us.png',
    'Украина': 'https://flagcdn.com/w80/ua.png',
    'Беларусь': 'https://flagcdn.com/w80/by.png',
    'Казахстан': 'https://flagcdn.com/w80/kz.png',
    'Германия': 'https://flagcdn.com/w80/de.png',
    'Франция': 'https://flagcdn.com/w80/fr.png',
    'Великобритания': 'https://flagcdn.com/w80/gb.png',
    'Канада': 'https://flagcdn.com/w80/ca.png',
    'Австралия': 'https://flagcdn.com/w80/au.png'
};

const dayNames = ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'];

let cachedData = null;
let isAnalyzing = false;
let chartData = null;
let liveUpdateInterval = null;
let currentMode = 'videos';
let viewerHistory = [];
let maxHistoryLength = 120;

function createElement(tag, className, text) {
    const el = document.createElement(tag);
    if (className) el.className = className;
    if (text) el.textContent = text;
    return el;
}

function parseViews(text) {
    if (!text) return 0;
    const cleanText = text.replace(/\s/g, '').replace(/ /g, '').toLowerCase();
    const num = parseFloat(cleanText.replace(',', '.'));
    if (cleanText.includes('млн')) return num * 1000000;
    if (cleanText.includes('тыс')) return num * 1000;
    return num || 0;
}

function parseDuration(text) {
    if (!text) return 0;
    const parts = text.trim().split(':').map(p => parseInt(p) || 0);
    if (parts.length === 3) return parts[0] * 3600 + parts[1] * 60 + parts[2];
    if (parts.length === 2) return parts[0] * 60 + parts[1];
    return parts[0] || 0;
}

function parseRelativeDate(text) {
    if (!text) return null;
    const now = new Date();
    const lowerText = text.toLowerCase();

    if (lowerText.includes('час')) {
        const hours = parseInt(text) || 1;
        return new Date(now - hours * 3600000);
    }
    if (lowerText.includes('день') || lowerText.includes('дня') || lowerText.includes('дней')) {
        const days = parseInt(text) || 1;
        return new Date(now - days * 86400000);
    }
    if (lowerText.includes('недел')) {
        const weeks = parseInt(text) || 1;
        return new Date(now - weeks * 604800000);
    }
    if (lowerText.includes('месяц')) {
        const months = parseInt(text) || 1;
        return new Date(now - months * 2592000000);
    }
    if (lowerText.includes('год') || lowerText.includes('лет')) {
        const years = parseInt(text) || 1;
        return new Date(now - years * 31536000000);
    }

    return null;
}

function formatNumber(num) {
    if (num >= 1000000) return (num / 1000000).toFixed(1) + ' млн';
    if (num >= 1000) return (num / 1000).toFixed(1) + ' тыс';
    return Math.floor(num).toLocaleString('ru-RU');
}

function formatTime(seconds) {
    const h = Math.floor(seconds / 3600);
    const m = Math.floor((seconds % 3600) / 60);
    const s = Math.floor(seconds % 60);
    if (h > 0) return `${h}ч ${m}м`;
    if (m > 0) return `${m}м ${s}с`;
    return `${s}с`;
}

function formatVideosPerWeek(num) {
    if (num < 0.5) return '< 1/мес';
    if (num < 1) return `${Math.round(num * 4)}/мес`;
    return `~${Math.round(num)}/нед`;
}

function getCountryFromAbout() {
    const metadataRenderer = document.querySelector('ytd-channel-about-metadata-renderer, ytd-about-channel-renderer');
    if (!metadataRenderer) return null;

    const rows = metadataRenderer.querySelectorAll('tr');
    for (const row of rows) {
        const cells = row.querySelectorAll('td');
        if (cells.length === 2) {
            const labelText = cells[0].textContent.trim().toLowerCase();
            if (labelText === 'location' || labelText === 'местоположение') {
                return cells[1].textContent.trim();
            }
        }
    }

    for (const row of rows) {
        const cells = row.querySelectorAll('td');
        if (cells.length === 2) {
            const potentialCountry = cells[1].textContent.trim();
            if (countryFlags.hasOwnProperty(potentialCountry)) {
                return potentialCountry;
            }
        }
    }

    return null;
}

function getVideosFromPage() {
    const videos = document.querySelectorAll('ytd-rich-item-renderer, ytd-grid-video-renderer');
    const data = [];

    videos.forEach(video => {
        if (video.querySelector('ytd-thumbnail-overlay-time-status-renderer[overlay-style="SHORTS"]')) {
            return;
        }

        const metadataLine = video.querySelector('#metadata-line');
        const durationEl = video.querySelector('ytd-thumbnail-overlay-time-status-renderer #text, ytd-thumbnail-overlay-time-status-renderer .yt-badge-shape__text');
        if (!metadataLine || !durationEl) return;

        const metaItems = metadataLine.querySelectorAll('span.inline-metadata-item');
        if (metaItems.length < 2) return;

        const viewsText = metaItems[0].textContent;
        const dateText = metaItems[1].textContent;
        const durationText = durationEl.textContent.trim();

        const parsedDate = parseRelativeDate(dateText);
        const parsedViews = parseViews(viewsText);
        const parsedDuration = parseDuration(durationText);

        if (parsedViews > 0 && parsedDate && parsedDuration > 0) {
            data.push({
                views: parsedViews,
                date: parsedDate,
                duration: parsedDuration
            });
        }
    });
    return data;
}

function getShortsFromPage() {
    const data = [];

    document.querySelectorAll('ytd-rich-item-renderer').forEach(item => {
        const viewsEl = item.querySelector('.shortsLockupViewModelHostOutsideMetadataSubhead .yt-core-attributed-string');
        if (viewsEl) {
            const parsedViews = parseViews(viewsEl.textContent);
            if (parsedViews > 0) {
                data.push({ views: parsedViews });
            }
        }
    });

    document.querySelectorAll('ytd-reel-item-renderer').forEach(item => {
        const viewsEl = item.querySelector('#video-info');
        if (viewsEl) {
            const parsedViews = parseViews(viewsEl.textContent);
            if (parsedViews > 0) {
                data.push({ views: parsedViews });
            }
        }
    });

    return data;
}

function getStreamsFromPage() {
    const streams = document.querySelectorAll('ytd-rich-item-renderer');
    const data = {
        liveNow: [],
        pastStreams: []
    };

    streams.forEach(stream => {
        const metadataLine = stream.querySelector('#metadata-line');
        if (!metadataLine) return;

        const metaItems = metadataLine.querySelectorAll('span.inline-metadata-item');
        const isLive = stream.querySelector('ytd-thumbnail-overlay-time-status-renderer[overlay-style="LIVE"]');

        if (isLive) {
            let viewers = 0;
            metaItems.forEach(item => {
                const text = item.textContent.trim();
                if (text.includes('Зрителей:')) {
                    viewers = parseInt(text.replace(/\D/g, '')) || 0;
                }
            });

            if (viewers > 0) {
                data.liveNow.push({ viewers });
            }
        } else {
            if (metaItems.length >= 2) {
                const viewsText = metaItems[0].textContent;
                const dateText = metaItems[1].textContent;

                if (dateText.includes('Трансляция закончилась')) {
                    const parsedViews = parseViews(viewsText);
                    const parsedDate = parseRelativeDate(dateText);

                    if (parsedViews > 0 && parsedDate) {
                        data.pastStreams.push({
                            views: parsedViews,
                            date: parsedDate
                        });
                    }
                }
            }
        }
    });

    return data;
}

function getLiveViewers() {
    const ariaLabel = document.querySelector('#view-count[aria-label]');
    if (ariaLabel) {
        const label = ariaLabel.getAttribute('aria-label');
        const match = label.match(/(\d+)/);
        if (match) {
            return parseInt(match[1]) || 0;
        }
    }

    const viewCountEl = document.querySelector('ytd-watch-info-text #view-count');
    if (!viewCountEl) return 0;

    const text = viewCountEl.textContent.trim();
    const match = text.match(/(\d+)/);
    if (match) {
        return parseInt(match[1]) || 0;
    }

    return 0;
}

function analyzeVideos(videosData) {
    if (!videosData || videosData.length === 0) {
        return {
            totalVideos: 0,
            totalViews: 0,
            avgViews: 0,
            avgDuration: 0,
            videosPerWeek: 0,
            mostActiveDay: 0,
            dayDistribution: [0, 0, 0, 0, 0, 0, 0],
            totalDays: 0,
            recentAvgViews: 0,
            oldAvgViews: 0,
            avgInterval: 0,
            shortVideos: 0,
            mediumVideos: 0,
            longVideos: 0,
            topViews: 0,
            lowViews: 0,
            viewsArray: [],
            viewsTrend: [],
            consistency: 0,
            growthRate: 0,
            volatility: 0,
            momentum: 0,
            daysSinceLastVideo: 0,
            channelHealth: 0
        };
    }

    let totalViews = 0;
    let totalDuration = 0;
    let count = 0;
    let dates = [];
    let dayDistribution = [0, 0, 0, 0, 0, 0, 0];
    let shortVideos = 0;
    let mediumVideos = 0;
    let longVideos = 0;
    let viewsArray = [];

    videosData.forEach(video => {
        if (video.views > 0) {
            totalViews += video.views;
            viewsArray.push(video.views);
            count++;
        }

        if (video.duration > 0) {
            totalDuration += video.duration;

            if (video.duration < 300) shortVideos++;
            else if (video.duration < 1200) mediumVideos++;
            else longVideos++;
        }

        if (video.date) {
            dates.push(video.date);
            dayDistribution[video.date.getDay()]++;
        }
    });

    viewsArray.sort((a, b) => b - a);
    dates.sort((a, b) => b - a);

    const halfCount = Math.floor(count / 2);
    const quarterCount = Math.floor(count / 4);
    let recentViews = 0;
    let oldViews = 0;
    let veryRecentViews = 0;

    for (let i = 0; i < count; i++) {
        if (i < quarterCount) veryRecentViews += viewsArray[i];
        if (i < halfCount) recentViews += viewsArray[i];
        else oldViews += viewsArray[i];
    }

    let videosPerWeek = 0;
    let avgInterval = 0;
    let daysSinceLastVideo = 0;

    if (dates.length > 1) {
        const oldestDate = dates[dates.length - 1];
        const newestDate = dates[0];
        const daysDiff = Math.max(1, (newestDate - oldestDate) / 86400000);
        const weeks = daysDiff / 7;
        videosPerWeek = weeks > 0 ? dates.length / weeks : 0;

        daysSinceLastVideo = Math.floor((new Date() - newestDate) / 86400000);

        let intervals = [];
        for (let i = 0; i < dates.length - 1; i++) {
            const interval = (dates[i] - dates[i + 1]) / 86400000;
            intervals.push(interval);
        }
        avgInterval = intervals.length > 0 ? intervals.reduce((a, b) => a + b, 0) / intervals.length : 0;
    } else if (dates.length === 1) {
        daysSinceLastVideo = Math.floor((new Date() - dates[0]) / 86400000);
    }

    const mostActiveDay = dayDistribution.indexOf(Math.max(...dayDistribution));
    const topViews = viewsArray.length > 0 ? viewsArray[0] : 0;
    const lowViews = viewsArray.length > 0 ? viewsArray[viewsArray.length - 1] : 0;

    const avgViews = count > 0 ? totalViews / count : 0;
    const stdDev = count > 0 ? Math.sqrt(viewsArray.reduce((sum, v) => sum + Math.pow(v - avgViews, 2), 0) / count) : 0;
    const consistency = avgViews > 0 ? (1 - (stdDev / avgViews)) * 100 : 0;

    const recentAvg = halfCount > 0 ? recentViews / halfCount : 0;
    const oldAvg = (count - halfCount) > 0 ? oldViews / (count - halfCount) : 0;
    const veryRecentAvg = quarterCount > 0 ? veryRecentViews / quarterCount : 0;

    let growthRate = oldAvg > 0 ? ((recentAvg - oldAvg) / oldAvg) * 100 : 0;
    const momentum = recentAvg > 0 ? ((veryRecentAvg - recentAvg) / recentAvg) * 100 : 0;
    const volatility = avgViews > 0 ? (stdDev / avgViews) * 100 : 0;

    if (daysSinceLastVideo > 60) {
        growthRate -= 30;
    } else if (daysSinceLastVideo > 30) {
        growthRate -= 15;
    } else if (daysSinceLastVideo > 14) {
        growthRate -= 5;
    }

    if (videosPerWeek < 0.3) {
        growthRate -= 20;
    } else if (videosPerWeek < 0.5) {
        growthRate -= 10;
    }

    const viewsTrend = viewsArray.slice(0, Math.min(30, viewsArray.length)).reverse();

    let channelHealth = 50;
    if (consistency > 60) channelHealth += 15;
    else if (consistency < 30) channelHealth -= 15;

    if (growthRate > 20) channelHealth += 20;
    else if (growthRate < -20) channelHealth -= 20;

    if (videosPerWeek >= 2) channelHealth += 15;
    else if (videosPerWeek < 0.5) channelHealth -= 15;

    if (daysSinceLastVideo > 30) channelHealth -= 20;

    channelHealth = Math.max(0, Math.min(100, channelHealth));

    return {
        totalVideos: count,
        totalViews,
        avgViews,
        avgDuration: count > 0 ? totalDuration / count : 0,
        videosPerWeek,
        mostActiveDay,
        dayDistribution,
        totalDays: dates.length > 1 ? (dates[0] - dates[dates.length - 1]) / 86400000 : 0,
        recentAvgViews: recentAvg,
        oldAvgViews: oldAvg,
        avgInterval,
        shortVideos,
        mediumVideos,
        longVideos,
        topViews,
        lowViews,
        viewsArray,
        viewsTrend,
        consistency: Math.max(0, Math.min(100, consistency)),
        growthRate,
        volatility,
        momentum,
        daysSinceLastVideo,
        channelHealth
    };
}

function analyzeShortsData(shortsData) {
    if (!shortsData || shortsData.length === 0) {
        return {
            totalShorts: 0,
            totalViews: 0,
            avgViews: 0,
            topViews: 0,
            lowViews: 0,
            viewsArray: [],
            consistency: 0,
            volatility: 0
        };
    }

    let totalViews = 0;
    let count = 0;
    let viewsArray = [];

    shortsData.forEach(short => {
        if (short.views > 0) {
            totalViews += short.views;
            viewsArray.push(short.views);
            count++;
        }
    });

    viewsArray.sort((a, b) => b - a);

    const avgViews = count > 0 ? totalViews / count : 0;
    const stdDev = count > 0 ? Math.sqrt(viewsArray.reduce((sum, v) => sum + Math.pow(v - avgViews, 2), 0) / count) : 0;
    const consistency = avgViews > 0 ? (1 - (stdDev / avgViews)) * 100 : 0;
    const volatility = avgViews > 0 ? (stdDev / avgViews) * 100 : 0;

    return {
        totalShorts: count,
        totalViews,
        avgViews,
        topViews: viewsArray.length > 0 ? viewsArray[0] : 0,
        lowViews: viewsArray.length > 0 ? viewsArray[viewsArray.length - 1] : 0,
        viewsArray,
        consistency: Math.max(0, Math.min(100, consistency)),
        volatility
    };
}

function analyzeStreamsData(streamsData) {
    const stats = {
        liveCount: streamsData.liveNow.length,
        currentViewers: 0,
        pastStreamsCount: streamsData.pastStreams.length,
        avgViews: 0,
        totalViews: 0,
        topViews: 0,
        lowViews: 0
    };

    if (streamsData.liveNow.length > 0) {
        stats.currentViewers = streamsData.liveNow.reduce((sum, s) => sum + s.viewers, 0);
    }

    if (streamsData.pastStreams.length > 0) {
        const views = streamsData.pastStreams.map(s => s.views);
        stats.totalViews = views.reduce((sum, v) => sum + v, 0);
        stats.avgViews = stats.totalViews / views.length;
        stats.topViews = Math.max(...views);
        stats.lowViews = Math.min(...views);
    }

    return stats;
}

function createStatCardElement(label, value, icon) {
    const card = createElement('div', 'lumo-stat-card');
    const labelEl = createElement('div', 'lumo-stat-label', label);
    const valueEl = createElement('div', 'lumo-stat-value');
    const iconEl = createElement('span', 'lumo-stat-icon', icon);
    const textEl = createElement('span', '', value);

    valueEl.appendChild(iconEl);
    valueEl.appendChild(textEl);
    card.appendChild(labelEl);
    card.appendChild(valueEl);

    return card;
}

function createDetailCardElement(title, value, subtitle) {
    const card = createElement('div', 'lumo-detail-card');
    const titleEl = createElement('div', 'lumo-detail-card-title', title);
    const valueEl = createElement('div', 'lumo-detail-card-value', value);
    const subEl = createElement('div', 'lumo-detail-card-subtitle', subtitle);

    card.appendChild(titleEl);
    card.appendChild(valueEl);
    card.appendChild(subEl);

    return card;
}

function createCountryCard(country) {
    const card = createElement('div', 'lumo-detail-card');
    const titleEl = createElement('div', 'lumo-detail-card-title', 'Страна');
    const info = createElement('div', 'lumo-country-info');
    const flag = document.createElement('img');
    flag.className = 'lumo-country-flag';
    flag.src = countryFlags[country] || 'https://flagcdn.com/w80/ru.png';
    flag.onerror = () => flag.style.display = 'none';
    const name = createElement('span', 'lumo-country-name', country);

    info.appendChild(flag);
    info.appendChild(name);
    card.appendChild(titleEl);
    card.appendChild(info);

    return card;
}

function drawLineChart(canvas, data, color = '#ff0000') {
    if (!canvas || !data || data.length === 0) return;

    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    const dpr = window.devicePixelRatio || 1;
    const rect = canvas.getBoundingClientRect();

    canvas.width = rect.width * dpr;
    canvas.height = rect.height * dpr;
    ctx.scale(dpr, dpr);

    const width = rect.width;
    const height = rect.height;
    const padding = 40;

    ctx.clearRect(0, 0, width, height);

    if (data.length === 1) {
        const value = data[0];
        ctx.fillStyle = color;
        ctx.font = 'bold 24px Roboto';
        ctx.textAlign = 'center';
        ctx.fillText(formatNumber(value), width / 2, height / 2);
        return;
    }

    const max = Math.max(...data);
    const min = Math.min(...data);
    const range = max - min || 1;

    const stepX = (width - padding * 2) / (data.length - 1);
    const stepY = (height - padding * 2) / range;

    ctx.strokeStyle = '#303030';
    ctx.lineWidth = 1;
    for (let i = 0; i <= 5; i++) {
        const y = padding + (height - padding * 2) * i / 5;
        ctx.beginPath();
        ctx.moveTo(padding, y);
        ctx.lineTo(width - padding, y);
        ctx.stroke();
    }

    ctx.strokeStyle = '#303030';
    const xSteps = Math.min(10, data.length);
    for (let i = 0; i < data.length; i += Math.max(1, Math.floor(data.length / xSteps))) {
        const x = padding + i * stepX;
        ctx.beginPath();
        ctx.moveTo(x, padding);
        ctx.lineTo(x, height - padding);
        ctx.stroke();
    }

    const gradient = ctx.createLinearGradient(0, padding, 0, height - padding);
    gradient.addColorStop(0, color);
    gradient.addColorStop(1, color + 'CC');

    ctx.beginPath();
    data.forEach((value, index) => {
        const x = padding + index * stepX;
        const y = height - padding - (value - min) * stepY;

        if (index === 0) ctx.moveTo(x, y);
        else ctx.lineTo(x, y);
    });
    ctx.strokeStyle = gradient;
    ctx.lineWidth = 3;
    ctx.lineCap = 'round';
    ctx.lineJoin = 'round';
    ctx.stroke();

    ctx.lineTo(width - padding, height - padding);
    ctx.lineTo(padding, height - padding);
    ctx.closePath();

    const fillGradient = ctx.createLinearGradient(0, padding, 0, height - padding);
    fillGradient.addColorStop(0, color + '40');
    fillGradient.addColorStop(1, color + '08');
    ctx.fillStyle = fillGradient;
    ctx.fill();

    data.forEach((value, index) => {
        const x = padding + index * stepX;
        const y = height - padding - (value - min) * stepY;

        ctx.beginPath();
        ctx.arc(x, y, 6, 0, Math.PI * 2);
        ctx.fillStyle = color;
        ctx.fill();
        ctx.strokeStyle = '#0f0f0f';
        ctx.lineWidth = 2;
        ctx.stroke();
    });

    chartData = { data, padding, stepX, stepY, min, height, width };
}

function setupChartTooltip(canvas, wrapper) {
    const tooltip = createElement('div', 'lumo-chart-tooltip');
    document.body.appendChild(tooltip);

    canvas.addEventListener('mousemove', (e) => {
        if (!chartData) return;

        const rect = canvas.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const y = e.clientY - rect.top;

        const { data, padding, stepX, stepY, min, height } = chartData;

        let closestIndex = -1;
        let closestDistance = Infinity;

        data.forEach((value, index) => {
            const pointX = padding + index * stepX;
            const pointY = height - padding - (value - min) * stepY;
            const distance = Math.sqrt(Math.pow(x - pointX, 2) + Math.pow(y - pointY, 2));

            if (distance < closestDistance && distance < 25) {
                closestDistance = distance;
                closestIndex = index;
            }
        });

        if (closestIndex !== -1) {
            const value = data[closestIndex];
            let label;
            if (currentMode === 'videos') {
                label = `Видео ${data.length - closestIndex}`;
            } else if (currentMode === 'shorts') {
                label = `Shorts ${data.length - closestIndex}`;
            } else if (currentMode === 'live') {
                const timeAgo = (data.length - closestIndex) * 3;
                label = `${timeAgo} сек назад`;
            } else {
                label = `Точка ${closestIndex + 1}`;
            }

            tooltip.textContent = '';
            const labelDiv = createElement('div', 'lumo-chart-tooltip-label', label);
            const valueDiv = createElement('div', 'lumo-chart-tooltip-value', currentMode === 'live' ? `${value} зрителей` : `${formatNumber(value)} просмотров`);
            tooltip.appendChild(labelDiv);
            tooltip.appendChild(valueDiv);

            let tooltipX = e.clientX + 15;
            let tooltipY = e.clientY - 45;

            const tooltipRect = tooltip.getBoundingClientRect();
            const viewportWidth = window.innerWidth;
            const viewportHeight = window.innerHeight;

            if (tooltipX + tooltipRect.width > viewportWidth - 10) {
                tooltipX = e.clientX - tooltipRect.width - 15;
            }

            if (tooltipY < 10) {
                tooltipY = e.clientY + 15;
            }

            if (tooltipY + tooltipRect.height > viewportHeight - 10) {
                tooltipY = viewportHeight - tooltipRect.height - 10;
            }

            tooltip.style.left = tooltipX + 'px';
            tooltip.style.top = tooltipY + 'px';
            tooltip.classList.add('visible');
        } else {
            tooltip.classList.remove('visible');
        }
    });

    canvas.addEventListener('mouseleave', () => {
        tooltip.classList.remove('visible');
    });
}

function getDetailedTrendStatus(stats) {
    const { growthRate, consistency, momentum, volatility, videosPerWeek, avgInterval, daysSinceLastVideo } = stats;

    const stabilityBonus = consistency > 60 ? 1.25 : consistency < 30 ? 0.75 : 1;
    let adjustedGrowth = growthRate * stabilityBonus;

    const isAbandoned = daysSinceLastVideo > 90;
    const isInactive = daysSinceLastVideo > 45 || videosPerWeek < 0.3;
    const isLowActivity = videosPerWeek < 0.8 && !isInactive;

    if (isAbandoned) {
        return {
            status: 'critical-decline',
            icon: '💀',
            text: 'Канал заброшен',
            desc: 'Очень давно не было публикаций, канал неактивен',
            level: 0
        };
    }

    if (isInactive && avgInterval > 40) {
        return {
            status: 'stagnant',
            icon: '⏸',
            text: 'Застой',
            desc: 'Канал публикует редко, активность на низком уровне',
            level: 1
        };
    }

    if (isLowActivity && adjustedGrowth < 5) {
        adjustedGrowth *= 0.6;
    }

    if (adjustedGrowth > 120 && momentum > 40 && videosPerWeek >= 2) {
        return {
            status: 'explosive-growth',
            icon: '🚀',
            text: 'Взрывной рост',
            desc: 'Невероятная динамика! Канал стремительно набирает обороты',
            level: 10
        };
    } else if (adjustedGrowth > 70 && consistency > 55 && videosPerWeek >= 1.5) {
        return {
            status: 'strong-growth',
            icon: '📈',
            text: 'Сильный рост',
            desc: 'Канал активно развивается со стабильными показателями',
            level: 9
        };
    } else if (adjustedGrowth > 45 && videosPerWeek >= 1) {
        return {
            status: 'strong-growth',
            icon: '📊',
            text: 'Активный рост',
            desc: 'Отличная положительная динамика развития канала',
            level: 8
        };
    } else if (adjustedGrowth > 25) {
        return {
            status: 'moderate-growth',
            icon: '↗',
            text: 'Умеренный рост',
            desc: 'Стабильное развитие с хорошими показателями',
            level: 7
        };
    } else if (adjustedGrowth > 12) {
        return {
            status: 'moderate-growth',
            icon: '↗',
            text: 'Рост выше среднего',
            desc: 'Канал растет, показатели постепенно улучшаются',
            level: 6
        };
    } else if (adjustedGrowth > 3) {
        return {
            status: 'slight-growth',
            icon: '→',
            text: 'Небольшой рост',
            desc: 'Слабая положительная динамика, рост медленный',
            level: 5
        };
    } else if (adjustedGrowth >= -8) {
        return {
            status: 'stable',
            icon: '━',
            text: 'Стабильно',
            desc: 'Показатели держатся примерно на одном уровне',
            level: 4
        };
    } else if (adjustedGrowth >= -20) {
        return {
            status: 'slight-decline',
            icon: '↘',
            text: 'Небольшое снижение',
            desc: 'Показатели немного падают, требуется внимание',
            level: 3
        };
    } else if (adjustedGrowth >= -40) {
        return {
            status: 'moderate-decline',
            icon: '📉',
            text: 'Умеренный спад',
            desc: 'Заметное снижение показателей, нужны изменения',
            level: 2
        };
    } else if (adjustedGrowth >= -65) {
        return {
            status: 'strong-decline',
            icon: '⬇',
            text: 'Сильный спад',
            desc: 'Серьезное падение популярности канала',
            level: 1
        };
    } else {
        return {
            status: 'critical-decline',
            icon: '⚠',
            text: 'Критический спад',
            desc: 'Катастрофическое падение показателей',
            level: 0
        };
    }
}

function getPerformanceScore(value, thresholds) {
    if (value >= thresholds.excellent) return { score: 'A+', class: 'excellent', percent: 100 };
    if (value >= thresholds.good) return { score: 'A', class: 'good', percent: 88 };
    if (value >= thresholds.average) return { score: 'B', class: 'average', percent: 72 };
    if (value >= thresholds.poor) return { score: 'C', class: 'poor', percent: 55 };
    return { score: 'D', class: 'bad', percent: 35 };
}

function createHealthIndicator(health) {
    const indicator = createElement('div', 'lumo-health-indicator');
    const title = createElement('div', 'lumo-health-title', 'Здоровье канала');
    const bar = createElement('div', 'lumo-health-bar');
    const fill = createElement('div', 'lumo-health-fill');

    let color;
    let statusText;
    if (health >= 80) {
        color = '#00ff88';
        statusText = 'Отличное';
    } else if (health >= 60) {
        color = '#66ffaa';
        statusText = 'Хорошее';
    } else if (health >= 40) {
        color = '#ffbb33';
        statusText = 'Среднее';
    } else if (health >= 20) {
        color = '#ff9966';
        statusText = 'Слабое';
    } else {
        color = '#ff4444';
        statusText = 'Критическое';
    }

    fill.style.background = `linear-gradient(90deg, ${color}, ${color}CC)`;
    fill.style.width = '0%';

    bar.appendChild(fill);

    const label = createElement('div', 'lumo-health-label', `${statusText} • ${health}%`);

    indicator.appendChild(title);
    indicator.appendChild(bar);
    indicator.appendChild(label);

    requestAnimationFrame(() => {
        fill.style.width = health + '%';
    });

    return indicator;
}

function createPredictionCard(stats) {
    const card = createElement('div', 'lumo-prediction-card');
    const title = createElement('div', 'lumo-prediction-title', 'Прогноз');
    const content = createElement('div', 'lumo-prediction-content');

    let icon, text;

    if (stats.daysSinceLastVideo > 60) {
        icon = '⏰';
        text = 'Канал давно не публикует. Рекомендуется возобновить активность в ближайшее время.';
    } else if (stats.avgInterval > 0 && stats.avgInterval < 30) {
        const nextDays = Math.round(stats.avgInterval);
        icon = '📅';
        text = `Следующее видео ожидается примерно через ${nextDays} ${nextDays === 1 ? 'день' : nextDays < 5 ? 'дня' : 'дней'}.`;
    } else if (stats.momentum > 20) {
        icon = '⚡';
        text = 'Канал набирает обороты! Продолжайте в том же духе для максимального роста.';
    } else if (stats.growthRate < -20) {
        icon = '💡';
        text = 'Показатели падают. Рекомендуется пересмотреть контент-стратегию.';
    } else if (stats.consistency > 70) {
        icon = '✨';
        text = 'Отличная стабильность! Аудитория знает, чего ожидать от канала.';
    } else {
        icon = '📊';
        text = 'Стабильное развитие. Для роста рекомендуется увеличить частоту публикаций.';
    }

    const iconEl = createElement('div', 'lumo-prediction-icon', icon);
    const textEl = createElement('div', 'lumo-prediction-text', text);

    content.appendChild(iconEl);
    content.appendChild(textEl);
    card.appendChild(title);
    card.appendChild(content);

    return card;
}

function createModal() {
    const modal = createElement('div', 'lumo-modal');
    const content = createElement('div', 'lumo-modal-content');

    const header = createElement('div', 'lumo-modal-header');
    const title = createElement('div', 'lumo-modal-title', '▣ Подробная аналитика');
    const closeBtn = createElement('button', 'lumo-modal-close', '✕');

    closeBtn.addEventListener('click', () => modal.classList.remove('active'));

    header.appendChild(title);
    header.appendChild(closeBtn);

    const tabs = createElement('div', 'lumo-tabs');

    let tabData = [];
    if (currentMode === 'videos') {
        tabData = [
            { name: 'overview', label: 'Обзор' },
            { name: 'trends', label: 'Тренды' },
            { name: 'frequency', label: 'Частота' },
            { name: 'days', label: 'Дни недели' },
            { name: 'compare', label: 'Сравнение' },
            { name: 'performance', label: 'Оценка' }
        ];
    } else if (currentMode === 'shorts') {
        tabData = [
            { name: 'overview', label: 'Обзор' },
            { name: 'trends', label: 'Тренды' }
        ];
    } else if (currentMode === 'streams') {
        tabData = [
            { name: 'overview', label: 'Обзор' },
            { name: 'live', label: 'Текущие' }
        ];
    }

    const tabContents = {};

    tabData.forEach((tab, index) => {
        const button = createElement('button', index === 0 ? 'lumo-tab active' : 'lumo-tab', tab.label);
        button.dataset.tab = tab.name;
        tabs.appendChild(button);

        const tabContent = createElement('div', index === 0 ? 'lumo-tab-content active' : 'lumo-tab-content');
        tabContent.dataset.content = tab.name;
        tabContents[tab.name] = tabContent;
    });

    content.appendChild(header);
    content.appendChild(tabs);

    Object.values(tabContents).forEach(tc => content.appendChild(tc));

    const author = createElement('div', 'lumo-author', 'Created by lumo');
    content.appendChild(author);

    modal.appendChild(content);
    document.body.appendChild(modal);

    modal.addEventListener('click', (e) => {
        if (e.target === modal) modal.classList.remove('active');
    });

    tabs.querySelectorAll('.lumo-tab').forEach(tab => {
        tab.addEventListener('click', () => {
            const tabName = tab.dataset.tab;
            modal.querySelectorAll('.lumo-tab').forEach(t => t.classList.remove('active'));
            modal.querySelectorAll('.lumo-tab-content').forEach(c => c.classList.remove('active'));
            tab.classList.add('active');
            modal.querySelector(`[data-content="${tabName}"]`).classList.add('active');
        });
    });

    return modal;
}

function forceYouTubeResize() {
    window.dispatchEvent(new Event('resize'));
    requestAnimationFrame(() => {
        window.dispatchEvent(new Event('resize'));
    });

    const ytdApp = document.querySelector('ytd-app');
    if (ytdApp && ytdApp.__dataHost) {
        ytdApp.__dataHost.notifyResize();
    }
}

async function showDetailedStats() {
    if (isAnalyzing) return;
    isAnalyzing = true;

    let modal = document.querySelector('.lumo-modal');
    if (!modal) {
        modal = createModal();
    }

    let stats, data;

    if (currentMode === 'videos') {
        data = getVideosFromPage();
        stats = analyzeVideos(data);
    } else if (currentMode === 'shorts') {
        data = getShortsFromPage();
        stats = analyzeShortsData(data);
    } else if (currentMode === 'streams') {
        data = getStreamsFromPage();
        stats = analyzeStreamsData(data);
    }

    const country = getCountryFromAbout();

    const overviewContent = modal.querySelector('[data-content="overview"]');
    const trendsContent = modal.querySelector('[data-content="trends"]');
    const frequencyContent = modal.querySelector('[data-content="frequency"]');
    const daysContent = modal.querySelector('[data-content="days"]');
    const compareContent = modal.querySelector('[data-content="compare"]');
    const performanceContent = modal.querySelector('[data-content="performance"]');

    if (overviewContent) {
        overviewContent.textContent = '';

        if (currentMode === 'videos' && stats.channelHealth !== undefined) {
            overviewContent.appendChild(createHealthIndicator(stats.channelHealth));
            overviewContent.appendChild(createPredictionCard(stats));
        }

        const overviewGrid = createElement('div', 'lumo-detail-grid');

        if (currentMode === 'videos') {
            overviewGrid.appendChild(createDetailCardElement('Средние просмотры', formatNumber(stats.avgViews), 'на видео'));
            overviewGrid.appendChild(createDetailCardElement('Всего просмотров', formatNumber(stats.totalViews), 'на странице'));
            overviewGrid.appendChild(createDetailCardElement('Средняя длительность', formatTime(stats.avgDuration), 'видео'));
            overviewGrid.appendChild(createDetailCardElement('Частота', formatVideosPerWeek(stats.videosPerWeek), 'публикаций'));
            overviewGrid.appendChild(createDetailCardElement('Топ видео', formatNumber(stats.topViews), 'просмотров'));
            overviewGrid.appendChild(createDetailCardElement('Низ видео', formatNumber(stats.lowViews), 'просмотров'));
        } else if (currentMode === 'shorts') {
            overviewGrid.appendChild(createDetailCardElement('Всего Shorts', stats.totalShorts.toString(), 'на странице'));
            overviewGrid.appendChild(createDetailCardElement('Средние просмотры', formatNumber(stats.avgViews), 'на shorts'));
            overviewGrid.appendChild(createDetailCardElement('Всего просмотров', formatNumber(stats.totalViews), 'общие'));
            overviewGrid.appendChild(createDetailCardElement('Топ Shorts', formatNumber(stats.topViews), 'просмотров'));
            overviewGrid.appendChild(createDetailCardElement('Низ Shorts', formatNumber(stats.lowViews), 'просмотров'));
            overviewGrid.appendChild(createDetailCardElement('Стабильность', stats.consistency.toFixed(0) + '%', 'консистентность'));
        } else if (currentMode === 'streams') {
            overviewGrid.appendChild(createDetailCardElement('Активные стримы', stats.liveCount.toString(), 'сейчас в эфире'));
            overviewGrid.appendChild(createDetailCardElement('Текущие зрители', stats.currentViewers.toString(), 'смотрят сейчас'));
            overviewGrid.appendChild(createDetailCardElement('Прошлых стримов', stats.pastStreamsCount.toString(), 'записей'));
            if (stats.pastStreamsCount > 0) {
                overviewGrid.appendChild(createDetailCardElement('Средние просмотры', formatNumber(stats.avgViews), 'на стрим'));
                overviewGrid.appendChild(createDetailCardElement('Топ стрим', formatNumber(stats.topViews), 'просмотров'));
            }
        }

        if (country) {
            overviewGrid.appendChild(createCountryCard(country));
        }
        overviewContent.appendChild(overviewGrid);
    }

    if (trendsContent) {
        trendsContent.textContent = '';

        if (currentMode === 'videos') {
            const trendInfo = getDetailedTrendStatus(stats);
            const trendIndicator = createElement('div', `lumo-trend-indicator ${trendInfo.status}`);
            const trendIcon = createElement('div', 'lumo-trend-icon', trendInfo.icon);
            const trendInfoDiv = createElement('div', 'lumo-trend-info');
            const trendStatus = createElement('div', `lumo-trend-status lumo-trend-${trendInfo.status.includes('growth') ? 'up' : trendInfo.status.includes('decline') || trendInfo.status === 'stagnant' ? 'down' : 'stable'}`, trendInfo.text);
            const trendDesc = createElement('div', 'lumo-trend-desc', trendInfo.desc);

            trendInfoDiv.appendChild(trendStatus);
            trendInfoDiv.appendChild(trendDesc);
            trendIndicator.appendChild(trendIcon);
            trendIndicator.appendChild(trendInfoDiv);
            trendsContent.appendChild(trendIndicator);

            const metricsRow = createElement('div', 'lumo-metrics-row');

            const growthCard = createElement('div', `lumo-metric-card ${stats.growthRate > 10 ? 'positive' : stats.growthRate < -10 ? 'negative' : 'neutral'}`);
            const growthLabel = createElement('div', 'lumo-metric-label', 'Динамика роста');
            const growthValue = createElement('div', `lumo-metric-value lumo-trend-${stats.growthRate > 0 ? 'up' : stats.growthRate < 0 ? 'down' : 'stable'}`, `${stats.growthRate > 0 ? '+' : ''}${stats.growthRate.toFixed(1)}%`);
            const growthChange = createElement('div', 'lumo-metric-change', stats.growthRate > 0 ? '↗ Новые видео лучше старых' : stats.growthRate < 0 ? '↘ Новые видео хуже старых' : '━ Стабильные показатели');
            growthCard.appendChild(growthLabel);
            growthCard.appendChild(growthValue);
            growthCard.appendChild(growthChange);

            const consistencyCard = createElement('div', `lumo-metric-card ${stats.consistency > 60 ? 'positive' : stats.consistency < 30 ? 'negative' : 'neutral'}`);
            const consistencyLabel = createElement('div', 'lumo-metric-label', 'Стабильность');
            const consistencyValue = createElement('div', `lumo-metric-value lumo-trend-${stats.consistency > 60 ? 'up' : stats.consistency < 30 ? 'down' : 'stable'}`, `${stats.consistency.toFixed(0)}%`);
            const consistencyChange = createElement('div', 'lumo-metric-change', stats.consistency > 60 ? '✓ Стабильный контент' : stats.consistency < 30 ? '⚠ Нестабильные просмотры' : '~ Средняя стабильность');
            consistencyCard.appendChild(consistencyLabel);
            consistencyCard.appendChild(consistencyValue);
            consistencyCard.appendChild(consistencyChange);

            const momentumCard = createElement('div', `lumo-metric-card ${stats.momentum > 10 ? 'positive' : stats.momentum < -10 ? 'negative' : 'neutral'}`);
            const momentumLabel = createElement('div', 'lumo-metric-label', 'Импульс');
            const momentumValue = createElement('div', `lumo-metric-value lumo-trend-${stats.momentum > 0 ? 'up' : stats.momentum < 0 ? 'down' : 'stable'}`, `${stats.momentum > 0 ? '+' : ''}${stats.momentum.toFixed(1)}%`);
            const momentumChange = createElement('div', 'lumo-metric-change', stats.momentum > 0 ? '↗ Ускорение роста' : stats.momentum < 0 ? '↘ Замедление' : '━ Равномерно');
            momentumCard.appendChild(momentumLabel);
            momentumCard.appendChild(momentumValue);
            momentumCard.appendChild(momentumChange);

            metricsRow.appendChild(growthCard);
            metricsRow.appendChild(consistencyCard);
            metricsRow.appendChild(momentumCard);
            trendsContent.appendChild(metricsRow);

            if (stats.viewsTrend && stats.viewsTrend.length > 0) {
                const wrapper = createElement('div', 'lumo-chart-wrapper');
                const canvas = document.createElement('canvas');
                canvas.className = 'lumo-chart-canvas';
                wrapper.appendChild(canvas);
                trendsContent.appendChild(wrapper);

                requestAnimationFrame(() => {
                    const trendLevel = trendInfo.level;
                    let color;
                    if (trendLevel >= 8) color = '#00ff88';
                    else if (trendLevel >= 6) color = '#66ffaa';
                    else if (trendLevel >= 5) color = '#99ffbb';
                    else if (trendLevel === 4) color = '#ffbb33';
                    else if (trendLevel === 3) color = '#ffaa99';
                    else if (trendLevel >= 1) color = '#ff6666';
                    else color = '#999999';

                    drawLineChart(canvas, stats.viewsTrend, color);
                    setupChartTooltip(canvas, wrapper);
                });
            }

            const detailGrid = createElement('div', 'lumo-detail-grid');
            detailGrid.appendChild(createDetailCardElement('Новые видео', formatNumber(stats.recentAvgViews), 'средние просмотры'));
            detailGrid.appendChild(createDetailCardElement('Старые видео', formatNumber(stats.oldAvgViews), 'средние просмотры'));
            detailGrid.appendChild(createDetailCardElement('Топ видео', formatNumber(stats.topViews), 'максимум просмотров'));
            detailGrid.appendChild(createDetailCardElement('Волатильность', stats.volatility.toFixed(1) + '%', 'изменчивость'));
            trendsContent.appendChild(detailGrid);
        } else if (currentMode === 'shorts') {
            if (stats.viewsArray && stats.viewsArray.length > 0) {
                const wrapper = createElement('div', 'lumo-chart-wrapper');
                const canvas = document.createElement('canvas');
                canvas.className = 'lumo-chart-canvas';
                wrapper.appendChild(canvas);
                trendsContent.appendChild(wrapper);

                requestAnimationFrame(() => {
                    const trendData = stats.viewsArray.slice(0, 30).reverse();
                    drawLineChart(canvas, trendData, '#ff4444');
                    setupChartTooltip(canvas, wrapper);
                });
            }

            const detailGrid = createElement('div', 'lumo-detail-grid');
            detailGrid.appendChild(createDetailCardElement('Всего Shorts', stats.totalShorts.toString(), 'на странице'));
            detailGrid.appendChild(createDetailCardElement('Средние просмотры', formatNumber(stats.avgViews), 'на shorts'));
            detailGrid.appendChild(createDetailCardElement('Топ Shorts', formatNumber(stats.topViews), 'максимум'));
            detailGrid.appendChild(createDetailCardElement('Низ Shorts', formatNumber(stats.lowViews), 'минимум'));
            trendsContent.appendChild(detailGrid);
        }
    }

    if (frequencyContent) {
        frequencyContent.textContent = '';
        if (currentMode === 'videos') {
            const frequencyGrid = createElement('div', 'lumo-detail-grid');
            frequencyGrid.appendChild(createDetailCardElement('Частота', formatVideosPerWeek(stats.videosPerWeek), 'публикаций'));
            frequencyGrid.appendChild(createDetailCardElement('Интервал', stats.avgInterval.toFixed(1), 'дней между видео'));
            frequencyGrid.appendChild(createDetailCardElement('Период анализа', Math.floor(stats.totalDays).toString(), 'дней'));
            frequencyGrid.appendChild(createDetailCardElement('Короткие', stats.shortVideos.toString(), '< 5 минут'));
            frequencyGrid.appendChild(createDetailCardElement('Средние', stats.mediumVideos.toString(), '5-20 минут'));
            frequencyGrid.appendChild(createDetailCardElement('Длинные', stats.longVideos.toString(), '> 20 минут'));
            frequencyContent.appendChild(frequencyGrid);
        }
    }

    if (daysContent) {
        daysContent.textContent = '';
        if (currentMode === 'videos' && stats.dayDistribution) {
            const maxCount = Math.max(...stats.dayDistribution);
            const dayDist = createElement('div', 'lumo-day-distribution');
            stats.dayDistribution.forEach((count, index) => {
                const isActive = index === stats.mostActiveDay && maxCount > 0;
                const dayItem = createElement('div', isActive ? 'lumo-day-item active' : 'lumo-day-item');
                const dayNameEl = createElement('div', 'lumo-day-name', dayNames[index]);
                const dayCountEl = createElement('div', 'lumo-day-count', count.toString());
                dayItem.appendChild(dayNameEl);
                dayItem.appendChild(dayCountEl);
                dayDist.appendChild(dayItem);
            });
            daysContent.appendChild(dayDist);

            const chartsContainer = document.createElement('div');
            chartsContainer.style.marginTop = '24px';
            stats.dayDistribution.forEach((count, index) => {
                const percentage = maxCount > 0 ? (count / maxCount) * 100 : 0;
                const bar = createElement('div', 'lumo-chart-bar');
                const label = createElement('div', 'lumo-chart-label');
                const labelName = createElement('span', '', dayNames[index]);
                const labelCount = createElement('span', '', `${count} видео`);
                label.appendChild(labelName);
                label.appendChild(labelCount);

                const bg = createElement('div', 'lumo-chart-bar-bg');
                const fill = createElement('div', 'lumo-chart-bar-fill');
                fill.style.width = '0%';

                bg.appendChild(fill);
                bar.appendChild(label);
                bar.appendChild(bg);
                chartsContainer.appendChild(bar);

                requestAnimationFrame(() => {
                    setTimeout(() => {
                        fill.style.width = percentage + '%';
                    }, index * 50);
                });
            });
            daysContent.appendChild(chartsContainer);
        }
    }

    if (compareContent) {
        compareContent.textContent = '';
        if (currentMode === 'videos') {
            const compareSection = createElement('div', 'lumo-compare-section');
            const compareTitle = createElement('div', 'lumo-compare-title', 'Сравнение периодов');
            const compareGrid = createElement('div', 'lumo-compare-grid');

            const recentColumn = createElement('div', 'lumo-compare-column');
            const recentTitle = createElement('div', 'lumo-compare-column-title', 'Новые видео');
            const recentValue = createElement('div', 'lumo-compare-value', formatNumber(stats.recentAvgViews));
            const diff = stats.recentAvgViews - stats.oldAvgViews;
            const diffPercent = stats.oldAvgViews > 0 ? ((diff / stats.oldAvgViews) * 100).toFixed(1) : 0;
            const recentDiff = createElement('div', `lumo-compare-diff ${diff >= 0 ? 'positive' : 'negative'}`,
                `${diff >= 0 ? '+' : ''}${diffPercent}%`);
            recentColumn.appendChild(recentTitle);
            recentColumn.appendChild(recentValue);
            recentColumn.appendChild(recentDiff);

            const oldColumn = createElement('div', 'lumo-compare-column');
            const oldTitle = createElement('div', 'lumo-compare-column-title', 'Старые видео');
            const oldValue = createElement('div', 'lumo-compare-value', formatNumber(stats.oldAvgViews));
            const oldDiff = createElement('div', 'lumo-compare-diff', 'Базовый уровень');
            oldColumn.appendChild(oldTitle);
            oldColumn.appendChild(oldValue);
            oldColumn.appendChild(oldDiff);

            compareGrid.appendChild(recentColumn);
            compareGrid.appendChild(oldColumn);
            compareSection.appendChild(compareTitle);
            compareSection.appendChild(compareGrid);
            compareContent.appendChild(compareSection);

            const detailsGrid = createElement('div', 'lumo-detail-grid');
            detailsGrid.appendChild(createDetailCardElement('Разница', formatNumber(Math.abs(diff)), diff >= 0 ? 'прирост' : 'снижение'));
            detailsGrid.appendChild(createDetailCardElement('Рост', `${diff >= 0 ? '+' : ''}${diffPercent}%`, 'в процентах'));
            detailsGrid.appendChild(createDetailCardElement('Топ видео', formatNumber(stats.topViews), 'лучший результат'));
            detailsGrid.appendChild(createDetailCardElement('Консистентность', `${stats.consistency.toFixed(0)}%`, 'стабильность'));
            compareContent.appendChild(detailsGrid);
        }
    }

    if (performanceContent) {
        performanceContent.textContent = '';

        const legend = createElement('div', 'lumo-score-legend');
        const legendTitle = createElement('div', 'lumo-score-legend-title', 'Расшифровка оценок');
        const legendItems = createElement('div', 'lumo-score-legend-items');

        const grades = [
            { grade: 'A+', desc: 'Отлично', class: 'excellent' },
            { grade: 'A', desc: 'Хорошо', class: 'good' },
            { grade: 'B', desc: 'Средне', class: 'average' },
            { grade: 'C', desc: 'Слабо', class: 'poor' },
            { grade: 'D', desc: 'Плохо', class: 'bad' }
        ];

        grades.forEach(g => {
            const item = createElement('div', 'lumo-score-legend-item');
            const badge = createElement('span', `lumo-score-legend-badge lumo-score-${g.class}`, g.grade);
            const desc = createElement('span', '', g.desc);
            item.appendChild(badge);
            item.appendChild(desc);
            legendItems.appendChild(item);
        });

        legend.appendChild(legendTitle);
        legend.appendChild(legendItems);
        performanceContent.appendChild(legend);

        const perfGrid = createElement('div', 'lumo-performance-grid');

        const viewsScore = getPerformanceScore(stats.avgViews, {
            excellent: 100000,
            good: 50000,
            average: 10000,
            poor: 1000
        });
        const viewsItem = createElement('div', 'lumo-performance-item');
        const viewsHeader = createElement('div', 'lumo-performance-header');
        viewsHeader.appendChild(createElement('div', 'lumo-performance-title', 'Просмотры'));
        viewsHeader.appendChild(createElement('div', `lumo-performance-score lumo-score-${viewsScore.class}`, viewsScore.score));
        viewsItem.appendChild(viewsHeader);
        viewsItem.appendChild(createElement('div', 'lumo-performance-desc', `Средние просмотры ${formatNumber(stats.avgViews)}`));
        perfGrid.appendChild(viewsItem);

        if (currentMode === 'videos') {
            const consistScore = getPerformanceScore(stats.consistency, {
                excellent: 70,
                good: 55,
                average: 40,
                poor: 25
            });
            const consistItem = createElement('div', 'lumo-performance-item');
            const consistHeader = createElement('div', 'lumo-performance-header');
            consistHeader.appendChild(createElement('div', 'lumo-performance-title', 'Стабильность'));
            consistHeader.appendChild(createElement('div', `lumo-performance-score lumo-score-${consistScore.class}`, consistScore.score));
            consistItem.appendChild(consistHeader);
            consistItem.appendChild(createElement('div', 'lumo-performance-desc', `Стабильность ${stats.consistency.toFixed(0)}%`));
            perfGrid.appendChild(consistItem);

            const freqScore = getPerformanceScore(stats.videosPerWeek, {
                excellent: 5,
                good: 3,
                average: 1,
                poor: 0.5
            });
            const freqItem = createElement('div', 'lumo-performance-item');
            const freqHeader = createElement('div', 'lumo-performance-header');
            freqHeader.appendChild(createElement('div', 'lumo-performance-title', 'Активность'));
            freqHeader.appendChild(createElement('div', `lumo-performance-score lumo-score-${freqScore.class}`, freqScore.score));
            freqItem.appendChild(freqHeader);
            freqItem.appendChild(createElement('div', 'lumo-performance-desc', `Частота ${formatVideosPerWeek(stats.videosPerWeek)}`));
            perfGrid.appendChild(freqItem);

            const growthScore = getPerformanceScore(stats.growthRate, {
                excellent: 40,
                good: 20,
                average: 5,
                poor: -10
            });
            const growthItem = createElement('div', 'lumo-performance-item');
            const growthHeader = createElement('div', 'lumo-performance-header');
            growthHeader.appendChild(createElement('div', 'lumo-performance-title', 'Рост'));
            growthHeader.appendChild(createElement('div', `lumo-performance-score lumo-score-${growthScore.class}`, growthScore.score));
            growthItem.appendChild(growthHeader);
            growthItem.appendChild(createElement('div', 'lumo-performance-desc', `Динамика ${stats.growthRate > 0 ? '+' : ''}${stats.growthRate.toFixed(1)}%`));
            perfGrid.appendChild(growthItem);

            const durationScore = getPerformanceScore(stats.avgDuration, {
                excellent: 900,
                good: 600,
                average: 300,
                poor: 120
            });
            const durationItem = createElement('div', 'lumo-performance-item');
            const durationHeader = createElement('div', 'lumo-performance-header');
            durationHeader.appendChild(createElement('div', 'lumo-performance-title', 'Длительность'));
            durationHeader.appendChild(createElement('div', `lumo-performance-score lumo-score-${durationScore.class}`, durationScore.score));
            durationItem.appendChild(durationHeader);
            durationItem.appendChild(createElement('div', 'lumo-performance-desc', `Средняя ${formatTime(stats.avgDuration)}`));
            perfGrid.appendChild(durationItem);

            const engagementRatio = stats.topViews > 0 ? (stats.avgViews / stats.topViews) * 100 : 0;
            const engageScore = getPerformanceScore(engagementRatio, {
                excellent: 60,
                good: 40,
                average: 20,
                poor: 10
            });
            const engageItem = createElement('div', 'lumo-performance-item');
            const engageHeader = createElement('div', 'lumo-performance-header');
            engageHeader.appendChild(createElement('div', 'lumo-performance-title', 'Вовлеченность'));
            engageHeader.appendChild(createElement('div', `lumo-performance-score lumo-score-${engageScore.class}`, engageScore.score));
            engageItem.appendChild(engageHeader);
            engageItem.appendChild(createElement('div', 'lumo-performance-desc', `Соотношение ${engagementRatio.toFixed(0)}%`));
            perfGrid.appendChild(engageItem);
        } else if (currentMode === 'shorts') {
            const consistScore = getPerformanceScore(stats.consistency, {
                excellent: 70,
                good: 55,
                average: 40,
                poor: 25
            });
            const consistItem = createElement('div', 'lumo-performance-item');
            const consistHeader = createElement('div', 'lumo-performance-header');
            consistHeader.appendChild(createElement('div', 'lumo-performance-title', 'Стабильность'));
            consistHeader.appendChild(createElement('div', `lumo-performance-score lumo-score-${consistScore.class}`, consistScore.score));
            consistItem.appendChild(consistHeader);
            consistItem.appendChild(createElement('div', 'lumo-performance-desc', `Стабильность ${stats.consistency.toFixed(0)}%`));
            perfGrid.appendChild(consistItem);
        }

        performanceContent.appendChild(perfGrid);
    }

    modal.classList.add('active');
    isAnalyzing = false;

    forceYouTubeResize();
}

function createAnalyticsPanel() {
    const existing = document.querySelector('.lumo-analytics-wrapper');
    if (existing) existing.remove();

    const wrapper = createElement('div', 'lumo-analytics-wrapper');
    const container = createElement('div', 'lumo-analytics-container');

    const header = createElement('div', 'lumo-analytics-header');
    const titleContainer = createElement('div', 'lumo-analytics-title');
    const titleText = createElement('span', '', '▣ Аналитика');
    const badge = createElement('span', 'lumo-analytics-badge', 'Pro');
    titleContainer.appendChild(titleText);
    titleContainer.appendChild(badge);

    const expandBtn = createElement('button', 'lumo-analytics-expand-btn', 'Подробно →');
    expandBtn.addEventListener('click', (e) => {
        e.preventDefault();
        e.stopPropagation();
        showDetailedStats();
    });

    header.appendChild(titleContainer);
    header.appendChild(expandBtn);

    const loading = createElement('div', 'lumo-loading');
    const spinner = createElement('div', 'lumo-spinner');
    const loadingText = createElement('div', 'lumo-loading-text', 'Анализ данных...');
    loading.appendChild(spinner);
    loading.appendChild(loadingText);

    container.appendChild(header);
    container.appendChild(loading);
    wrapper.appendChild(container);

    const pageHeader = document.querySelector('#page-header');
    if (pageHeader) {
        pageHeader.appendChild(wrapper);
        requestAnimationFrame(() => loadInitialStats());
    }
}

function createLiveAnalyticsPanel() {
    const existing = document.querySelector('.lumo-analytics-wrapper');
    if (existing) existing.remove();

    const wrapper = createElement('div', 'lumo-analytics-wrapper');
    const container = createElement('div', 'lumo-analytics-container');

    const header = createElement('div', 'lumo-analytics-header');
    const titleContainer = createElement('div', 'lumo-analytics-title');
    const titleText = createElement('span', '', '▣ Аналитика стрима');
    const badge = createElement('span', 'lumo-analytics-badge live', 'LIVE');
    titleContainer.appendChild(titleText);
    titleContainer.appendChild(badge);

    header.appendChild(titleContainer);

    container.appendChild(header);

    const statsContainer = createElement('div', 'lumo-live-stats');
    statsContainer.id = 'live-stats-container';
    container.appendChild(statsContainer);

    const chartWrapper = createElement('div', 'lumo-chart-wrapper');
    chartWrapper.style.marginTop = '16px';
    const canvas = document.createElement('canvas');
    canvas.className = 'lumo-chart-canvas';
    canvas.id = 'live-chart';
    chartWrapper.appendChild(canvas);
    container.appendChild(chartWrapper);

    wrapper.appendChild(container);

    const secondary = document.querySelector('#secondary');
    if (secondary) {
        secondary.insertBefore(wrapper, secondary.firstChild);
        requestAnimationFrame(() => {
            updateLiveStats();
            drawLiveChart();
        });
        startLiveUpdates();
    }
}

function updateLiveStats() {
    const viewers = getLiveViewers();

    viewerHistory.push({
        viewers: viewers,
        timestamp: Date.now()
    });

    if (viewerHistory.length > maxHistoryLength) {
        viewerHistory.shift();
    }

    const statsContainer = document.getElementById('live-stats-container');
    if (statsContainer) {
        while (statsContainer.firstChild) {
            statsContainer.removeChild(statsContainer.firstChild);
        }

        const viewerCard = createElement('div', 'lumo-live-card highlight');
        const viewerLabel = createElement('div', 'lumo-live-label', 'Зрителей');
        const viewerValue = createElement('div', 'lumo-live-value', viewers.toString());
        viewerCard.appendChild(viewerLabel);
        viewerCard.appendChild(viewerValue);

        const peakCard = createElement('div', 'lumo-live-card');
        const peakLabel = createElement('div', 'lumo-live-label', 'Пик');
        const peak = viewerHistory.length > 0 ? Math.max(...viewerHistory.map(h => h.viewers)) : viewers;
        const peakValue = createElement('div', 'lumo-live-value', peak.toString());
        peakCard.appendChild(peakLabel);
        peakCard.appendChild(peakValue);

        const minCard = createElement('div', 'lumo-live-card');
        const minLabel = createElement('div', 'lumo-live-label', 'Минимум');
        const min = viewerHistory.length > 0 ? Math.min(...viewerHistory.map(h => h.viewers)) : viewers;
        const minValue = createElement('div', 'lumo-live-value', min.toString());
        minCard.appendChild(minLabel);
        minCard.appendChild(minValue);

        const avgCard = createElement('div', 'lumo-live-card');
        const avgLabel = createElement('div', 'lumo-live-label', 'Средние');
        const avg = viewerHistory.length > 0 ? Math.round(viewerHistory.reduce((sum, h) => sum + h.viewers, 0) / viewerHistory.length) : viewers;
        const avgValue = createElement('div', 'lumo-live-value', avg.toString());
        avgCard.appendChild(avgLabel);
        avgCard.appendChild(avgValue);

        statsContainer.appendChild(viewerCard);
        statsContainer.appendChild(peakCard);
        statsContainer.appendChild(minCard);
        statsContainer.appendChild(avgCard);
    }

    drawLiveChart();
}

function drawLiveChart() {
    const canvas = document.getElementById('live-chart');
    if (!canvas || viewerHistory.length === 0) return;

    const data = viewerHistory.map(h => h.viewers);
    drawLineChart(canvas, data, '#ff0000');
    setupChartTooltip(canvas, canvas.parentElement);
}

function startLiveUpdates() {
    if (liveUpdateInterval) clearInterval(liveUpdateInterval);

    liveUpdateInterval = setInterval(() => {
        requestAnimationFrame(() => updateLiveStats());
    }, 3000);
}

function stopLiveUpdates() {
    if (liveUpdateInterval) {
        clearInterval(liveUpdateInterval);
        liveUpdateInterval = null;
    }
    viewerHistory = [];
}

function loadInitialStats() {
    const container = document.querySelector('.lumo-analytics-container');
    if (!container) return;

    let stats, data;

    if (currentMode === 'videos') {
        data = getVideosFromPage();
        stats = analyzeVideos(data);
    } else if (currentMode === 'shorts') {
        data = getShortsFromPage();
        stats = analyzeShortsData(data);
    } else if (currentMode === 'streams') {
        data = getStreamsFromPage();
        stats = analyzeStreamsData(data);
    }

    const country = getCountryFromAbout();

    const loading = container.querySelector('.lumo-loading');
    if (loading) loading.remove();

    const statsGrid = createElement('div', 'lumo-stats-grid');

    if (currentMode === 'videos') {
        statsGrid.appendChild(createStatCardElement('Ср. просмотры', formatNumber(stats.avgViews), '◉'));
        statsGrid.appendChild(createStatCardElement('Ср. длительность', formatTime(stats.avgDuration), '◷'));
        statsGrid.appendChild(createStatCardElement('Частота', formatVideosPerWeek(stats.videosPerWeek), '◔'));
    } else if (currentMode === 'shorts') {
        statsGrid.appendChild(createStatCardElement('Ср. просмотры', formatNumber(stats.avgViews), '◉'));
        statsGrid.appendChild(createStatCardElement('Всего Shorts', stats.totalShorts.toString(), '▣'));
        statsGrid.appendChild(createStatCardElement('Топ Shorts', formatNumber(stats.topViews), '↑'));
    } else if (currentMode === 'streams') {
        statsGrid.appendChild(createStatCardElement('Активные', stats.liveCount.toString(), '▣'));
        statsGrid.appendChild(createStatCardElement('Зрители сейчас', stats.currentViewers.toString(), '◉'));
        if (stats.pastStreamsCount > 0) {
            statsGrid.appendChild(createStatCardElement('Ср. просмотры', formatNumber(stats.avgViews), '◷'));
        }
    }

    if (country) {
        const countryCard = createElement('div', 'lumo-stat-card');
        const label = createElement('div', 'lumo-stat-label', 'Страна');
        const info = createElement('div', 'lumo-country-info');
        const flag = document.createElement('img');
        flag.className = 'lumo-country-flag';
        flag.src = countryFlags[country] || 'https://flagcdn.com/w80/ru.png';
        flag.onerror = () => flag.style.display = 'none';
        const name = createElement('span', 'lumo-country-name', country);

        info.appendChild(flag);
        info.appendChild(name);
        countryCard.appendChild(label);
        countryCard.appendChild(info);
        statsGrid.appendChild(countryCard);
    }

    container.appendChild(statsGrid);

    forceYouTubeResize();
}

function init() {
    const path = window.location.pathname;

    if (path.includes('/live/') || (path.includes('/watch') && document.querySelector('ytd-watch-info-text #view-count'))) {
        currentMode = 'live';
        stopLiveUpdates();
        setTimeout(() => {
            const existing = document.querySelector('.lumo-analytics-wrapper');
            if (!existing) {
                createLiveAnalyticsPanel();
            }
        }, 2000);
    } else if ((path.includes('/@') || path.includes('/channel/') || path.includes('/c/')) && path.includes('/streams')) {
        currentMode = 'streams';
        stopLiveUpdates();
        setTimeout(() => {
            if (!document.querySelector('.lumo-analytics-wrapper')) {
                createAnalyticsPanel();
            }
        }, 1000);
    } else if ((path.includes('/@') || path.includes('/channel/') || path.includes('/c/')) && path.includes('/videos')) {
        currentMode = 'videos';
        stopLiveUpdates();
        setTimeout(() => {
            if (!document.querySelector('.lumo-analytics-wrapper')) {
                createAnalyticsPanel();
            }
        }, 1000);
    } else if ((path.includes('/@') || path.includes('/channel/') || path.includes('/c/')) && path.includes('/shorts')) {
        currentMode = 'shorts';
        stopLiveUpdates();
        setTimeout(() => {
            if (!document.querySelector('.lumo-analytics-wrapper')) {
                createAnalyticsPanel();
            }
        }, 1000);
    } else {
        stopLiveUpdates();
    }
}

let lastUrl = location.href;
const observer = new MutationObserver(() => {
    const url = location.href;
    if (url !== lastUrl) {
        lastUrl = url;
        const modal = document.querySelector('.lumo-modal');
        if (modal) modal.remove();
        const wrapper = document.querySelector('.lumo-analytics-wrapper');
        if (wrapper) wrapper.remove();
        const tooltip = document.querySelector('.lumo-chart-tooltip');
        if (tooltip) tooltip.remove();
        cachedData = null;
        isAnalyzing = false;
        chartData = null;
        stopLiveUpdates();
        setTimeout(init, 500);
    }
});

observer.observe(document.body, { subtree: true, childList: true });
init();

})();